From 751cc9e2fb1e240e21f9bf1fe2839a928561e39c Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 19 Nov 2020 10:19:08 +0100 Subject: [PATCH 01/19] refactored uptime header --- .../plugins/uptime/public/apps/render_app.tsx | 18 ++- .../plugins/uptime/public/apps/uptime_app.tsx | 7 ++ .../toggle_alert_flyout_button.tsx | 23 +++- .../uptime_alerts_flyout_wrapper.tsx | 10 +- .../alerts/toggle_alert_flyout_button.tsx | 10 +- .../columns/define_connectors.tsx | 2 +- .../overview/monitor_list/monitor_list.tsx | 5 +- .../monitor_list/monitor_list_header.tsx | 14 --- .../pages/__tests__/page_header.test.tsx | 38 ------- .../uptime/public/pages/certificates.tsx | 42 ++----- .../plugins/uptime/public/pages/monitor.tsx | 2 +- .../plugins/uptime/public/pages/overview.tsx | 11 +- .../uptime/public/pages/page_header.tsx | 107 ------------------ .../plugins/uptime/public/pages/settings.tsx | 13 +-- .../uptime/public/pages/translations.ts | 14 --- 15 files changed, 82 insertions(+), 234 deletions(-) delete mode 100644 x-pack/plugins/uptime/public/pages/__tests__/page_header.test.tsx delete mode 100644 x-pack/plugins/uptime/public/pages/page_header.tsx diff --git a/x-pack/plugins/uptime/public/apps/render_app.tsx b/x-pack/plugins/uptime/public/apps/render_app.tsx index c0567ff956ce4..708dfa5b46297 100644 --- a/x-pack/plugins/uptime/public/apps/render_app.tsx +++ b/x-pack/plugins/uptime/public/apps/render_app.tsx @@ -8,6 +8,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { i18n as i18nFormatter } from '@kbn/i18n'; import { AppMountParameters, CoreStart } from 'kibana/public'; +import { createPortalNode, OutPortal } from 'react-reverse-portal'; import { getIntegratedAppAvailability } from '../lib/adapters/framework/capabilities_adapter'; import { DEFAULT_DARK_MODE, @@ -21,7 +22,7 @@ export function renderApp( core: CoreStart, plugins: ClientPluginsSetup, startPlugins: ClientPluginsStart, - { element, history }: AppMountParameters + { element, history, setHeaderActionMenu }: AppMountParameters ) { const { application: { capabilities }, @@ -31,6 +32,8 @@ export function renderApp( i18n, } = core; + const portalNode = createPortalNode(); + const { apm, infrastructure, logs } = getIntegratedAppAvailability( capabilities, INTEGRATED_SOLUTIONS @@ -51,6 +54,7 @@ export function renderApp( isApmAvailable: apm, isInfraAvailable: infrastructure, isLogsAvailable: logs, + actionMenu: portalNode, renderGlobalHelpControls: () => setHelpExtension({ appName: i18nFormatter.translate('xpack.uptime.header.appName', { @@ -71,6 +75,18 @@ export function renderApp( setBreadcrumbs: core.chrome.setBreadcrumbs, }; + function renderActionMenu(elem: HTMLElement) { + ReactDOM.render(, elem); + + return () => { + ReactDOM.unmountComponentAtNode(elem); + }; + } + + setHeaderActionMenu((elem) => { + return renderActionMenu(elem); + }); + ReactDOM.render(, element); return () => { diff --git a/x-pack/plugins/uptime/public/apps/uptime_app.tsx b/x-pack/plugins/uptime/public/apps/uptime_app.tsx index a5b8bc859ad94..4ab3be02d0737 100644 --- a/x-pack/plugins/uptime/public/apps/uptime_app.tsx +++ b/x-pack/plugins/uptime/public/apps/uptime_app.tsx @@ -10,6 +10,7 @@ import React, { useEffect } from 'react'; import { Provider as ReduxProvider } from 'react-redux'; import { Router } from 'react-router-dom'; import { I18nStart, ChromeBreadcrumb, CoreStart } from 'kibana/public'; +import { InPortal, PortalNode } from 'react-reverse-portal'; import { KibanaContextProvider, RedirectAppLinks, @@ -32,6 +33,7 @@ import { import { store } from '../state'; import { kibanaService } from '../state/kibana_service'; import { ScopedHistory } from '../../../../../src/core/public'; +import { ActionMenu } from './action_menu'; export interface UptimeAppColors { danger: string; @@ -59,6 +61,7 @@ export interface UptimeAppProps { renderGlobalHelpControls(): void; commonlyUsedRanges: CommonlyUsedRange[]; setBreadcrumbs: (crumbs: ChromeBreadcrumb[]) => void; + actionMenu: PortalNode; } const Application = (props: UptimeAppProps) => { @@ -72,6 +75,7 @@ const Application = (props: UptimeAppProps) => { renderGlobalHelpControls, setBadge, startPlugins, + actionMenu, } = props; useEffect(() => { @@ -111,6 +115,9 @@ const Application = (props: UptimeAppProps) => {
+ + +
diff --git a/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx b/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx index 2eee3ada8c004..c8a86b3f16522 100644 --- a/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx +++ b/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx @@ -4,10 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { useEffect } from 'react'; import { useDispatch } from 'react-redux'; +import { useRouteMatch } from 'react-router-dom'; import { setAlertFlyoutType, setAlertFlyoutVisible } from '../../../../state/actions'; import { ToggleAlertFlyoutButtonComponent } from '../index'; +import { CLIENT_ALERT_TYPES } from '../../../../../common/constants/alerts'; export interface ToggleAlertFlyoutButtonProps { alertOptions?: string[]; @@ -15,6 +17,25 @@ export interface ToggleAlertFlyoutButtonProps { export const ToggleAlertFlyoutButton: React.FC = (props) => { const dispatch = useDispatch(); + + const isCreateAlert = useRouteMatch('/status-alert/new'); + + const isTlsAlert = useRouteMatch('/tls-alert/new'); + + useEffect(() => { + if (isCreateAlert) { + dispatch(setAlertFlyoutType(CLIENT_ALERT_TYPES.MONITOR_STATUS)); + dispatch(setAlertFlyoutVisible(true)); + } + }, [isCreateAlert, dispatch]); + + useEffect(() => { + if (isTlsAlert) { + dispatch(setAlertFlyoutType(CLIENT_ALERT_TYPES.TLS)); + dispatch(setAlertFlyoutVisible(true)); + } + }, [isTlsAlert, dispatch]); + return ( { const dispatch = useDispatch(); - const setAddFlyoutVisibility = (value: React.SetStateAction) => + + const history = useHistory(); + + const setAddFlyoutVisibility = (value: React.SetStateAction) => { // @ts-ignore the value here is a boolean, and it works with the action creator function dispatch(setAlertFlyoutVisible(value)); + if (!value) { + history.push('/'); + } + }; const alertFlyoutVisible = useSelector(selectAlertFlyoutVisibility); const alertTypeId = useSelector(selectAlertFlyoutType); diff --git a/x-pack/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx b/x-pack/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx index bebc232b968d9..34f88a60f30b6 100644 --- a/x-pack/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx +++ b/x-pack/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx @@ -14,6 +14,7 @@ import { } from '@elastic/eui'; import React, { useState } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; +import { useHistory } from 'react-router-dom'; import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; import { CLIENT_ALERT_TYPES } from '../../../../common/constants/alerts'; import { ToggleFlyoutTranslations } from './translations'; @@ -34,13 +35,17 @@ export const ToggleAlertFlyoutButtonComponent: React.FC = ({ }) => { const [isOpen, setIsOpen] = useState(false); const kibana = useKibana(); + + const history = useHistory(); + const monitorStatusAlertContextMenuItem: EuiContextMenuPanelItemDescriptor = { 'aria-label': ToggleFlyoutTranslations.toggleMonitorStatusAriaLabel, 'data-test-subj': 'xpack.uptime.toggleAlertFlyout', name: ToggleFlyoutTranslations.toggleMonitorStatusContent, onClick: () => { - setAlertFlyoutVisible(CLIENT_ALERT_TYPES.MONITOR_STATUS); + // setAlertFlyoutVisible(CLIENT_ALERT_TYPES.MONITOR_STATUS); setIsOpen(false); + history.push('/status-alert/new'); }, }; @@ -49,8 +54,9 @@ export const ToggleAlertFlyoutButtonComponent: React.FC = ({ 'data-test-subj': 'xpack.uptime.toggleTlsAlertFlyout', name: ToggleFlyoutTranslations.toggleTlsContent, onClick: () => { - setAlertFlyoutVisible(CLIENT_ALERT_TYPES.TLS); + // setAlertFlyoutVisible(CLIENT_ALERT_TYPES.TLS); setIsOpen(false); + history.push('/tls-alert/new'); }, }; diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/columns/define_connectors.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/columns/define_connectors.tsx index 673588688db84..dd4535ec5ec09 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/columns/define_connectors.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/columns/define_connectors.tsx @@ -11,7 +11,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { ReactRouterEuiLink } from '../../../common/react_router_helpers'; import { MONITOR_ROUTE, SETTINGS_ROUTE } from '../../../../../common/constants'; import { ENABLE_STATUS_ALERT } from './translations'; -import { SETTINGS_LINK_TEXT } from '../../../../pages/page_header'; +import { SETTINGS_LINK_TEXT } from '../../../common/header/page_header'; export const DefineAlertConnectors = () => { const [isPopoverOpen, setIsPopoverOpen] = useState(false); diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx index f31e25484a936..7505ebb612953 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx @@ -9,7 +9,6 @@ import { EuiBasicTable, EuiFlexGroup, EuiFlexItem, - EuiIcon, EuiLink, EuiPanel, EuiSpacer, @@ -120,9 +119,9 @@ export const MonitorListComponent: ({ align: 'left' as const, field: 'state.url.full', name: URL_LABEL, - render: (url: string, summary: MonitorSummary) => ( + render: (url: string) => ( - {url} + {url} ), }, diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_header.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_header.tsx index 5f760030f37a3..87d8ad0ac879c 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_header.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_header.tsx @@ -7,16 +7,8 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { Link } from 'react-router-dom'; import styled from 'styled-components'; import { StatusFilter } from './status_filter'; -import { CERTIFICATES_ROUTE } from '../../../../common/constants'; - -const LinkStyle = styled(Link)` - position: absolute; - right: 16px; - top: 16px; -`; const FlexGroupContainer = styled(EuiFlexGroup)` position: relative; @@ -38,12 +30,6 @@ export const MonitorListHeader: React.FC = () => { - - - ); }; diff --git a/x-pack/plugins/uptime/public/pages/__tests__/page_header.test.tsx b/x-pack/plugins/uptime/public/pages/__tests__/page_header.test.tsx deleted file mode 100644 index 63d4c24f965d9..0000000000000 --- a/x-pack/plugins/uptime/public/pages/__tests__/page_header.test.tsx +++ /dev/null @@ -1,38 +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 React from 'react'; -import { PageHeader } from '../page_header'; -import { renderWithRouter, MountWithReduxProvider } from '../../lib'; - -describe('PageHeader', () => { - it('shallow renders with the date picker', () => { - const component = renderWithRouter( - - - - ); - expect(component).toMatchSnapshot('page_header_with_date_picker'); - }); - - it('shallow renders without the date picker', () => { - const component = renderWithRouter( - - - - ); - expect(component).toMatchSnapshot('page_header_no_date_picker'); - }); - - it('shallow renders extra links', () => { - const component = renderWithRouter( - - - - ); - expect(component).toMatchSnapshot('page_header_with_extra_links'); - }); -}); diff --git a/x-pack/plugins/uptime/public/pages/certificates.tsx b/x-pack/plugins/uptime/public/pages/certificates.tsx index a524ce6ba9b71..12088a2aeac97 100644 --- a/x-pack/plugins/uptime/public/pages/certificates.tsx +++ b/x-pack/plugins/uptime/public/pages/certificates.tsx @@ -5,7 +5,6 @@ */ import { useDispatch, useSelector } from 'react-redux'; -import { useHistory } from 'react-router-dom'; import { EuiButton, EuiButtonEmpty, @@ -15,13 +14,13 @@ import { EuiSpacer, EuiHideFor, EuiShowFor, + EuiTitle, } from '@elastic/eui'; import React, { useContext, useEffect, useState } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { useTrackPageview } from '../../../observability/public'; -import { PageHeader } from './page_header'; +import { PageHeader } from '../components/common/header/page_header'; import { useBreadcrumbs } from '../hooks/use_breadcrumbs'; -import { OVERVIEW_ROUTE, SETTINGS_ROUTE } from '../../common/constants'; import { getDynamicSettings } from '../state/actions/dynamic_settings'; import { UptimeRefreshContext } from '../contexts'; import * as labels from './translations'; @@ -29,7 +28,6 @@ import { certificatesSelector, getCertificatesAction } from '../state/certificat import { CertificateList, CertificateSearch, CertSort } from '../components/certificates'; import { ToggleAlertFlyoutButton } from '../components/overview/alerts/alerts_containers'; import { CLIENT_ALERT_TYPES } from '../../common/constants/alerts'; -import { ReactRouterEuiButtonEmpty } from '../components/common/react_router_helpers'; const DEFAULT_PAGE_SIZE = 10; const LOCAL_STORAGE_KEY = 'xpack.uptime.certList.pageSize'; @@ -74,38 +72,16 @@ export const CertificatesPage: React.FC = () => { }, [dispatch, page, search, sort.direction, sort.field, lastRefresh]); const { data: certificates } = useSelector(certificatesSelector); - const history = useHistory(); return ( <> - - - {labels.RETURN_TO_OVERVIEW} - + + - - - {labels.SETTINGS_ON_CERT} - - { - +

{ total: {certificates?.total ?? 0}, }} /> - } - datePicker={false} - /> +

+ + diff --git a/x-pack/plugins/uptime/public/pages/monitor.tsx b/x-pack/plugins/uptime/public/pages/monitor.tsx index d0173d2d96220..40f27bc1b9b24 100644 --- a/x-pack/plugins/uptime/public/pages/monitor.tsx +++ b/x-pack/plugins/uptime/public/pages/monitor.tsx @@ -8,7 +8,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import React, { useEffect } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { monitorStatusSelector } from '../state/selectors'; -import { PageHeader } from './page_header'; +import { PageHeader } from '../components/common/header/page_header'; import { useBreadcrumbs } from '../hooks/use_breadcrumbs'; import { useTrackPageview } from '../../../observability/public'; import { useMonitorId } from '../hooks'; diff --git a/x-pack/plugins/uptime/public/pages/overview.tsx b/x-pack/plugins/uptime/public/pages/overview.tsx index 9594819e385c0..7d8998c2e8906 100644 --- a/x-pack/plugins/uptime/public/pages/overview.tsx +++ b/x-pack/plugins/uptime/public/pages/overview.tsx @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { useDispatch } from 'react-redux'; import { useGetUrlParams } from '../hooks'; import { stringifyUrlParams } from '../lib/helper/stringify_url_params'; -import { PageHeader } from './page_header'; +import { PageHeader } from '../components/common/header/page_header'; import { IIndexPattern } from '../../../../../src/plugins/data/public'; import { useUpdateKueryString } from '../hooks'; import { useBreadcrumbs } from '../hooks/use_breadcrumbs'; @@ -65,16 +65,11 @@ export const OverviewPageComponent = React.memo( 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.`, - }); - useBreadcrumbs([]); // No extra breadcrumbs on overview return ( <> - + @@ -90,7 +85,7 @@ export const OverviewPageComponent = React.memo( {error && !loading && } - + diff --git a/x-pack/plugins/uptime/public/pages/page_header.tsx b/x-pack/plugins/uptime/public/pages/page_header.tsx deleted file mode 100644 index 08e753f38ab74..0000000000000 --- a/x-pack/plugins/uptime/public/pages/page_header.tsx +++ /dev/null @@ -1,107 +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 React from 'react'; -import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import styled from 'styled-components'; -import { UptimeDatePicker } from '../components/common/uptime_date_picker'; -import { SETTINGS_ROUTE } from '../../common/constants'; -import { ToggleAlertFlyoutButton } from '../components/overview/alerts/alerts_containers'; -import { useKibana } from '../../../../../src/plugins/kibana_react/public'; -import { ReactRouterEuiButtonEmpty } from '../components/common/react_router_helpers'; -import { SyntheticsCallout } from '../components/overview/synthetics_callout'; - -interface PageHeaderProps { - headingText: string | JSX.Element; - extraLinks?: boolean; - datePicker?: boolean; -} - -export const SETTINGS_LINK_TEXT = i18n.translate('xpack.uptime.page_header.settingsLink', { - defaultMessage: 'Settings', -}); - -const ADD_DATA_LABEL = i18n.translate('xpack.uptime.addDataButtonLabel', { - defaultMessage: 'Add data', -}); - -const StyledPicker = styled(EuiFlexItem)` - &&& { - @media only screen and (max-width: 1024px) and (min-width: 868px) { - .euiSuperDatePicker__flexWrapper { - width: 500px; - } - } - @media only screen and (max-width: 880px) { - flex-grow: 1; - .euiSuperDatePicker__flexWrapper { - width: calc(100% + 8px); - } - } - } -`; - -export const PageHeader = React.memo( - ({ headingText, extraLinks = false, datePicker = true }: PageHeaderProps) => { - const DatePickerComponent = () => - datePicker ? ( - - - - ) : null; - - const kibana = useKibana(); - - const extraLinkComponents = !extraLinks ? null : ( - - - - - - - {SETTINGS_LINK_TEXT} - - - - - {ADD_DATA_LABEL} - - - - ); - - return ( - <> - - - - -

{headingText}

-
-
- {extraLinks && {extraLinkComponents}} - -
- - - ); - } -); diff --git a/x-pack/plugins/uptime/public/pages/settings.tsx b/x-pack/plugins/uptime/public/pages/settings.tsx index 72d52b3497bb1..babf8c58091c1 100644 --- a/x-pack/plugins/uptime/public/pages/settings.tsx +++ b/x-pack/plugins/uptime/public/pages/settings.tsx @@ -35,6 +35,7 @@ import { } from '../../common/translations'; import { ReactRouterEuiButtonEmpty } from '../components/common/react_router_helpers'; import { AlertDefaultsForm } from '../components/settings/alert_defaults_form'; +import { PageHeader } from '../components/common/header/page_header'; interface SettingsPageFieldErrors { heartbeatIndices: string | ''; @@ -147,17 +148,9 @@ export const SettingsPage: React.FC = () => { return ( <> - - {Translations.settings.returnToOverviewLinkLabel} - + - + {cannotEditNotice} diff --git a/x-pack/plugins/uptime/public/pages/translations.ts b/x-pack/plugins/uptime/public/pages/translations.ts index dae4760edc469..6fb183051d7b8 100644 --- a/x-pack/plugins/uptime/public/pages/translations.ts +++ b/x-pack/plugins/uptime/public/pages/translations.ts @@ -6,17 +6,6 @@ import { i18n } from '@kbn/i18n'; -export const SETTINGS_ON_CERT = i18n.translate('xpack.uptime.certificates.settingsLinkLabel', { - defaultMessage: 'Settings', -}); - -export const RETURN_TO_OVERVIEW = i18n.translate( - 'xpack.uptime.certificates.returnToOverviewLinkLabel', - { - defaultMessage: 'Return to overview', - } -); - export const REFRESH_CERT = i18n.translate('xpack.uptime.certificates.refresh', { defaultMessage: 'Refresh', }); @@ -32,9 +21,6 @@ export const settings = { defaultMessage: "Your user currently has 'Read' permissions for the Uptime app. Enable a permissions-level of 'All' to edit these settings.", }), - returnToOverviewLinkLabel: i18n.translate('xpack.uptime.settings.returnToOverviewLinkLabel', { - defaultMessage: 'Return to overview', - }), mustBeNumber: i18n.translate('xpack.uptime.settings.blankNumberField.error', { defaultMessage: 'Must be a number.', }), From 63fbb2c8120c4e54a423f7c504ed7bfa5837fbfd Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 19 Nov 2020 10:19:36 +0100 Subject: [PATCH 02/19] update --- .../uptime/public/apps/action_menu.tsx | 36 +++++++++ .../header/__tests__/page_header.test.tsx | 38 +++++++++ .../components/common/header/page_header.tsx | 71 ++++++++++++++++ .../components/common/header/page_tabs.tsx | 81 +++++++++++++++++++ 4 files changed, 226 insertions(+) create mode 100644 x-pack/plugins/uptime/public/apps/action_menu.tsx create mode 100644 x-pack/plugins/uptime/public/components/common/header/__tests__/page_header.test.tsx create mode 100644 x-pack/plugins/uptime/public/components/common/header/page_header.tsx create mode 100644 x-pack/plugins/uptime/public/components/common/header/page_tabs.tsx diff --git a/x-pack/plugins/uptime/public/apps/action_menu.tsx b/x-pack/plugins/uptime/public/apps/action_menu.tsx new file mode 100644 index 0000000000000..a67be0dd43c85 --- /dev/null +++ b/x-pack/plugins/uptime/public/apps/action_menu.tsx @@ -0,0 +1,36 @@ +/* + * 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 { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { ToggleAlertFlyoutButton } from '../components/overview/alerts/alerts_containers'; +import { useKibana } from '../../../../../src/plugins/kibana_react/public'; + +const ADD_DATA_LABEL = i18n.translate('xpack.uptime.addDataButtonLabel', { + defaultMessage: 'Add data', +}); + +export const ActionMenu = () => { + const kibana = useKibana(); + + return ( + + + + + + + {ADD_DATA_LABEL} + + + + ); +}; diff --git a/x-pack/plugins/uptime/public/components/common/header/__tests__/page_header.test.tsx b/x-pack/plugins/uptime/public/components/common/header/__tests__/page_header.test.tsx new file mode 100644 index 0000000000000..ea4b5cef4cc70 --- /dev/null +++ b/x-pack/plugins/uptime/public/components/common/header/__tests__/page_header.test.tsx @@ -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 React from 'react'; +import { PageHeader } from '../page_header'; +import { renderWithRouter, MountWithReduxProvider } from '../../../../lib'; + +describe('PageHeader', () => { + it('shallow renders with the date picker', () => { + const component = renderWithRouter( + + + + ); + expect(component).toMatchSnapshot('page_header_with_date_picker'); + }); + + it('shallow renders without the date picker', () => { + const component = renderWithRouter( + + + + ); + expect(component).toMatchSnapshot('page_header_no_date_picker'); + }); + + it('shallow renders extra links', () => { + const component = renderWithRouter( + + + + ); + expect(component).toMatchSnapshot('page_header_with_extra_links'); + }); +}); 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 new file mode 100644 index 0000000000000..a229834730f65 --- /dev/null +++ b/x-pack/plugins/uptime/public/components/common/header/page_header.tsx @@ -0,0 +1,71 @@ +/* + * 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 { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; +import { Route, useRouteMatch } from 'react-router-dom'; +import styled from 'styled-components'; +import { UptimeDatePicker } from '../uptime_date_picker'; +import { ToggleAlertFlyoutButton } from '../../overview/alerts/alerts_containers'; +import { SyntheticsCallout } from '../../overview/synthetics_callout'; +import { PageTabs } from './page_tabs'; + +interface PageHeaderProps { + extraLinks?: boolean; + datePicker?: boolean; +} + +const StyledPicker = styled(EuiFlexItem)` + &&& { + @media only screen and (max-width: 1024px) and (min-width: 868px) { + .euiSuperDatePicker__flexWrapper { + width: 500px; + } + } + @media only screen and (max-width: 880px) { + flex-grow: 1; + .euiSuperDatePicker__flexWrapper { + width: calc(100% + 8px); + } + } + } +`; + +export const PageHeader = React.memo( + ({ extraLinks = false, datePicker = true }: PageHeaderProps) => { + const DatePickerComponent = () => + datePicker ? ( + + + + ) : null; + + const match = useRouteMatch(); + + return ( + <> + + + + + + + + + + + + + + ); + } +); 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 new file mode 100644 index 0000000000000..12418cb38cde8 --- /dev/null +++ b/x-pack/plugins/uptime/public/components/common/header/page_tabs.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, { useEffect, useState } from 'react'; + +import { EuiTabs, EuiTab } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { useHistory, useRouteMatch } from 'react-router-dom'; +import { CERTIFICATES_ROUTE, OVERVIEW_ROUTE, SETTINGS_ROUTE } from '../../../../common/constants'; + +const tabs = [ + { + id: OVERVIEW_ROUTE, + name: 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.`, + }), + dataTestSubj: 'uptimeSettingsToOverviewLink', + }, + { + id: CERTIFICATES_ROUTE, + name: 'Certificates', + dataTestSubj: 'uptimeCertificatesLink', + }, + { + id: SETTINGS_ROUTE, + dataTestSubj: 'settings-page-link', + name: i18n.translate('xpack.uptime.page_header.settingsLink', { + defaultMessage: 'Settings', + }), + }, +]; + +export const PageTabs = () => { + const [selectedTabId, setSelectedTabId] = useState('overview'); + + const history = useHistory(); + + const isOverView = useRouteMatch(OVERVIEW_ROUTE); + const isSettings = useRouteMatch(SETTINGS_ROUTE); + const isCerts = useRouteMatch(CERTIFICATES_ROUTE); + + const onSelectedTabChanged = (routeId: string) => { + setSelectedTabId(routeId); + history.push(routeId); + }; + + useEffect(() => { + if (isOverView) { + setSelectedTabId(OVERVIEW_ROUTE); + } + if (isCerts) { + setSelectedTabId(CERTIFICATES_ROUTE); + } + if (isSettings) { + setSelectedTabId(SETTINGS_ROUTE); + } + }, [isOverView, isSettings, isCerts]); + + const renderTabs = () => { + return tabs.map((tab, index, dataTestSubj) => ( + onSelectedTabChanged(tab.id)} + isSelected={tab.id === selectedTabId} + key={index} + data-test-subj={dataTestSubj} + > + {tab.name} + + )); + }; + + return ( + + {renderTabs()} + + ); +}; From 1d0c1dd6bbbd32d9a41a1226badbfcf862ff94a7 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 19 Nov 2020 10:46:30 +0100 Subject: [PATCH 03/19] update --- .../uptime/public/apps/action_menu.tsx | 34 +++++++++++-------- .../plugins/uptime/public/apps/render_app.tsx | 24 +++---------- .../plugins/uptime/public/apps/uptime_app.tsx | 15 +++----- 3 files changed, 28 insertions(+), 45 deletions(-) diff --git a/x-pack/plugins/uptime/public/apps/action_menu.tsx b/x-pack/plugins/uptime/public/apps/action_menu.tsx index a67be0dd43c85..835184102558d 100644 --- a/x-pack/plugins/uptime/public/apps/action_menu.tsx +++ b/x-pack/plugins/uptime/public/apps/action_menu.tsx @@ -9,28 +9,32 @@ import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { ToggleAlertFlyoutButton } from '../components/overview/alerts/alerts_containers'; import { useKibana } from '../../../../../src/plugins/kibana_react/public'; +import { HeaderMenuPortal } from '../../../observability/public'; +import { AppMountParameters } from '../../../../../src/core/public'; const ADD_DATA_LABEL = i18n.translate('xpack.uptime.addDataButtonLabel', { defaultMessage: 'Add data', }); -export const ActionMenu = () => { +export const ActionMenu = ({ appMountParameters }: { appMountParameters: AppMountParameters }) => { const kibana = useKibana(); return ( - - - - - - - {ADD_DATA_LABEL} - - - + + + + + + + + {ADD_DATA_LABEL} + + + + ); }; diff --git a/x-pack/plugins/uptime/public/apps/render_app.tsx b/x-pack/plugins/uptime/public/apps/render_app.tsx index 708dfa5b46297..803431dc25b24 100644 --- a/x-pack/plugins/uptime/public/apps/render_app.tsx +++ b/x-pack/plugins/uptime/public/apps/render_app.tsx @@ -8,7 +8,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { i18n as i18nFormatter } from '@kbn/i18n'; import { AppMountParameters, CoreStart } from 'kibana/public'; -import { createPortalNode, OutPortal } from 'react-reverse-portal'; import { getIntegratedAppAvailability } from '../lib/adapters/framework/capabilities_adapter'; import { DEFAULT_DARK_MODE, @@ -22,7 +21,7 @@ export function renderApp( core: CoreStart, plugins: ClientPluginsSetup, startPlugins: ClientPluginsStart, - { element, history, setHeaderActionMenu }: AppMountParameters + appMountParameters: AppMountParameters ) { const { application: { capabilities }, @@ -32,8 +31,6 @@ export function renderApp( i18n, } = core; - const portalNode = createPortalNode(); - const { apm, infrastructure, logs } = getIntegratedAppAvailability( capabilities, INTEGRATED_SOLUTIONS @@ -50,11 +47,9 @@ export function renderApp( basePath: basePath.get(), darkMode: core.uiSettings.get(DEFAULT_DARK_MODE), commonlyUsedRanges: core.uiSettings.get(DEFAULT_TIMEPICKER_QUICK_RANGES), - history, isApmAvailable: apm, isInfraAvailable: infrastructure, isLogsAvailable: logs, - actionMenu: portalNode, renderGlobalHelpControls: () => setHelpExtension({ appName: i18nFormatter.translate('xpack.uptime.header.appName', { @@ -72,24 +67,13 @@ export function renderApp( ], }), setBadge, + appMountParameters, setBreadcrumbs: core.chrome.setBreadcrumbs, }; - function renderActionMenu(elem: HTMLElement) { - ReactDOM.render(, elem); - - return () => { - ReactDOM.unmountComponentAtNode(elem); - }; - } - - setHeaderActionMenu((elem) => { - return renderActionMenu(elem); - }); - - ReactDOM.render(, element); + ReactDOM.render(, appMountParameters.element); return () => { - ReactDOM.unmountComponentAtNode(element); + ReactDOM.unmountComponentAtNode(appMountParameters.element); }; } diff --git a/x-pack/plugins/uptime/public/apps/uptime_app.tsx b/x-pack/plugins/uptime/public/apps/uptime_app.tsx index 4ab3be02d0737..c7caf9959e7e0 100644 --- a/x-pack/plugins/uptime/public/apps/uptime_app.tsx +++ b/x-pack/plugins/uptime/public/apps/uptime_app.tsx @@ -9,8 +9,7 @@ import { i18n } from '@kbn/i18n'; import React, { useEffect } from 'react'; import { Provider as ReduxProvider } from 'react-redux'; import { Router } from 'react-router-dom'; -import { I18nStart, ChromeBreadcrumb, CoreStart } from 'kibana/public'; -import { InPortal, PortalNode } from 'react-reverse-portal'; +import { I18nStart, ChromeBreadcrumb, CoreStart, AppMountParameters } from 'kibana/public'; import { KibanaContextProvider, RedirectAppLinks, @@ -32,7 +31,6 @@ import { } from '../components/overview/alerts'; import { store } from '../state'; import { kibanaService } from '../state/kibana_service'; -import { ScopedHistory } from '../../../../../src/core/public'; import { ActionMenu } from './action_menu'; export interface UptimeAppColors { @@ -50,7 +48,6 @@ export interface UptimeAppProps { canSave: boolean; core: CoreStart; darkMode: boolean; - history: ScopedHistory; i18n: I18nStart; isApmAvailable: boolean; isInfraAvailable: boolean; @@ -61,7 +58,7 @@ export interface UptimeAppProps { renderGlobalHelpControls(): void; commonlyUsedRanges: CommonlyUsedRange[]; setBreadcrumbs: (crumbs: ChromeBreadcrumb[]) => void; - actionMenu: PortalNode; + appMountParameters: AppMountParameters; } const Application = (props: UptimeAppProps) => { @@ -75,7 +72,7 @@ const Application = (props: UptimeAppProps) => { renderGlobalHelpControls, setBadge, startPlugins, - actionMenu, + appMountParameters, } = props; useEffect(() => { @@ -104,7 +101,7 @@ const Application = (props: UptimeAppProps) => { - + @@ -115,9 +112,7 @@ const Application = (props: UptimeAppProps) => {
- - - +
From 49133836083cce804ae97996c35c6e83652815cd Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 19 Nov 2020 11:40:32 +0100 Subject: [PATCH 04/19] revert --- .../plugins/uptime/public/apps/uptime_app.tsx | 2 +- .../common/header}/action_menu.tsx | 8 +-- .../components/common/header/page_header.tsx | 64 ++++++++----------- .../toggle_alert_flyout_button.tsx | 23 +------ .../alerts/toggle_alert_flyout_button.tsx | 10 +-- .../plugins/uptime/public/pages/overview.tsx | 2 +- 6 files changed, 36 insertions(+), 73 deletions(-) rename x-pack/plugins/uptime/public/{apps => components/common/header}/action_menu.tsx (80%) diff --git a/x-pack/plugins/uptime/public/apps/uptime_app.tsx b/x-pack/plugins/uptime/public/apps/uptime_app.tsx index c7caf9959e7e0..0aeeab62a2686 100644 --- a/x-pack/plugins/uptime/public/apps/uptime_app.tsx +++ b/x-pack/plugins/uptime/public/apps/uptime_app.tsx @@ -31,7 +31,7 @@ import { } from '../components/overview/alerts'; import { store } from '../state'; import { kibanaService } from '../state/kibana_service'; -import { ActionMenu } from './action_menu'; +import { ActionMenu } from '../components/common/header/action_menu'; export interface UptimeAppColors { danger: string; diff --git a/x-pack/plugins/uptime/public/apps/action_menu.tsx b/x-pack/plugins/uptime/public/components/common/header/action_menu.tsx similarity index 80% rename from x-pack/plugins/uptime/public/apps/action_menu.tsx rename to x-pack/plugins/uptime/public/components/common/header/action_menu.tsx index 835184102558d..62b79e21e6eed 100644 --- a/x-pack/plugins/uptime/public/apps/action_menu.tsx +++ b/x-pack/plugins/uptime/public/components/common/header/action_menu.tsx @@ -7,10 +7,10 @@ import React from 'react'; import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { ToggleAlertFlyoutButton } from '../components/overview/alerts/alerts_containers'; -import { useKibana } from '../../../../../src/plugins/kibana_react/public'; -import { HeaderMenuPortal } from '../../../observability/public'; -import { AppMountParameters } from '../../../../../src/core/public'; +import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; +import { HeaderMenuPortal } from '../../../../../observability/public'; +import { AppMountParameters } from '../../../../../../../src/core/public'; +import { ToggleAlertFlyoutButton } from '../../overview/alerts/alerts_containers'; const ADD_DATA_LABEL = i18n.translate('xpack.uptime.addDataButtonLabel', { defaultMessage: 'Add data', 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 a229834730f65..84f3d73891397 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 @@ -6,15 +6,12 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; -import { Route, useRouteMatch } from 'react-router-dom'; import styled from 'styled-components'; import { UptimeDatePicker } from '../uptime_date_picker'; -import { ToggleAlertFlyoutButton } from '../../overview/alerts/alerts_containers'; import { SyntheticsCallout } from '../../overview/synthetics_callout'; import { PageTabs } from './page_tabs'; interface PageHeaderProps { - extraLinks?: boolean; datePicker?: boolean; } @@ -34,38 +31,31 @@ const StyledPicker = styled(EuiFlexItem)` } `; -export const PageHeader = React.memo( - ({ extraLinks = false, datePicker = true }: PageHeaderProps) => { - const DatePickerComponent = () => - datePicker ? ( - - - - ) : null; +export const PageHeader = React.memo(({ datePicker = true }: PageHeaderProps) => { + const DatePickerComponent = () => + datePicker ? ( + + + + ) : null; - const match = useRouteMatch(); - - return ( - <> - - - - - - - - - - - - - - ); - } -); + return ( + <> + + + + + + + + + + + ); +}); diff --git a/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx b/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx index c8a86b3f16522..2eee3ada8c004 100644 --- a/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx +++ b/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx @@ -4,12 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useEffect } from 'react'; +import React from 'react'; import { useDispatch } from 'react-redux'; -import { useRouteMatch } from 'react-router-dom'; import { setAlertFlyoutType, setAlertFlyoutVisible } from '../../../../state/actions'; import { ToggleAlertFlyoutButtonComponent } from '../index'; -import { CLIENT_ALERT_TYPES } from '../../../../../common/constants/alerts'; export interface ToggleAlertFlyoutButtonProps { alertOptions?: string[]; @@ -17,25 +15,6 @@ export interface ToggleAlertFlyoutButtonProps { export const ToggleAlertFlyoutButton: React.FC = (props) => { const dispatch = useDispatch(); - - const isCreateAlert = useRouteMatch('/status-alert/new'); - - const isTlsAlert = useRouteMatch('/tls-alert/new'); - - useEffect(() => { - if (isCreateAlert) { - dispatch(setAlertFlyoutType(CLIENT_ALERT_TYPES.MONITOR_STATUS)); - dispatch(setAlertFlyoutVisible(true)); - } - }, [isCreateAlert, dispatch]); - - useEffect(() => { - if (isTlsAlert) { - dispatch(setAlertFlyoutType(CLIENT_ALERT_TYPES.TLS)); - dispatch(setAlertFlyoutVisible(true)); - } - }, [isTlsAlert, dispatch]); - return ( = ({ }) => { const [isOpen, setIsOpen] = useState(false); const kibana = useKibana(); - - const history = useHistory(); - const monitorStatusAlertContextMenuItem: EuiContextMenuPanelItemDescriptor = { 'aria-label': ToggleFlyoutTranslations.toggleMonitorStatusAriaLabel, 'data-test-subj': 'xpack.uptime.toggleAlertFlyout', name: ToggleFlyoutTranslations.toggleMonitorStatusContent, onClick: () => { - // setAlertFlyoutVisible(CLIENT_ALERT_TYPES.MONITOR_STATUS); + setAlertFlyoutVisible(CLIENT_ALERT_TYPES.MONITOR_STATUS); setIsOpen(false); - history.push('/status-alert/new'); }, }; @@ -54,9 +49,8 @@ export const ToggleAlertFlyoutButtonComponent: React.FC = ({ 'data-test-subj': 'xpack.uptime.toggleTlsAlertFlyout', name: ToggleFlyoutTranslations.toggleTlsContent, onClick: () => { - // setAlertFlyoutVisible(CLIENT_ALERT_TYPES.TLS); + setAlertFlyoutVisible(CLIENT_ALERT_TYPES.TLS); setIsOpen(false); - history.push('/tls-alert/new'); }, }; diff --git a/x-pack/plugins/uptime/public/pages/overview.tsx b/x-pack/plugins/uptime/public/pages/overview.tsx index 7d8998c2e8906..c3dcca53be059 100644 --- a/x-pack/plugins/uptime/public/pages/overview.tsx +++ b/x-pack/plugins/uptime/public/pages/overview.tsx @@ -69,7 +69,7 @@ export const OverviewPageComponent = React.memo( return ( <> - + From 81443e4a8fad932c08e69c7cf1fa691199b55b0d Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 19 Nov 2020 12:17:19 +0100 Subject: [PATCH 05/19] update header --- .../components/common/header/page_header.tsx | 21 +++++++++++++++---- .../components/common/header/page_tabs.tsx | 8 +++---- .../uptime_alerts_flyout_wrapper.tsx | 10 +-------- .../uptime/public/pages/certificates.tsx | 7 ------- 4 files changed, 22 insertions(+), 24 deletions(-) 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 84f3d73891397..4ef3e6a02a701 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,14 +5,17 @@ */ import React from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, EuiSpacer, EuiTitle } 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 { MONITOR_ROUTE } from '../../../../common/constants'; interface PageHeaderProps { datePicker?: boolean; + headingText?: string | JSX.Element; } const StyledPicker = styled(EuiFlexItem)` @@ -31,7 +34,7 @@ const StyledPicker = styled(EuiFlexItem)` } `; -export const PageHeader = React.memo(({ datePicker = true }: PageHeaderProps) => { +export const PageHeader = React.memo(({ datePicker = true, headingText }: PageHeaderProps) => { const DatePickerComponent = () => datePicker ? ( @@ -39,6 +42,8 @@ export const PageHeader = React.memo(({ datePicker = true }: PageHeaderProps) => ) : null; + const isMonRoute = useRouteMatch(MONITOR_ROUTE); + return ( <> @@ -51,11 +56,19 @@ export const PageHeader = React.memo(({ datePicker = true }: PageHeaderProps) => > - - + {isMonRoute && } + {!isMonRoute && } + {headingText && ( + <> + +

{headingText}

+
+ + + )} ); }); 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 12418cb38cde8..ce69fd4f9e355 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 @@ -6,7 +6,7 @@ import React, { useEffect, useState } from 'react'; -import { EuiTabs, EuiTab } from '@elastic/eui'; +import { EuiTabs, EuiTab, EuiHorizontalRule } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useHistory, useRouteMatch } from 'react-router-dom'; import { CERTIFICATES_ROUTE, OVERVIEW_ROUTE, SETTINGS_ROUTE } from '../../../../common/constants'; @@ -49,7 +49,7 @@ export const PageTabs = () => { }; useEffect(() => { - if (isOverView) { + if (isOverView?.isExact) { setSelectedTabId(OVERVIEW_ROUTE); } if (isCerts) { @@ -61,12 +61,12 @@ export const PageTabs = () => { }, [isOverView, isSettings, isCerts]); const renderTabs = () => { - return tabs.map((tab, index, dataTestSubj) => ( + return tabs.map((tab, index) => ( onSelectedTabChanged(tab.id)} isSelected={tab.id === selectedTabId} key={index} - data-test-subj={dataTestSubj} + data-test-subj={tab.dataTestSubj} > {tab.name} diff --git a/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/uptime_alerts_flyout_wrapper.tsx b/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/uptime_alerts_flyout_wrapper.tsx index 024cb3c63bf3b..33eafbd1e21bc 100644 --- a/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/uptime_alerts_flyout_wrapper.tsx +++ b/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/uptime_alerts_flyout_wrapper.tsx @@ -6,23 +6,15 @@ import React from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useHistory } from 'react-router-dom'; import { setAlertFlyoutVisible } from '../../../../state/actions'; import { UptimeAlertsFlyoutWrapperComponent } from '../uptime_alerts_flyout_wrapper'; import { selectAlertFlyoutVisibility, selectAlertFlyoutType } from '../../../../state/selectors'; export const UptimeAlertsFlyoutWrapper: React.FC = () => { const dispatch = useDispatch(); - - const history = useHistory(); - - const setAddFlyoutVisibility = (value: React.SetStateAction) => { + const setAddFlyoutVisibility = (value: React.SetStateAction) => // @ts-ignore the value here is a boolean, and it works with the action creator function dispatch(setAlertFlyoutVisible(value)); - if (!value) { - history.push('/'); - } - }; const alertFlyoutVisible = useSelector(selectAlertFlyoutVisibility); const alertTypeId = useSelector(selectAlertFlyoutType); diff --git a/x-pack/plugins/uptime/public/pages/certificates.tsx b/x-pack/plugins/uptime/public/pages/certificates.tsx index 12088a2aeac97..207b241a87049 100644 --- a/x-pack/plugins/uptime/public/pages/certificates.tsx +++ b/x-pack/plugins/uptime/public/pages/certificates.tsx @@ -26,8 +26,6 @@ import { UptimeRefreshContext } from '../contexts'; import * as labels from './translations'; import { certificatesSelector, getCertificatesAction } from '../state/certificates/certificates'; import { CertificateList, CertificateSearch, CertSort } from '../components/certificates'; -import { ToggleAlertFlyoutButton } from '../components/overview/alerts/alerts_containers'; -import { CLIENT_ALERT_TYPES } from '../../common/constants/alerts'; const DEFAULT_PAGE_SIZE = 10; const LOCAL_STORAGE_KEY = 'xpack.uptime.certList.pageSize'; @@ -79,9 +77,6 @@ export const CertificatesPage: React.FC = () => { - - - {
- -

From 38e13484bc1a97b6cd995cc381f6d3811dff23ad Mon Sep 17 00:00:00 2001 From: Shahzad Date: Fri, 20 Nov 2020 15:12:08 +0100 Subject: [PATCH 06/19] update --- .../certificates/cert_refresh_btn.tsx | 51 ++++ .../__snapshots__/page_header.test.tsx.snap | 276 ++++++++++++------ .../components/common/header/action_menu.tsx | 2 +- .../components/common/header/page_header.tsx | 30 +- .../components/common/header/page_tabs.tsx | 22 +- .../__snapshots__/monitor_list.test.tsx.snap | 53 +--- .../uptime/public/pages/certificates.tsx | 96 ++---- .../plugins/uptime/public/pages/monitor.tsx | 32 +- .../plugins/uptime/public/pages/overview.tsx | 1 - .../plugins/uptime/public/pages/settings.tsx | 4 - x-pack/plugins/uptime/public/routes.tsx | 26 +- 11 files changed, 327 insertions(+), 266 deletions(-) create mode 100644 x-pack/plugins/uptime/public/components/certificates/cert_refresh_btn.tsx rename x-pack/plugins/uptime/public/{pages => components/common/header}/__tests__/__snapshots__/page_header.test.tsx.snap (79%) 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 new file mode 100644 index 0000000000000..593b7afa4ecca --- /dev/null +++ b/x-pack/plugins/uptime/public/components/certificates/cert_refresh_btn.tsx @@ -0,0 +1,51 @@ +/* + * 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, { useContext } from 'react'; +import * as labels from '../../pages/translations'; +import { + EuiButton, + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiHideFor, + EuiShowFor, +} from '@elastic/eui'; +import { UptimeRefreshContext } from '../../contexts'; + +export const CertRefreshBtn = () => { + const { refreshApp } = useContext(UptimeRefreshContext); + + return ( + + + + + { + refreshApp(); + }} + data-test-subj="superDatePickerApplyTimeButton" + > + {labels.REFRESH_CERT} + + + + { + refreshApp(); + }} + data-test-subj="superDatePickerApplyTimeButton" + /> + + + + + ); +}; diff --git a/x-pack/plugins/uptime/public/pages/__tests__/__snapshots__/page_header.test.tsx.snap b/x-pack/plugins/uptime/public/components/common/header/__tests__/__snapshots__/page_header.test.tsx.snap similarity index 79% rename from x-pack/plugins/uptime/public/pages/__tests__/__snapshots__/page_header.test.tsx.snap rename to x-pack/plugins/uptime/public/components/common/header/__tests__/__snapshots__/page_header.test.tsx.snap index 7bb578494ab44..8944b1008c251 100644 --- a/x-pack/plugins/uptime/public/pages/__tests__/__snapshots__/page_header.test.tsx.snap +++ b/x-pack/plugins/uptime/public/components/common/header/__tests__/__snapshots__/page_header.test.tsx.snap @@ -111,97 +111,51 @@ Array [ >
-

- TestingHeading -

-
-
- - -
+ + -
+ Settings + +
, + @media only screen and (max-width:1024px) and (min-width:868px) { + +} + +@media only screen and (max-width:880px) { + +} + +

+ TestingHeading +

, + @media only screen and (max-width:1024px) and (min-width:868px) { + +} + +@media only screen and (max-width:880px) { + +} + +
, ] `; @@ -425,11 +403,51 @@ Array [
-

- TestingHeading -

+ + + +
, + @media only screen and (max-width:1024px) and (min-width:868px) { + +} + +@media only screen and (max-width:880px) { + +} + +

+ TestingHeading +

, + @media only screen and (max-width:1024px) and (min-width:868px) { + +} + +@media only screen and (max-width:880px) { + +} + +
, ] `; @@ -617,15 +659,63 @@ Array [
-

- TestingHeading -

+ + + +
,
, +

+ TestingHeading +

, +
, ] `; diff --git a/x-pack/plugins/uptime/public/components/common/header/action_menu.tsx b/x-pack/plugins/uptime/public/components/common/header/action_menu.tsx index 62b79e21e6eed..0946806557a96 100644 --- a/x-pack/plugins/uptime/public/components/common/header/action_menu.tsx +++ b/x-pack/plugins/uptime/public/components/common/header/action_menu.tsx @@ -29,7 +29,7 @@ export const ActionMenu = ({ appMountParameters }: { appMountParameters: AppMoun {ADD_DATA_LABEL} 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 4ef3e6a02a701..17e25892b7732 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,18 +5,14 @@ */ import React from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, EuiSpacer, EuiTitle } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, 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 { MONITOR_ROUTE } from '../../../../common/constants'; - -interface PageHeaderProps { - datePicker?: boolean; - headingText?: string | JSX.Element; -} +import { CERTIFICATES_ROUTE, MONITOR_ROUTE } from '../../../../common/constants'; +import { CertRefreshBtn } from '../../certificates/cert_refresh_btn'; const StyledPicker = styled(EuiFlexItem)` &&& { @@ -34,13 +30,17 @@ const StyledPicker = styled(EuiFlexItem)` } `; -export const PageHeader = React.memo(({ datePicker = true, headingText }: PageHeaderProps) => { +export const PageHeader = () => { + const isCertRoute = useRouteMatch(CERTIFICATES_ROUTE); + const DatePickerComponent = () => - datePicker ? ( + isCertRoute ? ( + + ) : ( - ) : null; + ); const isMonRoute = useRouteMatch(MONITOR_ROUTE); @@ -61,14 +61,6 @@ export const PageHeader = React.memo(({ datePicker = true, headingText }: PageHe {isMonRoute && } {!isMonRoute && } - {headingText && ( - <> - -

{headingText}

-
- - - )} ); -}); +}; 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 ce69fd4f9e355..5e20850d76873 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 @@ -6,7 +6,7 @@ import React, { useEffect, useState } from 'react'; -import { EuiTabs, EuiTab, EuiHorizontalRule } from '@elastic/eui'; +import { EuiTabs, EuiTab } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useHistory, useRouteMatch } from 'react-router-dom'; import { CERTIFICATES_ROUTE, OVERVIEW_ROUTE, SETTINGS_ROUTE } from '../../../../common/constants'; @@ -35,7 +35,7 @@ const tabs = [ ]; export const PageTabs = () => { - const [selectedTabId, setSelectedTabId] = useState('overview'); + const [selectedTabId, setSelectedTabId] = useState(null); const history = useHistory(); @@ -43,11 +43,6 @@ export const PageTabs = () => { const isSettings = useRouteMatch(SETTINGS_ROUTE); const isCerts = useRouteMatch(CERTIFICATES_ROUTE); - const onSelectedTabChanged = (routeId: string) => { - setSelectedTabId(routeId); - history.push(routeId); - }; - useEffect(() => { if (isOverView?.isExact) { setSelectedTabId(OVERVIEW_ROUTE); @@ -58,17 +53,18 @@ export const PageTabs = () => { if (isSettings) { setSelectedTabId(SETTINGS_ROUTE); } - }, [isOverView, isSettings, isCerts]); + }, []); const renderTabs = () => { - return tabs.map((tab, index) => ( + return tabs.map(({ dataTestSubj, name, id }, index) => ( onSelectedTabChanged(tab.id)} - isSelected={tab.id === selectedTabId} + onClick={() => setSelectedTabId(id)} + isSelected={id === selectedTabId} key={index} - data-test-subj={tab.dataTestSubj} + data-test-subj={dataTestSubj} + href={history.createHref({ pathname: id })} > - {tab.name} + {name} )); }; diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap index 1f5e86dc67386..9bc262dcf26ed 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap @@ -819,32 +819,26 @@ exports[`MonitorList component renders loading state 1`] = ` `; exports[`MonitorList component renders the monitor list 1`] = ` -.c3 { +.c2 { padding-left: 17px; } -.c5 { +.c4 { padding-top: 12px; } -.c1 { - position: absolute; - right: 16px; - top: 16px; -} - .c0 { position: relative; } -.c4 { +.c3 { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } @media (max-width:574px) { - .c2 { + .c1 { min-width: 230px; } } @@ -935,13 +929,6 @@ exports[`MonitorList component renders the monitor list 1`] = `
- - Certificates status -
+ />
+ />
- - +
, - @media only screen and (max-width:1024px) and (min-width:868px) { - -} - -@media only screen and (max-width:880px) { - -} - -

- TestingHeading -

, - @media only screen and (max-width:1024px) and (min-width:868px) { - -} - -@media only screen and (max-width:880px) { - -} - -
, ] `; @@ -408,45 +387,48 @@ Array [ role="tablist" style="padding-left:16px" > - - - +
, - @media only screen and (max-width:1024px) and (min-width:868px) { - -} - -@media only screen and (max-width:880px) { - -} +] +`; -

- TestingHeading -

, +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) { } @@ -577,14 +551,6 @@ Array [ }
, -] -`; - -exports[`PageHeader shallow renders without the date picker: page_header_no_date_picker 1`] = ` -Array [ -
, -
, - +
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+ + + +
, -
, -

- TestingHeading -

, -
, ] `; diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/columns/__tests__/enable_alert.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/columns/__tests__/enable_alert.test.tsx index 4f41ea4c0b895..7b6c98abaa838 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/columns/__tests__/enable_alert.test.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/columns/__tests__/enable_alert.test.tsx @@ -14,6 +14,7 @@ import { } from '../../../../../lib'; import { EuiPopover, EuiText } from '@elastic/eui'; import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../../../common/constants'; +import { ReactRouterEuiLink } from '../../../../common/react_router_helpers'; describe('EnableAlertComponent', () => { let defaultConnectors: string[] = []; @@ -64,8 +65,32 @@ describe('EnableAlertComponent', () => { expect(wrapper.find(EuiPopover)).toHaveLength(1); wrapper.find('button').simulate('click'); expect(wrapper.find(EuiText).text()).toBe( - 'To start enabling alerts, please define a default alert action connector in Settings' + 'To start enabling alerts, please define a default alert action connector in ' ); + expect(wrapper.find(ReactRouterEuiLink)).toMatchInlineSnapshot(` + + + + + + + + `); }); it('does not displays define connectors when there is connector', () => { From 2ce8f1f06e74a09a67569ee7b21fe0c1cb73e5fb Mon Sep 17 00:00:00 2001 From: Shahzad Date: Mon, 30 Nov 2020 17:52:34 +0100 Subject: [PATCH 08/19] update --- .../__snapshots__/monitor_list.test.tsx.snap | 31 ++++++------------- .../columns/define_connectors.tsx | 6 +++- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap index edd901253f509..161b333e85b03 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap @@ -831,26 +831,20 @@ exports[`MonitorList component renders loading state 1`] = ` `; exports[`MonitorList component renders the monitor list 1`] = ` -.c3 { +.c2 { padding-right: 4px; } -.c4 { +.c3 { padding-top: 12px; } -.c1 { - position: absolute; - right: 16px; - top: 16px; -} - .c0 { position: relative; } @media (max-width:574px) { - .c2 { + .c1 { min-width: 230px; } } @@ -941,13 +935,6 @@ exports[`MonitorList component renders the monitor list 1`] = `
- - Certificates status -
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
Date: Tue, 8 Dec 2020 19:26:35 +0100 Subject: [PATCH 18/19] update flaky test --- x-pack/test/functional/services/uptime/overview.ts | 12 +++++++++--- .../apps/uptime/simple_down_alert.ts | 9 ++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/x-pack/test/functional/services/uptime/overview.ts b/x-pack/test/functional/services/uptime/overview.ts index 6fe7be632f08e..3e2c29d937b5b 100644 --- a/x-pack/test/functional/services/uptime/overview.ts +++ b/x-pack/test/functional/services/uptime/overview.ts @@ -8,6 +8,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export function UptimeOverviewProvider({ getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); + const retry = getService('retry'); return { async expandMonitorDetail(id: string): Promise { @@ -24,15 +25,20 @@ export function UptimeOverviewProvider({ getService }: FtrProviderContext) { * Otherwise, open the popover, then click the nested button. */ async navigateToNestedPopover(): Promise { - if (testSubjects.exists('xpack.uptime.openAlertContextPanel')) { + if (await testSubjects.exists('xpack.uptime.openAlertContextPanel')) { return testSubjects.click('xpack.uptime.openAlertContextPanel'); } await testSubjects.click('xpack.uptime.alertsPopover.toggleButton'); return testSubjects.click('xpack.uptime.openAlertContextPanel'); }, - async displaysDefineConnector() { - return await testSubjects.existOrFail('uptimeSettingsDefineConnector'); + async clickDefineSettings() { + return retry.tryForTime(60 * 1000, async () => { + if (await testSubjects.exists('errorToastMessage', { timeout: 0 })) { + await testSubjects.click('toastCloseButton'); + } + await testSubjects.click('uptimeSettingsLink'); + }); }, }; } diff --git a/x-pack/test/functional_with_es_ssl/apps/uptime/simple_down_alert.ts b/x-pack/test/functional_with_es_ssl/apps/uptime/simple_down_alert.ts index b85013ea8438b..d4b8be7ee0145 100644 --- a/x-pack/test/functional_with_es_ssl/apps/uptime/simple_down_alert.ts +++ b/x-pack/test/functional_with_es_ssl/apps/uptime/simple_down_alert.ts @@ -25,6 +25,12 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const DEFAULT_DATE_START = 'Sep 10, 2019 @ 12:40:08.078'; const DEFAULT_DATE_END = 'Sep 11, 2019 @ 19:40:08.078'; + const hideErrorToast = async () => { + if (await testSubjects.exists('errorToastMessage', { timeout: 0 })) { + await testSubjects.click('toastCloseButton'); + } + }; + before(async () => { // delete the saved object await deleteUptimeSettingsObject(server); @@ -39,12 +45,13 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); it('displays to define default connector', async () => { + await hideErrorToast(); await testSubjects.click('uptimeDisplayDefineConnector'); await testSubjects.existOrFail('uptimeSettingsDefineConnector'); }); it('go to settings to define connector', async () => { - await testSubjects.click('uptimeSettingsLink'); + await uptimeService.overview.clickDefineSettings(); await uptimeService.common.waitUntilDataIsLoaded(); await testSubjects.existOrFail('comboBoxInput'); }); From 67e500fdae4257c3c0127821e8fb0e379b8421c9 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 8 Dec 2020 20:52:00 +0100 Subject: [PATCH 19/19] wip --- .../uptime/public/components/certificates/cert_refresh_btn.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2cfccf8e09461..d0823276f1885 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,7 @@ export const CertRefreshBtn = () => { const { refreshApp } = useContext(UptimeRefreshContext); return ( - +