diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/monitor_charts.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/monitor_charts.test.tsx.snap index 511485e70d0dc..f6846dfb1164d 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/monitor_charts.test.tsx.snap +++ b/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/monitor_charts.test.tsx.snap @@ -1,81 +1,192 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`MonitorCharts component renders the component without errors 1`] = ` - - - + - - - - - + } + dateRangeEnd="2011-12-03T10:15:30+01:00" + dateRangeStart="2011-12-03T10:15:30+01:00" + loading={false} + mean="mean" + monitorId="something" + range="range" + success="success" + /> + `; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/uptime_date_picker.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/uptime_date_picker.test.tsx.snap index 9a4cb2e04f59b..1b1711153a626 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/uptime_date_picker.test.tsx.snap +++ b/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/uptime_date_picker.test.tsx.snap @@ -111,155 +111,57 @@ exports[`UptimeDatePicker component renders properly with mock data 1`] = ` `; -exports[`UptimeDatePicker component renders properly without commonlyUsedRanges prop 1`] = ` -
-
-
-
-
- -
-
-
-
- -
-
-
-
-
- - - -
-
-`; - exports[`UptimeDatePicker component validates props with shallow render 1`] = ` - +> + + `; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/monitor_charts.test.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/monitor_charts.test.tsx index 7beb3b545b45b..81c60c8fbeaaa 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/monitor_charts.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/monitor_charts.test.tsx @@ -9,6 +9,7 @@ import DateMath from '@elastic/datemath'; import { shallowWithIntl } from 'test_utils/enzyme_helpers'; import { MonitorChartsComponent } from '../monitor_charts'; import { MonitorChart } from '../../../../common/graphql/types'; +import { renderWithRouter } from '../../../lib'; describe('MonitorCharts component', () => { let dateMathSpy: any; @@ -63,17 +64,19 @@ describe('MonitorCharts component', () => { it('renders the component without errors', () => { const component = shallowWithIntl( - + renderWithRouter( + + ) ); expect(component).toMatchSnapshot(); }); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/uptime_date_picker.test.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/uptime_date_picker.test.tsx index e3ca1a87850c8..5ce88f2bd5c22 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/uptime_date_picker.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/uptime_date_picker.test.tsx @@ -7,20 +7,16 @@ import { shallowWithIntl, renderWithIntl } from 'test_utils/enzyme_helpers'; import React from 'react'; import { UptimeDatePicker } from '../uptime_date_picker'; +import { renderWithRouter } from '../../../lib'; describe('UptimeDatePicker component', () => { it('validates props with shallow render', () => { - const component = shallowWithIntl(); + const component = shallowWithIntl(renderWithRouter()); expect(component).toMatchSnapshot(); }); it('renders properly with mock data', () => { - const component = renderWithIntl(); - expect(component).toMatchSnapshot(); - }); - - it('renders properly without commonlyUsedRanges prop', () => { - const component = renderWithIntl(); + const component = renderWithIntl(renderWithRouter()); expect(component).toMatchSnapshot(); }); }); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart.tsx index 50dca8577455d..35ee35e2926a8 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart.tsx @@ -9,7 +9,7 @@ import React, { useContext, useEffect, useRef } from 'react'; import * as d3 from 'd3'; import { i18n } from '@kbn/i18n'; import { DonutChartLegend } from './donut_chart_legend'; -import { UptimeSettingsContext } from '../../../contexts'; +import { UptimeThemeContext } from '../../../contexts'; interface DonutChartProps { down: number; @@ -23,7 +23,7 @@ export const DonutChart = ({ height, down, up, width }: DonutChartProps) => { const { colors: { danger, gray }, - } = useContext(UptimeSettingsContext); + } = useContext(UptimeThemeContext); let upCount = up; if (up === 0 && down === 0) { diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart_legend.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart_legend.tsx index ff471f7ba5407..a514013eeed98 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart_legend.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/charts/donut_chart_legend.tsx @@ -9,7 +9,7 @@ import { EuiSpacer } from '@elastic/eui'; import React, { useContext } from 'react'; import styled from 'styled-components'; import { DonutChartLegendRow } from './donut_chart_legend_row'; -import { UptimeSettingsContext } from '../../../contexts'; +import { UptimeThemeContext } from '../../../contexts'; const LegendContainer = styled.div` max-width: 260px; @@ -28,7 +28,7 @@ interface Props { export const DonutChartLegend = ({ down, up }: Props) => { const { colors: { gray, danger }, - } = useContext(UptimeSettingsContext); + } = useContext(UptimeThemeContext); return ( = ({ }: Props) => { const { colors: { danger, gray }, - } = useContext(UptimeSettingsContext); + } = useContext(UptimeThemeContext); if (!data || !data.queryResult) /** * TODO: the Fragment, EuiTitle, and EuiPanel should be extracted to a dumb component diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/__snapshots__/filter_status_button.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/__snapshots__/filter_status_button.test.tsx.snap index 28ac27054b856..2d21c4d2fe2a2 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/__snapshots__/filter_status_button.test.tsx.snap +++ b/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/__snapshots__/filter_status_button.test.tsx.snap @@ -1,16 +1,61 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`FilterStatusButton renders without errors for valid props 1`] = ` - - Up - + + `; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/filter_status_button.test.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/filter_status_button.test.tsx index 73a74747d5ca5..0c0393cb4fedf 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/filter_status_button.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/filter_group/__tests__/filter_status_button.test.tsx @@ -7,6 +7,7 @@ import React from 'react'; import { shallowWithIntl } from 'test_utils/enzyme_helpers'; import { FilterStatusButton, FilterStatusButtonProps } from '../filter_status_button'; +import { renderWithRouter } from '../../../../lib/'; describe('FilterStatusButton', () => { let props: FilterStatusButtonProps; @@ -20,7 +21,7 @@ describe('FilterStatusButton', () => { }); it('renders without errors for valid props', () => { - const wrapper = shallowWithIntl(); + const wrapper = shallowWithIntl(renderWithRouter()); expect(wrapper).toMatchSnapshot(); }); }); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/embedded_map.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/embedded_map.tsx index 9b20651fadb86..63a054c0c4889 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/embedded_map.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/embedded_map.tsx @@ -15,7 +15,7 @@ import { MAP_SAVED_OBJECT_TYPE } from '../../../../../../maps/common/constants'; import { MapEmbeddable } from './types'; import { getLayerList } from './map_config'; -import { UptimeSettingsContext } from '../../../../contexts'; +import { UptimeThemeContext } from '../../../../contexts'; export interface EmbeddedMapProps { upPoints: LocationPoint[]; @@ -46,7 +46,7 @@ const EmbeddedPanel = styled.div` `; export const EmbeddedMap = ({ upPoints, downPoints }: EmbeddedMapProps) => { - const { colors } = useContext(UptimeSettingsContext); + const { colors } = useContext(UptimeThemeContext); const [embeddable, setEmbeddable] = useState(); const embeddableRoot: React.RefObject = useRef(null); const factory = start.getEmbeddableFactory(MAP_SAVED_OBJECT_TYPE); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/location_status_tags.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/location_status_tags.tsx index e7107b5246c37..c34c0b0088b3a 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/location_status_tags.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/location_status_tags.tsx @@ -5,11 +5,11 @@ */ import React, { useContext } from 'react'; +import moment from 'moment'; import styled from 'styled-components'; import { EuiBadge, EuiText } from '@elastic/eui'; -import moment from 'moment'; import { FormattedMessage } from '@kbn/i18n/react'; -import { UptimeSettingsContext } from '../../../contexts'; +import { UptimeThemeContext } from '../../../contexts'; import { MonitorLocation } from '../../../../common/runtime_types'; const TimeStampSpan = styled.span` @@ -48,7 +48,7 @@ interface StatusTag { export const LocationStatusTags = ({ locations }: Props) => { const { colors: { gray, danger }, - } = useContext(UptimeSettingsContext); + } = useContext(UptimeThemeContext); const upLocations: StatusTag[] = []; const downLocations: StatusTag[] = []; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_list_drawer.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_list_drawer.test.tsx.snap index b6402ae852215..29f2c0b63991e 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_list_drawer.test.tsx.snap +++ b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_list_drawer.test.tsx.snap @@ -1,189 +1,197 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`MonitorListDrawer component renders a MonitorListDrawer when there are many checks 1`] = ` - - - - - - https://expired.badssl.com - - - - - - + - - - - - - + `; exports[`MonitorListDrawer component renders a MonitorListDrawer when there is only one check 1`] = ` - - - - - - https://expired.badssl.com - - - - - - - - - - - + - + `; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/monitor_list_drawer.test.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/monitor_list_drawer.test.tsx index 5c606f2356dfc..9bd407902cb55 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/monitor_list_drawer.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/__tests__/monitor_list_drawer.test.tsx @@ -9,6 +9,7 @@ import { shallowWithIntl } from 'test_utils/enzyme_helpers'; import React from 'react'; import { MonitorListDrawerComponent } from '../monitor_list_drawer'; import { MonitorDetails } from '../../../../../../common/runtime_types'; +import { renderWithRouter } from '../../../../../lib'; describe('MonitorListDrawer component', () => { let summary: MonitorSummary; @@ -52,11 +53,13 @@ describe('MonitorListDrawer component', () => { it('renders nothing when no summary data is present', () => { const component = shallowWithIntl( - + renderWithRouter( + + ) ); expect(component).toEqual({}); }); @@ -64,22 +67,26 @@ describe('MonitorListDrawer component', () => { it('renders nothing when no check data is present', () => { delete summary.state.checks; const component = shallowWithIntl( - + renderWithRouter( + + ) ); expect(component).toEqual({}); }); it('renders a MonitorListDrawer when there is only one check', () => { const component = shallowWithIntl( - + renderWithRouter( + + ) ); expect(component).toMatchSnapshot(); }); @@ -110,11 +117,13 @@ describe('MonitorListDrawer component', () => { ]; summary.state.checks = checks; const component = shallowWithIntl( - + renderWithRouter( + + ) ); expect(component).toMatchSnapshot(); }); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/monitor_status_row.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/monitor_status_row.tsx index 23f11b88517fc..e724986c2505e 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/monitor_status_row.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_list/monitor_list_drawer/monitor_status_row.tsx @@ -7,7 +7,7 @@ import React, { useContext } from 'react'; import { EuiHealth, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { UptimeSettingsContext } from '../../../../contexts'; +import { UptimeThemeContext } from '../../../../contexts'; import { UP } from './monitor_status_list'; import { UNNAMED_LOCATION } from '../../../../../common/constants'; @@ -25,7 +25,7 @@ interface MonitorStatusRowProps { export const MonitorStatusRow = ({ locationNames, status }: MonitorStatusRowProps) => { const { colors: { success, danger }, - } = useContext(UptimeSettingsContext); + } = useContext(UptimeThemeContext); const color = status === UP ? success : danger; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/uptime_date_picker.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/uptime_date_picker.tsx index c282ac9b9e155..2118faa775130 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/uptime_date_picker.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/uptime_date_picker.tsx @@ -8,7 +8,7 @@ import { EuiSuperDatePicker } from '@elastic/eui'; import React, { useContext } from 'react'; import { useUrlParams } from '../../hooks'; import { CLIENT_DEFAULTS } from '../../../common/constants'; -import { UptimeSettingsContext } from '../../contexts'; +import { UptimeRefreshContext, UptimeSettingsContext } from '../../contexts'; // TODO: when EUI exports types for this, this should be replaced interface SuperDateRangePickerRangeChangedEvent { @@ -27,14 +27,11 @@ export interface CommonlyUsedRange { display: string; } -interface UptimeDatePickerProps { - refreshApp: () => void; -} - -export const UptimeDatePicker = ({ refreshApp }: UptimeDatePickerProps) => { +export const UptimeDatePicker = () => { const [getUrlParams, updateUrl] = useUrlParams(); const { autorefreshInterval, autorefreshIsPaused, dateRangeStart, dateRangeEnd } = getUrlParams(); const { commonlyUsedRanges } = useContext(UptimeSettingsContext); + const { refreshApp } = useContext(UptimeRefreshContext); const euiCommonlyUsedRanges = commonlyUsedRanges ? commonlyUsedRanges.map( diff --git a/x-pack/legacy/plugins/uptime/public/contexts/index.ts b/x-pack/legacy/plugins/uptime/public/contexts/index.ts index 32eab9d1da291..2b27fcfe907ab 100644 --- a/x-pack/legacy/plugins/uptime/public/contexts/index.ts +++ b/x-pack/legacy/plugins/uptime/public/contexts/index.ts @@ -4,5 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -export { UptimeRefreshContext } from './uptime_refresh_context'; -export { UMSettingsContextValues, UptimeSettingsContext } from './uptime_settings_context'; +export { UptimeRefreshContext, UptimeRefreshContextProvider } from './uptime_refresh_context'; +export { + UptimeSettingsContextValues, + UptimeSettingsContext, + UptimeSettingsContextProvider, +} from './uptime_settings_context'; +export { UptimeThemeContextProvider, UptimeThemeContext } from './uptime_theme_context'; diff --git a/x-pack/legacy/plugins/uptime/public/contexts/uptime_refresh_context.ts b/x-pack/legacy/plugins/uptime/public/contexts/uptime_refresh_context.ts deleted file mode 100644 index e15f3fcd9e0fb..0000000000000 --- a/x-pack/legacy/plugins/uptime/public/contexts/uptime_refresh_context.ts +++ /dev/null @@ -1,27 +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 { createContext } from 'react'; -import { History } from 'history'; - -interface Location { - pathname: string; - search: string; -} - -interface UMRefreshContext { - lastRefresh: number; - history: History | undefined; - location: Location | undefined; -} - -const defaultContext: UMRefreshContext = { - lastRefresh: 0, - history: undefined, - location: undefined, -}; - -export const UptimeRefreshContext = createContext(defaultContext); diff --git a/x-pack/legacy/plugins/uptime/public/contexts/uptime_refresh_context.tsx b/x-pack/legacy/plugins/uptime/public/contexts/uptime_refresh_context.tsx new file mode 100644 index 0000000000000..4516289bd51d6 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/contexts/uptime_refresh_context.tsx @@ -0,0 +1,39 @@ +/* + * 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, { createContext, useMemo, useState } from 'react'; +import { store } from '../state'; +import { triggerAppRefresh } from '../state/actions'; + +interface UptimeRefreshContext { + lastRefresh: number; + refreshApp: () => void; +} + +const defaultContext: UptimeRefreshContext = { + lastRefresh: 0, + refreshApp: () => { + throw new Error('App refresh was not initialized, set it when you invoke the context'); + }, +}; + +export const UptimeRefreshContext = createContext(defaultContext); + +export const UptimeRefreshContextProvider: React.FC = ({ children }) => { + const [lastRefresh, setLastRefresh] = useState(Date.now()); + + const refreshApp = () => { + const refreshTime = Date.now(); + setLastRefresh(refreshTime); + store.dispatch(triggerAppRefresh(refreshTime)); + }; + + const value = useMemo(() => { + return { lastRefresh, refreshApp }; + }, [lastRefresh]); + + return ; +}; diff --git a/x-pack/legacy/plugins/uptime/public/contexts/uptime_settings_context.ts b/x-pack/legacy/plugins/uptime/public/contexts/uptime_settings_context.ts deleted file mode 100644 index c656391678aa2..0000000000000 --- a/x-pack/legacy/plugins/uptime/public/contexts/uptime_settings_context.ts +++ /dev/null @@ -1,70 +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 DateMath from '@elastic/datemath'; -import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; -import { createContext } from 'react'; -import { UptimeAppColors } from '../uptime_app'; -import { CONTEXT_DEFAULTS } from '../../common/constants'; -import { CommonlyUsedRange } from '../components/functional/uptime_date_picker'; - -export interface UMSettingsContextValues { - absoluteStartDate: number; - absoluteEndDate: number; - autorefreshIsPaused: boolean; - autorefreshInterval: number; - basePath: string; - colors: UptimeAppColors; - dateRangeStart: string; - dateRangeEnd: string; - isApmAvailable: boolean; - isInfraAvailable: boolean; - isLogsAvailable: boolean; - refreshApp: () => void; - commonlyUsedRanges?: CommonlyUsedRange[]; -} - -const { - AUTOREFRESH_IS_PAUSED, - AUTOREFRESH_INTERVAL, - BASE_PATH, - DATE_RANGE_START, - DATE_RANGE_END, -} = CONTEXT_DEFAULTS; -const parsedStart = DateMath.parse(DATE_RANGE_START); -const parsedEnd = DateMath.parse(DATE_RANGE_END); -const DEFAULT_ABSOLUTE_START_DATE = parsedStart ? parsedStart.valueOf() : 0; -const DEFAULT_ABSOLUTE_END_DATE = parsedEnd ? parsedEnd.valueOf() : 1; - -/** - * These are default values for the context. These defaults are typically - * overwritten by the Uptime App upon its invocation. - */ -const defaultContext: UMSettingsContextValues = { - absoluteStartDate: DEFAULT_ABSOLUTE_START_DATE, - absoluteEndDate: DEFAULT_ABSOLUTE_END_DATE, - autorefreshIsPaused: AUTOREFRESH_IS_PAUSED, - autorefreshInterval: AUTOREFRESH_INTERVAL, - basePath: BASE_PATH, - colors: { - danger: euiLightVars.euiColorDanger, - mean: euiLightVars.euiColorPrimary, - range: euiLightVars.euiFocusBackgroundColor, - success: euiLightVars.euiColorSuccess, - warning: euiLightVars.euiColorWarning, - gray: euiLightVars.euiColorLightShade, - }, - dateRangeStart: DATE_RANGE_START, - dateRangeEnd: DATE_RANGE_END, - isApmAvailable: true, - isInfraAvailable: true, - isLogsAvailable: true, - refreshApp: () => { - throw new Error('App refresh was not initialized, set it when you invoke the context'); - }, -}; - -export const UptimeSettingsContext = createContext(defaultContext); diff --git a/x-pack/legacy/plugins/uptime/public/contexts/uptime_settings_context.tsx b/x-pack/legacy/plugins/uptime/public/contexts/uptime_settings_context.tsx new file mode 100644 index 0000000000000..b529d5346e88e --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/contexts/uptime_settings_context.tsx @@ -0,0 +1,56 @@ +/* + * 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, { createContext, useMemo } from 'react'; +import { useParams } from 'react-router-dom'; +import { UptimeAppProps } from '../uptime_app'; +import { CONTEXT_DEFAULTS } from '../../common/constants'; +import { CommonlyUsedRange } from '../components/functional/uptime_date_picker'; + +export interface UptimeSettingsContextValues { + basePath: string; + dateRangeStart: string; + dateRangeEnd: string; + isApmAvailable: boolean; + isInfraAvailable: boolean; + isLogsAvailable: boolean; + commonlyUsedRanges?: CommonlyUsedRange[]; +} + +const { BASE_PATH, DATE_RANGE_START, DATE_RANGE_END } = CONTEXT_DEFAULTS; + +/** + * These are default values for the context. These defaults are typically + * overwritten by the Uptime App upon its invocation. + */ +const defaultContext: UptimeSettingsContextValues = { + basePath: BASE_PATH, + dateRangeStart: DATE_RANGE_START, + dateRangeEnd: DATE_RANGE_END, + isApmAvailable: true, + isInfraAvailable: true, + isLogsAvailable: true, +}; +export const UptimeSettingsContext = createContext(defaultContext); + +export const UptimeSettingsContextProvider: React.FC = ({ children, ...props }) => { + const { basePath, isApmAvailable, isInfraAvailable, isLogsAvailable } = props; + + const { dateRangeStart, dateRangeEnd } = useParams(); + + const value = useMemo(() => { + return { + basePath, + isApmAvailable, + isInfraAvailable, + isLogsAvailable, + dateRangeStart: dateRangeStart ?? DATE_RANGE_START, + dateRangeEnd: dateRangeEnd ?? DATE_RANGE_END, + }; + }, [basePath, isApmAvailable, isInfraAvailable, isLogsAvailable, dateRangeStart, dateRangeEnd]); + + return ; +}; diff --git a/x-pack/legacy/plugins/uptime/public/contexts/uptime_theme_context.tsx b/x-pack/legacy/plugins/uptime/public/contexts/uptime_theme_context.tsx new file mode 100644 index 0000000000000..7a9450ea2774e --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/contexts/uptime_theme_context.tsx @@ -0,0 +1,65 @@ +/* + * 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 euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; +import React, { createContext, useMemo } from 'react'; +import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json'; +import { UptimeAppColors } from '../uptime_app'; + +export interface UptimeThemeContextValues { + colors: UptimeAppColors; +} + +/** + * These are default values for the context. These defaults are typically + * overwritten by the Uptime App upon its invocation. + */ +const defaultContext: UptimeThemeContextValues = { + colors: { + danger: euiLightVars.euiColorDanger, + mean: euiLightVars.euiColorPrimary, + range: euiLightVars.euiFocusBackgroundColor, + success: euiLightVars.euiColorSuccess, + warning: euiLightVars.euiColorWarning, + gray: euiLightVars.euiColorLightShade, + }, +}; + +export const UptimeThemeContext = createContext(defaultContext); + +interface ThemeContextProps { + darkMode: boolean; +} + +export const UptimeThemeContextProvider: React.FC = ({ darkMode, children }) => { + let colors: UptimeAppColors; + if (darkMode) { + colors = { + danger: euiDarkVars.euiColorDanger, + mean: euiDarkVars.euiColorPrimary, + gray: euiDarkVars.euiColorLightShade, + range: euiDarkVars.euiFocusBackgroundColor, + success: euiDarkVars.euiColorSuccess, + warning: euiDarkVars.euiColorWarning, + }; + } else { + colors = { + danger: euiLightVars.euiColorDanger, + mean: euiLightVars.euiColorPrimary, + gray: euiLightVars.euiColorLightShade, + range: euiLightVars.euiFocusBackgroundColor, + success: euiLightVars.euiColorSuccess, + warning: euiLightVars.euiColorWarning, + }; + } + const value = useMemo(() => { + return { + colors, + }; + }, [colors]); + + return ; +}; diff --git a/x-pack/legacy/plugins/uptime/public/hooks/__tests__/__snapshots__/use_url_params.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/hooks/__tests__/__snapshots__/use_url_params.test.tsx.snap index 6abb14d015d67..a2c52f9405289 100644 --- a/x-pack/legacy/plugins/uptime/public/hooks/__tests__/__snapshots__/use_url_params.test.tsx.snap +++ b/x-pack/legacy/plugins/uptime/public/hooks/__tests__/__snapshots__/use_url_params.test.tsx.snap @@ -1,50 +1,324 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`useUrlParams deletes keys that do not have truthy values 1`] = ` - -
- {"absoluteDateRangeStart":20,"absoluteDateRangeEnd":20,"autorefreshInterval":60000,"autorefreshIsPaused":false,"dateRangeStart":"now-12","dateRangeEnd":"now","filters":"","search":"","selectedPingStatus":"","statusFilter":"","pagination":"foo"} -
- - -
+
+ {"absoluteDateRangeStart":20,"absoluteDateRangeEnd":20,"autorefreshInterval":60000,"autorefreshIsPaused":false,"dateRangeStart":"now-12","dateRangeEnd":"now","filters":"","search":"","selectedPingStatus":"","statusFilter":"","pagination":"foo"} +
+ + + + `; exports[`useUrlParams gets the expected values using the context 1`] = ` - -
- {"absoluteDateRangeStart":20,"absoluteDateRangeEnd":20,"autorefreshInterval":60000,"autorefreshIsPaused":false,"dateRangeStart":"now-19d","dateRangeEnd":"now-1m","filters":"","search":"","selectedPingStatus":"","statusFilter":""} -
- - -
+
+ {"absoluteDateRangeStart":20,"absoluteDateRangeEnd":20,"autorefreshInterval":60000,"autorefreshIsPaused":false,"dateRangeStart":"now-15m","dateRangeEnd":"now","filters":"","search":"","selectedPingStatus":"","statusFilter":""} +
+ + + + `; diff --git a/x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx b/x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx index 66cb5d29d1742..c9ba7b9bc0098 100644 --- a/x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx @@ -8,16 +8,15 @@ import { mountWithIntl } from 'test_utils/enzyme_helpers'; import DateMath from '@elastic/datemath'; import React, { useState, Fragment } from 'react'; import { useUrlParams, UptimeUrlParamsHook } from '../use_url_params'; -import { RouteComponentProps } from 'react-router-dom'; import { UptimeRefreshContext } from '../../contexts'; +import { renderWithRouter } from '../../lib'; +import { createMemoryHistory } from 'history'; interface MockUrlParamsComponentProps { hook: UptimeUrlParamsHook; updateParams?: { [key: string]: any }; } -let mockRouter: RouteComponentProps; - const UseUrlParamsTestComponent = ({ hook, updateParams }: MockUrlParamsComponentProps) => { const [params, setParams] = useState({}); const [getUrlParams, updateUrlParams] = hook(); @@ -42,61 +41,45 @@ const UseUrlParamsTestComponent = ({ hook, updateParams }: MockUrlParamsComponen describe('useUrlParams', () => { let dateMathSpy: any; const MOCK_DATE_VALUE = 20; + beforeEach(() => { - mockRouter = { - // @ts-ignore other properties aren't needed for this test - history: { - push: jest.fn(), - }, - location: { - pathname: '', - search: '?g=""', - state: {}, - hash: '', - }, - match: { - params: '', - isExact: true, - path: '/', - url: 'http://elastic.co', - }, - }; dateMathSpy = jest.spyOn(DateMath, 'parse'); dateMathSpy.mockReturnValue(MOCK_DATE_VALUE); }); it('accepts router props, updates URL params, and returns the current params', () => { + const history = createMemoryHistory(); + jest.spyOn(history, 'push'); + const component = mountWithIntl( - - - + renderWithRouter( + + + , + history + ) ); const setUrlParamsButton = component.find('#setUrlParams'); setUrlParamsButton.simulate('click'); - - expect(mockRouter.history.push).toHaveBeenCalledWith({ - pathname: '', - search: 'g=%22%22&dateRangeStart=now-12d&dateRangeEnd=now', + expect(history.push).toHaveBeenCalledWith({ + pathname: '/', + search: 'dateRangeStart=now-12d&dateRangeEnd=now', }); }); it('gets the expected values using the context', () => { const component = mountWithIntl( - - - + renderWithRouter( + + + + ) ); const getUrlParamsButton = component.find('#getUrlParams'); @@ -106,17 +89,24 @@ describe('useUrlParams', () => { }); it('deletes keys that do not have truthy values', () => { - mockRouter.location.search = 'g=%22%22&dateRangeStart=now-12&dateRangeEnd=now&pagination=foo'; + const history = createMemoryHistory({ + initialEntries: ['/?g=%22%22&dateRangeStart=now-12&dateRangeEnd=now&pagination=foo'], + }); + history.location.key = 'test'; + + jest.spyOn(history, 'push'); const component = mountWithIntl( - - - + renderWithRouter( + + + , + history + ) ); const getUrlParamsButton = component.find('#getUrlParams'); @@ -126,11 +116,11 @@ describe('useUrlParams', () => { expect(component).toMatchSnapshot(); - const setUrlParmsButton = component.find('#setUrlParams'); - setUrlParmsButton.simulate('click'); + const setUrlParamsButton = component.find('#setUrlParams'); + setUrlParamsButton.simulate('click'); - expect(mockRouter.history.push).toHaveBeenCalledWith({ - pathname: '', + expect(history.push).toHaveBeenCalledWith({ + pathname: '/', search: 'g=%22%22&dateRangeStart=now-12&dateRangeEnd=now', }); }); diff --git a/x-pack/legacy/plugins/uptime/public/hooks/use_url_params.ts b/x-pack/legacy/plugins/uptime/public/hooks/use_url_params.ts index 31343e6a1883c..e509e14223006 100644 --- a/x-pack/legacy/plugins/uptime/public/hooks/use_url_params.ts +++ b/x-pack/legacy/plugins/uptime/public/hooks/use_url_params.ts @@ -5,8 +5,7 @@ */ import qs from 'querystring'; -import { useContext } from 'react'; -import { UptimeRefreshContext } from '../contexts'; +import { useLocation, useHistory } from 'react-router-dom'; import { UptimeUrlParams, getSupportedUrlParams } from '../lib/helper'; type GetUrlParams = () => UptimeUrlParams; @@ -15,12 +14,13 @@ type UpdateUrlParams = (updatedParams: { [key: string]: string | number | boolea export type UptimeUrlParamsHook = () => [GetUrlParams, UpdateUrlParams]; export const useUrlParams: UptimeUrlParamsHook = () => { - const refreshContext = useContext(UptimeRefreshContext); + const location = useLocation(); + const history = useHistory(); const getUrlParams: GetUrlParams = () => { let search: string | undefined; - if (refreshContext.location) { - search = refreshContext.location.search; + if (location) { + search = location.search; } const params = search ? { ...qs.parse(search[0] === '?' ? search.slice(1) : search) } : {}; @@ -28,11 +28,8 @@ export const useUrlParams: UptimeUrlParamsHook = () => { }; const updateUrlParams: UpdateUrlParams = updatedParams => { - if (!refreshContext.history || !refreshContext.location) return; - const { - history, - location: { pathname, search }, - } = refreshContext; + if (!history || !location) return; + const { pathname, search } = location; const currentParams: any = qs.parse(search[0] === '?' ? search.slice(1) : search); const mergedParams = { ...currentParams, diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/render_with_router.tsx b/x-pack/legacy/plugins/uptime/public/lib/helper/render_with_router.tsx new file mode 100644 index 0000000000000..5cd9ec23a3587 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/lib/helper/render_with_router.tsx @@ -0,0 +1,21 @@ +/* + * 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 { Router } from 'react-router-dom'; +import { MemoryHistory } from 'history/createMemoryHistory'; +import { createMemoryHistory } from 'history'; + +export const renderWithRouter = (Component: any, customHistory?: MemoryHistory) => { + if (customHistory) { + return {Component}; + } + const history = createMemoryHistory(); + history.location.key = 'TestKeyForTesting'; + + return {Component}; +}; diff --git a/x-pack/legacy/plugins/uptime/public/lib/index.ts b/x-pack/legacy/plugins/uptime/public/lib/index.ts new file mode 100644 index 0000000000000..9a78c6df5d63d --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/lib/index.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export { renderWithRouter } from './helper/render_with_router'; diff --git a/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx b/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx index 1b4ad8d82ead1..408d2584911e0 100644 --- a/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx +++ b/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx @@ -9,7 +9,7 @@ import React, { Fragment, useContext, useState } from 'react'; import { useParams } from 'react-router-dom'; import { MonitorCharts, PingList } from '../components/functional'; import { UMUpdateBreadcrumbs } from '../lib/lib'; -import { UptimeSettingsContext } from '../contexts'; +import { UptimeRefreshContext, UptimeThemeContext } from '../contexts'; import { useUptimeTelemetry, useUrlParams, UptimePage } from '../hooks'; import { useTrackPageview } from '../../../infra/public'; import { MonitorStatusDetails } from '../components/functional/monitor_status_details'; @@ -25,7 +25,8 @@ export const MonitorPage = ({ setBreadcrumbs }: MonitorPageProps) => { monitorId = atob(monitorId || ''); const [pingListPageCount, setPingListPageCount] = useState(10); - const { colors, refreshApp } = useContext(UptimeSettingsContext); + const { colors } = useContext(UptimeThemeContext); + const { refreshApp } = useContext(UptimeRefreshContext); const [getUrlParams, updateUrlParams] = useUrlParams(); const { absoluteDateRangeStart, absoluteDateRangeEnd, ...params } = getUrlParams(); const { dateRangeStart, dateRangeEnd, selectedPingStatus } = params; diff --git a/x-pack/legacy/plugins/uptime/public/pages/overview.tsx b/x-pack/legacy/plugins/uptime/public/pages/overview.tsx index e7ef7f53afde4..fbfbfc06e3c52 100644 --- a/x-pack/legacy/plugins/uptime/public/pages/overview.tsx +++ b/x-pack/legacy/plugins/uptime/public/pages/overview.tsx @@ -16,7 +16,6 @@ import { StatusPanel, } from '../components/functional'; import { UMUpdateBreadcrumbs } from '../lib/lib'; -import { UptimeSettingsContext } from '../contexts'; import { useIndexPattern, useUrlParams, useUptimeTelemetry, UptimePage } from '../hooks'; import { stringifyUrlParams } from '../lib/helper/stringify_url_params'; import { useTrackPageview } from '../../../infra/public'; @@ -25,6 +24,7 @@ import { AutocompleteProviderRegister, esKuery } from '../../../../../../src/plu import { store } from '../state'; import { setEsKueryString } from '../state/actions'; import { PageHeader } from './page_header'; +import { UptimeThemeContext } from '../contexts/uptime_theme_context'; interface OverviewPageProps { autocomplete: Pick; @@ -48,7 +48,7 @@ const EuiFlexItemStyled = styled(EuiFlexItem)` `; export const OverviewPage = ({ autocomplete, setBreadcrumbs }: Props) => { - const { colors } = useContext(UptimeSettingsContext); + const { colors } = useContext(UptimeThemeContext); const [getUrlParams, updateUrl] = useUrlParams(); const { absoluteDateRangeStart, absoluteDateRangeEnd, ...params } = getUrlParams(); const { 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 250dacb8914e7..d341a22bc583b 100644 --- a/x-pack/legacy/plugins/uptime/public/pages/page_header.tsx +++ b/x-pack/legacy/plugins/uptime/public/pages/page_header.tsx @@ -5,7 +5,7 @@ */ import { EuiTitle, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; -import React, { useEffect, useState, useContext } from 'react'; +import React, { useEffect, useState } from 'react'; import { connect } from 'react-redux'; import { useRouteMatch, useParams } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; @@ -14,7 +14,6 @@ import { AppState } from '../state'; import { selectSelectedMonitor } from '../state/selectors'; import { getMonitorPageBreadcrumb, getOverviewPageBreadcrumbs } from '../breadcrumbs'; import { stringifyUrlParams } from '../lib/helper/stringify_url_params'; -import { UptimeSettingsContext } from '../contexts'; import { getTitle } from '../lib/helper/get_title'; import { UMUpdateBreadcrumbs } from '../lib/lib'; import { MONITOR_ROUTE } from '../routes'; @@ -28,7 +27,6 @@ export const PageHeaderComponent = ({ monitorStatus, setBreadcrumbs }: PageHeade const monitorPage = useRouteMatch({ path: MONITOR_ROUTE, }); - const { refreshApp } = useContext(UptimeSettingsContext); const { absoluteDateRangeStart, absoluteDateRangeEnd, ...params } = useParams(); @@ -61,6 +59,10 @@ export const PageHeaderComponent = ({ monitorStatus, setBreadcrumbs }: PageHeade } }, [headerText, setBreadcrumbs, params, monitorPage]); + useEffect(() => { + document.title = getTitle(); + }, []); + return ( <> @@ -70,7 +72,7 @@ export const PageHeaderComponent = ({ monitorStatus, setBreadcrumbs }: PageHeade - + diff --git a/x-pack/legacy/plugins/uptime/public/uptime_app.tsx b/x-pack/legacy/plugins/uptime/public/uptime_app.tsx index 25ff0e7177016..513faa3eb4bc2 100644 --- a/x-pack/legacy/plugins/uptime/public/uptime_app.tsx +++ b/x-pack/legacy/plugins/uptime/public/uptime_app.tsx @@ -4,25 +4,24 @@ * you may not use this file except in compliance with the Elastic License. */ -import DateMath from '@elastic/datemath'; -import { EuiPage } from '@elastic/eui'; -import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json'; -import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; +import { EuiPage, EuiErrorBoundary } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect } from 'react'; import { ApolloProvider } from 'react-apollo'; import { Provider as ReduxProvider } from 'react-redux'; -import { BrowserRouter as Router, Route, RouteComponentProps } from 'react-router-dom'; +import { BrowserRouter as Router } from 'react-router-dom'; import { I18nStart, ChromeBreadcrumb, LegacyCoreStart } from 'src/core/public'; import { PluginsStart } from 'ui/new_platform/new_platform'; import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public'; import { UMGraphQLClient, UMUpdateBreadcrumbs, UMUpdateBadge } from './lib/lib'; -import { UptimeRefreshContext, UptimeSettingsContext, UMSettingsContextValues } from './contexts'; +import { + UptimeRefreshContextProvider, + UptimeSettingsContextProvider, + UptimeThemeContextProvider, +} from './contexts'; import { CommonlyUsedRange } from './components/functional/uptime_date_picker'; -import { useUrlParams } from './hooks'; -import { getTitle } from './lib/helper/get_title'; import { store } from './state'; -import { setBasePath, triggerAppRefresh } from './state/actions'; +import { setBasePath } from './state/actions'; import { PageRouter } from './routes'; export interface UptimeAppColors { @@ -60,11 +59,7 @@ const Application = (props: UptimeAppProps) => { client, core, darkMode, - commonlyUsedRanges, i18n: i18nCore, - isApmAvailable, - isInfraAvailable, - isLogsAvailable, plugins, renderGlobalHelpControls, routerBasename, @@ -72,28 +67,6 @@ const Application = (props: UptimeAppProps) => { setBadge, } = props; - let colors: UptimeAppColors; - if (darkMode) { - colors = { - danger: euiDarkVars.euiColorDanger, - mean: euiDarkVars.euiColorPrimary, - gray: euiDarkVars.euiColorLightShade, - range: euiDarkVars.euiFocusBackgroundColor, - success: euiDarkVars.euiColorSuccess, - warning: euiDarkVars.euiColorWarning, - }; - } else { - colors = { - danger: euiLightVars.euiColorDanger, - mean: euiLightVars.euiColorPrimary, - gray: euiLightVars.euiColorLightShade, - range: euiLightVars.euiFocusBackgroundColor, - success: euiLightVars.euiColorSuccess, - warning: euiLightVars.euiColorWarning, - }; - } - const [lastRefresh, setLastRefresh] = useState(Date.now()); - useEffect(() => { renderGlobalHelpControls(); setBadge( @@ -111,77 +84,36 @@ const Application = (props: UptimeAppProps) => { ); }, [canSave, renderGlobalHelpControls, setBadge]); - useEffect(() => { - document.title = getTitle(); - }, []); - - const refreshApp = () => { - const refreshTime = Date.now(); - setLastRefresh(refreshTime); - store.dispatch(triggerAppRefresh(refreshTime)); - }; - - const [getUrlParams] = useUrlParams(); - const initializeSettingsContextValues = (): UMSettingsContextValues => { - const { - autorefreshInterval, - autorefreshIsPaused, - dateRangeStart, - dateRangeEnd, - } = getUrlParams(); - const absoluteStartDate = DateMath.parse(dateRangeStart); - const absoluteEndDate = DateMath.parse(dateRangeEnd); - return { - // TODO: extract these values to dedicated (and more sensible) constants - absoluteStartDate: absoluteStartDate ? absoluteStartDate.valueOf() : 0, - absoluteEndDate: absoluteEndDate ? absoluteEndDate.valueOf() : 1, - autorefreshInterval, - autorefreshIsPaused, - basePath, - colors, - dateRangeStart, - dateRangeEnd, - isApmAvailable, - isInfraAvailable, - isLogsAvailable, - refreshApp, - commonlyUsedRanges, - }; - }; - store.dispatch(setBasePath(basePath)); return ( - - - - - { - return ( - - - - -
- -
-
-
-
-
- ); - }} - /> -
-
-
-
+ + + + + + + + + + +
+ +
+
+
+
+
+
+
+
+
+
+
); };