From 9a7d7deb7b5fa8e9e9399861f952f6ff674e80e1 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 11 Jan 2021 08:45:32 -0500 Subject: [PATCH] [Uptime] Fix/details page tabs (#86296) (#87795) * Remove tabs from details page * update * fix monitord id * var name * add Uptime PageHeader tests to test for the presences of tabs or header * add Uptime MonitorPageTitle test * Uptime adjust auto generated monitor id regex * Uptime add tests for MonitorPageTitle to test behavior for missing monitor names and auto generated monitor ids * remove history from MonitorPageTitle test * adjust uptime tabs tests * adjust MonitorPageTitle tests to mock useSelector * adjust uptime PageHeader tests * adjust import order in page_header.test * add props to Uptime PageHeader to determine render, rather than route context * alphabetize props in Uptime PageHeader * remove header from individual pages * add indepdent page header route that matches all paths * adjust monitor tests to use mockReduxHooks helper, and add mockReactRouterDomHooks * update tests * adjust header spacing Co-authored-by: Shahzad Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Shahzad Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../certificates/cert_refresh_btn.tsx | 6 +- .../__snapshots__/page_header.test.tsx.snap | 907 ------------------ .../common/header/page_header.test.tsx | 72 +- .../components/common/header/page_header.tsx | 56 +- .../components/common/header/page_tabs.tsx | 2 +- .../components/monitor/monitor_title.test.tsx | 81 ++ .../components/monitor/monitor_title.tsx | 58 ++ .../uptime/public/lib/helper/test_helpers.ts | 5 + .../plugins/uptime/public/pages/monitor.tsx | 45 +- .../plugins/uptime/public/pages/settings.tsx | 1 - x-pack/plugins/uptime/public/routes.tsx | 33 +- 11 files changed, 257 insertions(+), 1009 deletions(-) delete mode 100644 x-pack/plugins/uptime/public/components/common/header/__snapshots__/page_header.test.tsx.snap create mode 100644 x-pack/plugins/uptime/public/components/monitor/monitor_title.test.tsx create mode 100644 x-pack/plugins/uptime/public/components/monitor/monitor_title.tsx diff --git a/x-pack/plugins/uptime/public/components/certificates/cert_refresh_btn.tsx b/x-pack/plugins/uptime/public/components/certificates/cert_refresh_btn.tsx index d0823276f1885..39661fe84a4be 100644 --- a/x-pack/plugins/uptime/public/components/certificates/cert_refresh_btn.tsx +++ b/x-pack/plugins/uptime/public/components/certificates/cert_refresh_btn.tsx @@ -20,7 +20,11 @@ export const CertRefreshBtn = () => { const { refreshApp } = useContext(UptimeRefreshContext); return ( - + diff --git a/x-pack/plugins/uptime/public/components/common/header/__snapshots__/page_header.test.tsx.snap b/x-pack/plugins/uptime/public/components/common/header/__snapshots__/page_header.test.tsx.snap deleted file mode 100644 index 05a78624848c6..0000000000000 --- a/x-pack/plugins/uptime/public/components/common/header/__snapshots__/page_header.test.tsx.snap +++ /dev/null @@ -1,907 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`PageHeader shallow renders extra links: page_header_with_extra_links 1`] = ` -Array [ - @media only screen and (max-width:1024px) and (min-width:868px) { - -} - -@media only screen and (max-width:880px) { - -} - -
-
-
-
-

- Uptime is now previewing support for scripted multi-step availability checks. This means you can interact with elements of a webpage and check the availability of an entire journey (such as making a purchase or signing into a system) instead of just a simple single page up/down check. Please click below to read more and, if you'd like to be one of the first to use these capabilities, you can download our preview synthetics agent and view your synthetic checks in Uptime. -

-
- -
- -
-
-
-
, - @media only screen and (max-width:1024px) and (min-width:868px) { - -} - -@media only screen and (max-width:880px) { - -} - -
, - @media only screen and (max-width:1024px) and (min-width:868px) { - .c0.c0.c0 .euiSuperDatePicker__flexWrapper { - width: 500px; - } -} - -@media only screen and (max-width:880px) { - .c0.c0.c0 { - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - -ms-flex-positive: 1; - flex-grow: 1; - } - - .c0.c0.c0 .euiSuperDatePicker__flexWrapper { - width: calc(100% + 8px); - } -} - -
- -
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
- - - -
-
-
-
, - @media only screen and (max-width:1024px) and (min-width:868px) { - -} - -@media only screen and (max-width:880px) { - -} - -
, -] -`; - -exports[`PageHeader shallow renders with the date picker: page_header_with_date_picker 1`] = ` -Array [ - @media only screen and (max-width:1024px) and (min-width:868px) { - -} - -@media only screen and (max-width:880px) { - -} - -
-
-
-
-

- Uptime is now previewing support for scripted multi-step availability checks. This means you can interact with elements of a webpage and check the availability of an entire journey (such as making a purchase or signing into a system) instead of just a simple single page up/down check. Please click below to read more and, if you'd like to be one of the first to use these capabilities, you can download our preview synthetics agent and view your synthetic checks in Uptime. -

-
- -
- -
-
-
-
, - @media only screen and (max-width:1024px) and (min-width:868px) { - -} - -@media only screen and (max-width:880px) { - -} - -
, - @media only screen and (max-width:1024px) and (min-width:868px) { - .c0.c0.c0 .euiSuperDatePicker__flexWrapper { - width: 500px; - } -} - -@media only screen and (max-width:880px) { - .c0.c0.c0 { - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - -ms-flex-positive: 1; - flex-grow: 1; - } - - .c0.c0.c0 .euiSuperDatePicker__flexWrapper { - width: calc(100% + 8px); - } -} - -
- -
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
- - - -
-
-
-
, - @media only screen and (max-width:1024px) and (min-width:868px) { - -} - -@media only screen and (max-width:880px) { - -} - -
, -] -`; - -exports[`PageHeader shallow renders without the date picker: page_header_no_date_picker 1`] = ` -Array [ - @media only screen and (max-width:1024px) and (min-width:868px) { - -} - -@media only screen and (max-width:880px) { - -} - -
-
-
-
-

- Uptime is now previewing support for scripted multi-step availability checks. This means you can interact with elements of a webpage and check the availability of an entire journey (such as making a purchase or signing into a system) instead of just a simple single page up/down check. Please click below to read more and, if you'd like to be one of the first to use these capabilities, you can download our preview synthetics agent and view your synthetic checks in Uptime. -

-
- -
- -
-
-
-
, - @media only screen and (max-width:1024px) and (min-width:868px) { - -} - -@media only screen and (max-width:880px) { - -} - -
, - @media only screen and (max-width:1024px) and (min-width:868px) { - .c0.c0.c0 .euiSuperDatePicker__flexWrapper { - width: 500px; - } -} - -@media only screen and (max-width:880px) { - .c0.c0.c0 { - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - -ms-flex-positive: 1; - flex-grow: 1; - } - - .c0.c0.c0 .euiSuperDatePicker__flexWrapper { - width: calc(100% + 8px); - } -} - -
- -
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
- - - -
-
-
-
, - @media only screen and (max-width:1024px) and (min-width:868px) { - -} - -@media only screen and (max-width:880px) { - -} - -
, -] -`; diff --git a/x-pack/plugins/uptime/public/components/common/header/page_header.test.tsx b/x-pack/plugins/uptime/public/components/common/header/page_header.test.tsx index cde87e736d09c..e3c62fb2a48f2 100644 --- a/x-pack/plugins/uptime/public/components/common/header/page_header.test.tsx +++ b/x-pack/plugins/uptime/public/components/common/header/page_header.test.tsx @@ -5,34 +5,64 @@ */ import React from 'react'; +import moment from 'moment'; import { PageHeader } from './page_header'; -import { renderWithRouter, MountWithReduxProvider } from '../../../lib'; +import { Ping } from '../../../../common/runtime_types'; +import { renderWithRouter } from '../../../lib'; +import { mockReduxHooks } from '../../../lib/helper/test_helpers'; describe('PageHeader', () => { + const monitorName = 'sample monitor'; + const defaultMonitorId = 'always-down'; + + const defaultMonitorStatus: Ping = { + docId: 'few213kl', + timestamp: moment(new Date()).subtract(15, 'm').toString(), + monitor: { + duration: { + us: 1234567, + }, + id: defaultMonitorId, + status: 'up', + type: 'http', + name: monitorName, + }, + url: { + full: 'https://www.elastic.co/', + }, + }; + + beforeEach(() => { + mockReduxHooks(defaultMonitorStatus); + }); + + it('does not render dynamic elements by default', () => { + const component = renderWithRouter(); + + expect(component.find('[data-test-subj="superDatePickerShowDatesButton"]').length).toBe(0); + expect(component.find('[data-test-subj="certificatesRefreshButton"]').length).toBe(0); + expect(component.find('[data-test-subj="monitorTitle"]').length).toBe(0); + expect(component.find('[data-test-subj="uptimeTabs"]').length).toBe(0); + }); + it('shallow renders with the date picker', () => { - const component = renderWithRouter( - - - - ); - expect(component).toMatchSnapshot('page_header_with_date_picker'); + const component = renderWithRouter(); + expect(component.find('[data-test-subj="superDatePickerShowDatesButton"]').length).toBe(1); + }); + + it('shallow renders with certificate refresh button', () => { + const component = renderWithRouter(); + expect(component.find('[data-test-subj="certificatesRefreshButton"]').length).toBe(1); }); - it('shallow renders without the date picker', () => { - const component = renderWithRouter( - - - - ); - expect(component).toMatchSnapshot('page_header_no_date_picker'); + it('renders monitor title when showMonitorTitle', () => { + const component = renderWithRouter(); + expect(component.find('[data-test-subj="monitorTitle"]').length).toBe(1); + expect(component.find('h1').text()).toBe(monitorName); }); - it('shallow renders extra links', () => { - const component = renderWithRouter( - - - - ); - expect(component).toMatchSnapshot('page_header_with_extra_links'); + it('renders tabs when showTabs is true', () => { + const component = renderWithRouter(); + expect(component.find('[data-test-subj="uptimeTabs"]').length).toBe(1); }); }); diff --git a/x-pack/plugins/uptime/public/components/common/header/page_header.tsx b/x-pack/plugins/uptime/public/components/common/header/page_header.tsx index 923aee472faa6..2bb14d279f2d9 100644 --- a/x-pack/plugins/uptime/public/components/common/header/page_header.tsx +++ b/x-pack/plugins/uptime/public/components/common/header/page_header.tsx @@ -5,20 +5,21 @@ */ import React from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, EuiSpacer } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import styled from 'styled-components'; -import { useRouteMatch } from 'react-router-dom'; import { UptimeDatePicker } from '../uptime_date_picker'; import { SyntheticsCallout } from '../../overview/synthetics_callout'; import { PageTabs } from './page_tabs'; -import { - CERTIFICATES_ROUTE, - MONITOR_ROUTE, - SETTINGS_ROUTE, - STEP_DETAIL_ROUTE, -} from '../../../../common/constants'; import { CertRefreshBtn } from '../../certificates/cert_refresh_btn'; import { ToggleAlertFlyoutButton } from '../../overview/alerts/alerts_containers'; +import { MonitorPageTitle } from '../../monitor/monitor_title'; + +export interface Props { + showCertificateRefreshBtn?: boolean; + showDatePicker?: boolean; + showMonitorTitle?: boolean; + showTabs?: boolean; +} const StyledPicker = styled(EuiFlexItem)` &&& { @@ -36,40 +37,31 @@ const StyledPicker = styled(EuiFlexItem)` } `; -export const PageHeader = () => { - const isCertRoute = useRouteMatch(CERTIFICATES_ROUTE); - const isSettingsRoute = useRouteMatch(SETTINGS_ROUTE); - const isStepDetailRoute = useRouteMatch(STEP_DETAIL_ROUTE); - - const DatePickerComponent = () => - isCertRoute ? ( - - ) : ( - - - - ); - - const isMonRoute = useRouteMatch(MONITOR_ROUTE); - - if (isStepDetailRoute) { - return null; - } - +export const PageHeader = ({ + showCertificateRefreshBtn = false, + showDatePicker = false, + showMonitorTitle = false, + showTabs = false, +}: Props) => { return ( <> - + {showMonitorTitle && } + {showTabs && } - {!isSettingsRoute && } + {showCertificateRefreshBtn && } + {showDatePicker && ( + + + + )} - {isMonRoute && } - {!isMonRoute && } + ); }; diff --git a/x-pack/plugins/uptime/public/components/common/header/page_tabs.tsx b/x-pack/plugins/uptime/public/components/common/header/page_tabs.tsx index 68df15c52c65e..56da7d5f92803 100644 --- a/x-pack/plugins/uptime/public/components/common/header/page_tabs.tsx +++ b/x-pack/plugins/uptime/public/components/common/header/page_tabs.tsx @@ -73,7 +73,7 @@ export const PageTabs = () => { }; return ( - + {renderTabs()} ); diff --git a/x-pack/plugins/uptime/public/components/monitor/monitor_title.test.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_title.test.tsx new file mode 100644 index 0000000000000..6ee25f8360933 --- /dev/null +++ b/x-pack/plugins/uptime/public/components/monitor/monitor_title.test.tsx @@ -0,0 +1,81 @@ +/* + * 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 React from 'react'; +import moment from 'moment'; +import * as reactRouterDom from 'react-router-dom'; +import { Ping } from '../../../common/runtime_types'; +import { MonitorPageTitle } from './monitor_title'; +import { renderWithRouter } from '../../lib'; +import { mockReduxHooks } from '../../lib/helper/test_helpers'; + +jest.mock('react-router-dom', () => { + const originalModule = jest.requireActual('react-router-dom'); + + return { + ...originalModule, + useParams: jest.fn(), + }; +}); + +export function mockReactRouterDomHooks({ useParamsResponse }: { useParamsResponse: any }) { + jest.spyOn(reactRouterDom, 'useParams').mockReturnValue(useParamsResponse); +} + +describe('MonitorTitle component', () => { + const monitorName = 'sample monitor'; + const defaultMonitorId = 'always-down'; + const defaultMonitorIdEncoded = 'YWx3YXlzLWRvd24'; // resolves to always-down + const autoGeneratedMonitorIdEncoded = 'YXV0by1pY21wLTBYMjQ5NDhGNDY3QzZDNEYwMQ'; // resolves to auto-icmp-0X24948F467C6C4F01 + + const defaultMonitorStatus: Ping = { + docId: 'few213kl', + timestamp: moment(new Date()).subtract(15, 'm').toString(), + monitor: { + duration: { + us: 1234567, + }, + id: defaultMonitorId, + status: 'up', + type: 'http', + }, + url: { + full: 'https://www.elastic.co/', + }, + }; + + const monitorStatusWithName: Ping = { + ...defaultMonitorStatus, + monitor: { + ...defaultMonitorStatus.monitor, + name: monitorName, + }, + }; + + beforeEach(() => { + mockReactRouterDomHooks({ useParamsResponse: { monitorId: defaultMonitorIdEncoded } }); + mockReduxHooks(defaultMonitorStatus); + }); + + it('renders the monitor heading and EnableMonitorAlert toggle', () => { + mockReduxHooks(monitorStatusWithName); + const component = renderWithRouter(); + expect(component.find('h1').text()).toBe(monitorName); + expect(component.find('[data-test-subj="uptimeDisplayDefineConnector"]').length).toBe(1); + }); + + it('renders the user provided monitorId when the name is not present', () => { + mockReactRouterDomHooks({ useParamsResponse: { monitorId: defaultMonitorIdEncoded } }); + const component = renderWithRouter(); + expect(component.find('h1').text()).toBe(defaultMonitorId); + }); + + it('renders the url when the monitorId is auto generated and the monitor name is not present', () => { + mockReactRouterDomHooks({ useParamsResponse: { monitorId: autoGeneratedMonitorIdEncoded } }); + const component = renderWithRouter(); + expect(component.find('h1').text()).toBe(defaultMonitorStatus.url?.full); + }); +}); diff --git a/x-pack/plugins/uptime/public/components/monitor/monitor_title.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_title.tsx new file mode 100644 index 0000000000000..cecef14298267 --- /dev/null +++ b/x-pack/plugins/uptime/public/components/monitor/monitor_title.tsx @@ -0,0 +1,58 @@ +/* + * 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 { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui'; +import React from 'react'; +import { useSelector } from 'react-redux'; +import { useMonitorId } from '../../hooks'; +import { monitorStatusSelector } from '../../state/selectors'; +import { EnableMonitorAlert } from '../overview/monitor_list/columns/enable_alert'; +import { Ping } from '../../../common/runtime_types/ping'; +import { useBreadcrumbs } from '../../hooks/use_breadcrumbs'; + +const isAutogeneratedId = (id: string) => { + const autoGeneratedId = /^auto-(icmp|http|tcp|browser)-0X[A-F0-9]{16}.*/; + return autoGeneratedId.test(id); +}; + +// For monitors with no explicit ID, we display the URL instead of the +// auto-generated ID because it is difficult to derive meaning from a +// generated id like `auto-http-0X8D6082B94BBE3B8A`. +// We may deprecate this behavior in the next major release, because +// the heartbeat config will require an explicit ID. +const getPageTitle = (monitorId: string, selectedMonitor: Ping | null) => { + if (isAutogeneratedId(monitorId)) { + return selectedMonitor?.url?.full || monitorId; + } + return monitorId; +}; + +export const MonitorPageTitle: React.FC = () => { + const monitorId = useMonitorId(); + + const selectedMonitor = useSelector(monitorStatusSelector); + + const nameOrId = selectedMonitor?.monitor?.name || getPageTitle(monitorId, selectedMonitor); + + useBreadcrumbs([{ text: nameOrId }]); + + return ( + + + +

{nameOrId}

+
+ +
+ + + +
+ ); +}; diff --git a/x-pack/plugins/uptime/public/lib/helper/test_helpers.ts b/x-pack/plugins/uptime/public/lib/helper/test_helpers.ts index faa1b968d2546..8102bdee9485b 100644 --- a/x-pack/plugins/uptime/public/lib/helper/test_helpers.ts +++ b/x-pack/plugins/uptime/public/lib/helper/test_helpers.ts @@ -9,6 +9,7 @@ import moment from 'moment'; import { Moment } from 'moment-timezone'; import * as redux from 'react-redux'; +import * as reactRouterDom from 'react-router-dom'; export function mockMoment() { // avoid timezone issues @@ -27,3 +28,7 @@ export function mockReduxHooks(response?: any) { jest.spyOn(redux, 'useSelector').mockReturnValue(response); } + +export function mockReactRouterDomHooks({ useParamsResponse }: { useParamsResponse: any }) { + jest.spyOn(reactRouterDom, 'useParams').mockReturnValue(useParamsResponse); +} diff --git a/x-pack/plugins/uptime/public/pages/monitor.tsx b/x-pack/plugins/uptime/public/pages/monitor.tsx index 559f118e89665..d68f791e3b77b 100644 --- a/x-pack/plugins/uptime/public/pages/monitor.tsx +++ b/x-pack/plugins/uptime/public/pages/monitor.tsx @@ -4,39 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui'; +import { EuiSpacer } from '@elastic/eui'; import React, { useEffect } from 'react'; -import { useSelector, useDispatch } from 'react-redux'; -import { monitorStatusSelector } from '../state/selectors'; -import { useBreadcrumbs } from '../hooks/use_breadcrumbs'; +import { useDispatch } from 'react-redux'; import { useTrackPageview } from '../../../observability/public'; import { useMonitorId } from '../hooks'; import { MonitorCharts } from '../components/monitor'; import { MonitorStatusDetails, PingList } from '../components/monitor'; import { getDynamicSettings } from '../state/actions/dynamic_settings'; -import { Ping } from '../../common/runtime_types/ping'; import { setSelectedMonitorId } from '../state/actions'; -import { EnableMonitorAlert } from '../components/overview/monitor_list/columns/enable_alert'; import { getMonitorAlertsAction } from '../state/alerts/alerts'; import { useInitApp } from '../hooks/use_init_app'; -const isAutogeneratedId = (id: string) => { - const autoGeneratedId = /^auto-(icmp|http|tcp)-OX[A-F0-9]{16}-[a-f0-9]{16}/; - return autoGeneratedId.test(id); -}; - -// For monitors with no explicit ID, we display the URL instead of the -// auto-generated ID because it is difficult to derive meaning from a -// generated id like `auto-http-0X8D6082B94BBE3B8A`. -// We may deprecate this behavior in the next major release, because -// the heartbeat config will require an explicit ID. -const getPageTitle = (monId: string, selectedMonitor: Ping | null) => { - if (isAutogeneratedId(monId)) { - return selectedMonitor?.url?.full || monId; - } - return monId; -}; - export const MonitorPage: React.FC = () => { const dispatch = useDispatch(); @@ -53,31 +32,11 @@ export const MonitorPage: React.FC = () => { dispatch(getMonitorAlertsAction.get()); }, [monitorId, dispatch]); - const selectedMonitor = useSelector(monitorStatusSelector); - useTrackPageview({ app: 'uptime', path: 'monitor' }); useTrackPageview({ app: 'uptime', path: 'monitor', delay: 15000 }); - const nameOrId = selectedMonitor?.monitor?.name || getPageTitle(monitorId, selectedMonitor); - useBreadcrumbs([{ text: nameOrId }]); - return ( <> - - - -

{nameOrId}

-
- -
- - - -
- diff --git a/x-pack/plugins/uptime/public/pages/settings.tsx b/x-pack/plugins/uptime/public/pages/settings.tsx index 530e0194305a4..6cdb7113e36c3 100644 --- a/x-pack/plugins/uptime/public/pages/settings.tsx +++ b/x-pack/plugins/uptime/public/pages/settings.tsx @@ -145,7 +145,6 @@ export const SettingsPage: React.FC = () => { return ( <> - {cannotEditNotice} diff --git a/x-pack/plugins/uptime/public/routes.tsx b/x-pack/plugins/uptime/public/routes.tsx index 65526f9bca4fc..5eb689e72bc1b 100644 --- a/x-pack/plugins/uptime/public/routes.tsx +++ b/x-pack/plugins/uptime/public/routes.tsx @@ -5,8 +5,9 @@ */ import React, { FC, useEffect } from 'react'; -import { Route, Switch } from 'react-router-dom'; +import { Route, RouteComponentProps, Switch } from 'react-router-dom'; import { OverviewPage } from './components/overview/overview_container'; +import { Props as PageHeaderProps, PageHeader } from './components/common/header/page_header'; import { CERTIFICATES_ROUTE, MONITOR_ROUTE, @@ -17,7 +18,6 @@ import { import { MonitorPage, StepDetailPage, NotFoundPage, SettingsPage } from './pages'; import { CertificatesPage } from './pages/certificates'; import { UptimePage, useUptimeTelemetry } from './hooks'; -import { PageHeader } from './components/common/header/page_header'; interface RouteProps { path: string; @@ -25,6 +25,7 @@ interface RouteProps { dataTestSubj: string; title: string; telemetryId: UptimePage; + headerProps?: PageHeaderProps; } const baseTitle = 'Uptime - Kibana'; @@ -36,6 +37,10 @@ const Routes: RouteProps[] = [ component: MonitorPage, dataTestSubj: 'uptimeMonitorPage', telemetryId: UptimePage.Monitor, + headerProps: { + showDatePicker: true, + showMonitorTitle: true, + }, }, { title: `Settings | ${baseTitle}`, @@ -43,6 +48,9 @@ const Routes: RouteProps[] = [ component: SettingsPage, dataTestSubj: 'uptimeSettingsPage', telemetryId: UptimePage.Settings, + headerProps: { + showTabs: true, + }, }, { title: `Certificates | ${baseTitle}`, @@ -50,6 +58,10 @@ const Routes: RouteProps[] = [ component: CertificatesPage, dataTestSubj: 'uptimeCertificatesPage', telemetryId: UptimePage.Certificates, + headerProps: { + showCertificateRefreshBtn: true, + showTabs: true, + }, }, { title: baseTitle, @@ -64,6 +76,10 @@ const Routes: RouteProps[] = [ component: OverviewPage, dataTestSubj: 'uptimeOverviewPage', telemetryId: UptimePage.Overview, + headerProps: { + showDatePicker: true, + showTabs: true, + }, }, ]; @@ -82,7 +98,18 @@ const RouteInit: React.FC> = export const PageRouter: FC = () => { return ( <> - + {/* Independent page header route that matches all paths and passes appropriate header props */} + {/* Prevents the header from being remounted on route changes */} + route.path)]} + exact={true} + render={({ match }: RouteComponentProps) => { + const routeProps: RouteProps | undefined = Routes.find( + (route: RouteProps) => route?.path === match?.path + ); + return routeProps?.headerProps && ; + }} + /> {Routes.map(({ title, path, component: RouteComponent, dataTestSubj, telemetryId }) => (