+
{
setAlertFlyoutVisible(false);
@@ -63,7 +66,7 @@ export const SettingsMessageExpressionPopover: React.FC
settings page
-
+
),
}}
/>
diff --git a/x-pack/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx b/x-pack/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx
index 5c0ee632a2bda..03c8e919ebbf1 100644
--- a/x-pack/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx
+++ b/x-pack/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx
@@ -36,13 +36,19 @@ function convertKueryToEsQuery(kuery: string, indexPattern: IIndexPattern) {
interface Props {
'aria-label': string;
autocomplete: DataPublicPluginSetup['autocomplete'];
+ defaultKuery?: string;
'data-test-subj': string;
+ shouldUpdateUrl?: boolean;
+ updateDefaultKuery?: (value: string) => void;
}
export function KueryBar({
'aria-label': ariaLabel,
autocomplete: autocompleteService,
+ defaultKuery,
'data-test-subj': dataTestSubj,
+ shouldUpdateUrl,
+ updateDefaultKuery,
}: Props) {
const { loading, index_pattern: indexPattern } = useIndexPattern();
const { updateSearchText } = useSearchText();
@@ -68,8 +74,6 @@ export function KueryBar({
return;
}
- updateSearchText(inputValue);
-
setIsLoadingSuggestions(true);
setState({ ...state, suggestions: [] });
@@ -112,7 +116,13 @@ export function KueryBar({
return;
}
- updateUrlParams({ search: inputValue.trim() });
+ if (shouldUpdateUrl !== false) {
+ updateUrlParams({ search: inputValue.trim() });
+ }
+ updateSearchText(inputValue);
+ if (updateDefaultKuery) {
+ updateDefaultKuery(inputValue);
+ }
} catch (e) {
console.log('Invalid kuery syntax'); // eslint-disable-line no-console
}
@@ -125,7 +135,7 @@ export function KueryBar({
data-test-subj={dataTestSubj}
disabled={indexPatternMissing}
isLoading={isLoadingSuggestions || loading}
- initialValue={kuery}
+ initialValue={defaultKuery || kuery}
onChange={onChange}
onSubmit={onSubmit}
suggestions={state.suggestions}
diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/filter_status_button.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/filter_status_button.test.tsx
index 58c305f0d15a0..612ede2c556e7 100644
--- a/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/filter_status_button.test.tsx
+++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/filter_status_button.test.tsx
@@ -6,7 +6,7 @@
import React from 'react';
import { FilterStatusButton, FilterStatusButtonProps } from '../filter_status_button';
-import { renderWithRouter, shallowWithRouter } from '../../../../lib';
+import { renderWithRouter, shallowWithRouter, MountWithReduxProvider } from '../../../../lib';
describe('FilterStatusButton', () => {
let props: FilterStatusButtonProps;
@@ -26,7 +26,11 @@ describe('FilterStatusButton', () => {
});
it('renders without errors for valid props', () => {
- const wrapper = renderWithRouter();
+ const wrapper = renderWithRouter(
+
+
+
+ );
expect(wrapper).toMatchSnapshot();
});
});
diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/status_filter.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/status_filter.test.tsx
index a1288513eb785..d09bbad5cb9e0 100644
--- a/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/status_filter.test.tsx
+++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/status_filter.test.tsx
@@ -5,7 +5,12 @@
*/
import React from 'react';
-import { mountWithRouter, renderWithRouter, shallowWithRouter } from '../../../../lib';
+import {
+ mountWithRouter,
+ renderWithRouter,
+ shallowWithRouter,
+ MountWithReduxProvider,
+} from '../../../../lib';
import { createMemoryHistory } from 'history';
import { StatusFilter } from '../status_filter';
import { FilterStatusButton } from '../filter_status_button';
@@ -18,7 +23,12 @@ describe('StatusFilterComponent', () => {
initialEntries: [`/?g=%22%22&statusFilter=${status}`],
});
- const wrapper = mountWithRouter(, history);
+ const wrapper = mountWithRouter(
+
+
+ ,
+ history
+ );
const filterBtns = wrapper.find(FilterStatusButton);
const allBtn = filterBtns.at(0);
@@ -34,7 +44,11 @@ describe('StatusFilterComponent', () => {
});
it('renders without errors for valid props', () => {
- const wrapper = renderWithRouter();
+ const wrapper = renderWithRouter(
+
+
+
+ );
expect(wrapper).toMatchSnapshot();
});
diff --git a/x-pack/plugins/uptime/public/hooks/__tests__/__snapshots__/use_url_params.test.tsx.snap b/x-pack/plugins/uptime/public/hooks/__tests__/__snapshots__/use_url_params.test.tsx.snap
index 827c9257893ad..5d2565b7210da 100644
--- a/x-pack/plugins/uptime/public/hooks/__tests__/__snapshots__/use_url_params.test.tsx.snap
+++ b/x-pack/plugins/uptime/public/hooks/__tests__/__snapshots__/use_url_params.test.tsx.snap
@@ -137,30 +137,95 @@ 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"}
+
+
+
+
+
+
`;
@@ -301,24 +366,89 @@ exports[`useUrlParams gets the expected values using the context 1`] = `
}
}
>
-
-
- {"absoluteDateRangeStart":20,"absoluteDateRangeEnd":20,"autorefreshInterval":60000,"autorefreshIsPaused":false,"dateRangeStart":"now-15m","dateRangeEnd":"now","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/plugins/uptime/public/hooks/__tests__/use_breadcrumbs.test.tsx b/x-pack/plugins/uptime/public/hooks/__tests__/use_breadcrumbs.test.tsx
index 306919015fcb1..d688660f564ca 100644
--- a/x-pack/plugins/uptime/public/hooks/__tests__/use_breadcrumbs.test.tsx
+++ b/x-pack/plugins/uptime/public/hooks/__tests__/use_breadcrumbs.test.tsx
@@ -10,7 +10,7 @@ import { Route } from 'react-router-dom';
import { mountWithRouter } from '../../lib';
import { OVERVIEW_ROUTE } from '../../../common/constants';
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
-import { UptimeUrlParams, getSupportedUrlParams } from '../../lib/helper';
+import { UptimeUrlParams, getSupportedUrlParams, MountWithReduxProvider } from '../../lib/helper';
import { makeBaseBreadcrumb, useBreadcrumbs } from '../use_breadcrumbs';
describe('useBreadcrumbs', () => {
@@ -34,11 +34,13 @@ describe('useBreadcrumbs', () => {
};
mountWithRouter(
-
-
-
-
-
+
+
+
+
+
+
+
);
const urlParams: UptimeUrlParams = getSupportedUrlParams({});
diff --git a/x-pack/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx b/x-pack/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx
index deb1f163c1326..af5c113a02834 100644
--- a/x-pack/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx
+++ b/x-pack/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx
@@ -8,7 +8,7 @@ import DateMath from '@elastic/datemath';
import React, { useState, Fragment } from 'react';
import { useUrlParams, UptimeUrlParamsHook } from '../use_url_params';
import { UptimeRefreshContext } from '../../contexts';
-import { mountWithRouter } from '../../lib';
+import { mountWithRouter, MountWithReduxProvider } from '../../lib';
import { createMemoryHistory } from 'history';
interface MockUrlParamsComponentProps {
@@ -52,9 +52,11 @@ describe('useUrlParams', () => {
jest.spyOn(history, 'push');
const component = mountWithRouter(
-
-
- ,
+
+
+
+
+ ,
history
);
@@ -68,14 +70,16 @@ describe('useUrlParams', () => {
it('gets the expected values using the context', () => {
const component = mountWithRouter(
-
-
-
+
+
+
+
+
);
const getUrlParamsButton = component.find('#getUrlParams');
@@ -92,14 +96,16 @@ describe('useUrlParams', () => {
jest.spyOn(history, 'push');
const component = mountWithRouter(
-
-
- ,
+
+
+
+
+ ,
history
);
diff --git a/x-pack/plugins/uptime/public/hooks/use_filter_update.ts b/x-pack/plugins/uptime/public/hooks/use_filter_update.ts
index 550de134c49bc..fefb676e6e2b5 100644
--- a/x-pack/plugins/uptime/public/hooks/use_filter_update.ts
+++ b/x-pack/plugins/uptime/public/hooks/use_filter_update.ts
@@ -20,14 +20,18 @@ interface SelectedFilters {
selectedFilters: Map;
}
-export const useFilterUpdate = (fieldName?: string, values?: string[]): SelectedFilters => {
+export const useFilterUpdate = (
+ fieldName?: string,
+ values?: string[],
+ shouldUpdateUrl: boolean = true
+): SelectedFilters => {
const [getUrlParams, updateUrl] = useUrlParams();
const { filters: currentFilters } = getUrlParams();
// update filters in the URL from filter group
const onFilterUpdate = (filtersKuery: string) => {
- if (currentFilters !== filtersKuery) {
+ if (currentFilters !== filtersKuery && shouldUpdateUrl) {
updateUrl({ filters: filtersKuery, pagination: '' });
}
};
diff --git a/x-pack/plugins/uptime/public/hooks/use_url_params.ts b/x-pack/plugins/uptime/public/hooks/use_url_params.ts
index c706b92ff3616..0981da20a7a07 100644
--- a/x-pack/plugins/uptime/public/hooks/use_url_params.ts
+++ b/x-pack/plugins/uptime/public/hooks/use_url_params.ts
@@ -4,9 +4,13 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import { useEffect } from 'react';
import { parse, stringify } from 'query-string';
import { useLocation, useHistory } from 'react-router-dom';
+import { useDispatch, useSelector } from 'react-redux';
import { UptimeUrlParams, getSupportedUrlParams } from '../lib/helper';
+import { selectedFiltersSelector } from '../state/selectors';
+import { setSelectedFilters } from '../state/actions/selected_filters';
export type GetUrlParams = () => UptimeUrlParams;
export type UpdateUrlParams = (updatedParams: {
@@ -27,9 +31,35 @@ export const useGetUrlParams: GetUrlParams = () => {
return getSupportedUrlParams(params);
};
+const getMapFromFilters = (value: any): Map | undefined => {
+ try {
+ return new Map(JSON.parse(value));
+ } catch {
+ return undefined;
+ }
+};
+
+const mapMapToObject = (map: Map) => ({
+ locations: map.get('observer.geo.name') ?? [],
+ ports: map.get('url.port') ?? [],
+ schemes: map.get('monitor.type') ?? [],
+ tags: map.get('tags') ?? [],
+});
+
export const useUrlParams: UptimeUrlParamsHook = () => {
const location = useLocation();
const history = useHistory();
+ const dispatch = useDispatch();
+ const selectedFilters = useSelector(selectedFiltersSelector);
+ const { filters } = useGetUrlParams();
+ useEffect(() => {
+ if (selectedFilters === null) {
+ const filterMap = getMapFromFilters(filters);
+ if (filterMap) {
+ dispatch(setSelectedFilters(mapMapToObject(filterMap)));
+ }
+ }
+ }, [dispatch, filters, selectedFilters]);
const updateUrlParams: UpdateUrlParams = (updatedParams) => {
if (!history || !location) return;
@@ -57,6 +87,12 @@ export const useUrlParams: UptimeUrlParamsHook = () => {
{ sort: false }
),
});
+ const filterMap = getMapFromFilters(mergedParams.filters);
+ if (!filterMap) {
+ dispatch(setSelectedFilters(null));
+ } else {
+ dispatch(setSelectedFilters(mapMapToObject(filterMap)));
+ }
};
return [useGetUrlParams, updateUrlParams];
diff --git a/x-pack/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx b/x-pack/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx
index c83a04e4e9939..3a940b4655b19 100644
--- a/x-pack/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx
+++ b/x-pack/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx
@@ -9,7 +9,6 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { get } from 'lodash';
import { i18n as i18nFormatter } from '@kbn/i18n';
-import { alertTypeInitializers } from '../../alert_types';
import { UptimeApp, UptimeAppProps } from '../../../uptime_app';
import { getIntegratedAppAvailability } from './capabilities_adapter';
import {
@@ -34,18 +33,6 @@ export const getKibanaFrameworkAdapter = (
i18n,
} = core;
- const {
- data: { autocomplete },
- triggers_actions_ui,
- } = plugins;
-
- alertTypeInitializers.forEach((init) => {
- const alertInitializer = init({ autocomplete });
- if (!triggers_actions_ui.alertTypeRegistry.has(alertInitializer.id)) {
- triggers_actions_ui.alertTypeRegistry.register(init({ autocomplete }));
- }
- });
-
const { apm, infrastructure, logs } = getIntegratedAppAvailability(
capabilities,
INTEGRATED_SOLUTIONS
diff --git a/x-pack/plugins/uptime/public/lib/alert_types/__tests__/monitor_status.test.ts b/x-pack/plugins/uptime/public/lib/alert_types/__tests__/monitor_status.test.ts
index 098a999b0d89c..7ca5e7438d28a 100644
--- a/x-pack/plugins/uptime/public/lib/alert_types/__tests__/monitor_status.test.ts
+++ b/x-pack/plugins/uptime/public/lib/alert_types/__tests__/monitor_status.test.ts
@@ -33,6 +33,24 @@ describe('monitor status alert type', () => {
`);
});
+ it('accepts original alert params', () => {
+ expect(
+ validate({
+ locations: ['fairbanks'],
+ numTimes: 3,
+ timerange: {
+ from: 'now-15m',
+ to: 'now',
+ },
+ filters: '{foo: "bar"}',
+ })
+ ).toMatchInlineSnapshot(`
+ Object {
+ "errors": Object {},
+ }
+ `);
+ });
+
describe('timerange', () => {
it('has invalid timerangeCount value', () => {
expect(validate({ ...params, timerangeCount: 0 })).toMatchInlineSnapshot(`
@@ -96,7 +114,22 @@ describe('monitor status alert type', () => {
});
describe('initMonitorStatusAlertType', () => {
- expect(initMonitorStatusAlertType({ autocomplete: {} })).toMatchInlineSnapshot(`
+ expect(
+ initMonitorStatusAlertType({
+ store: {
+ dispatch: jest.fn(),
+ getState: jest.fn(),
+ replaceReducer: jest.fn(),
+ subscribe: jest.fn(),
+ [Symbol.observable]: jest.fn(),
+ },
+ // @ts-ignore we don't need to test this functionality here because
+ // it's not used by the code this file tests
+ core: {},
+ // @ts-ignore
+ plugins: {},
+ })
+ ).toMatchInlineSnapshot(`
Object {
"alertParamsExpression": [Function],
"defaultActionMessage": "{{context.message}}
@@ -104,8 +137,20 @@ describe('monitor status alert type', () => {
{{context.downMonitorsWithGeo}}",
"iconClass": "uptimeApp",
"id": "xpack.uptime.alerts.monitorStatus",
- "name": ,
- "requiresAppContext": true,
+ "name":
+
+ ,
+ "requiresAppContext": false,
"validate": [Function],
}
`);
diff --git a/x-pack/plugins/uptime/public/lib/alert_types/index.ts b/x-pack/plugins/uptime/public/lib/alert_types/index.ts
index 9a0151e95748c..f2f72311d2262 100644
--- a/x-pack/plugins/uptime/public/lib/alert_types/index.ts
+++ b/x-pack/plugins/uptime/public/lib/alert_types/index.ts
@@ -4,11 +4,16 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import { CoreStart } from 'kibana/public';
import { AlertTypeModel } from '../../../../triggers_actions_ui/public';
import { initMonitorStatusAlertType } from './monitor_status';
import { initTlsAlertType } from './tls';
+import { ClientPluginsStart } from '../../apps/plugin';
-export type AlertTypeInitializer = (dependenies: { autocomplete: any }) => AlertTypeModel;
+export type AlertTypeInitializer = (dependenies: {
+ core: CoreStart;
+ plugins: ClientPluginsStart;
+}) => AlertTypeModel;
export const alertTypeInitializers: AlertTypeInitializer[] = [
initMonitorStatusAlertType,
diff --git a/x-pack/plugins/uptime/public/lib/alert_types/monitor_status.tsx b/x-pack/plugins/uptime/public/lib/alert_types/monitor_status.tsx
index a39317f8db1ed..9906519865bdc 100644
--- a/x-pack/plugins/uptime/public/lib/alert_types/monitor_status.tsx
+++ b/x-pack/plugins/uptime/public/lib/alert_types/monitor_status.tsx
@@ -4,24 +4,33 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import { Provider as ReduxProvider } from 'react-redux';
import React from 'react';
import { isRight } from 'fp-ts/lib/Either';
import { PathReporter } from 'io-ts/lib/PathReporter';
import { AlertTypeModel } from '../../../../triggers_actions_ui/public';
import { AlertTypeInitializer } from '.';
-import { AtomicStatusCheckParamsType } from '../../../common/runtime_types';
+import { AtomicStatusCheckParamsType, StatusCheckParamsType } from '../../../common/runtime_types';
import { MonitorStatusTitle } from './monitor_status_title';
import { CLIENT_ALERT_TYPES } from '../../../common/constants';
import { MonitorStatusTranslations } from './translations';
+import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
+import { store } from '../../state';
export const validate = (alertParams: unknown) => {
const errors: Record = {};
const decoded = AtomicStatusCheckParamsType.decode(alertParams);
+ const oldDecoded = StatusCheckParamsType.decode(alertParams);
- if (!isRight(decoded)) {
- errors.typeCheckFailure = 'Provided parameters do not conform to the expected type.';
- errors.typeCheckParsingMessage = PathReporter.report(decoded);
- } else {
+ if (!isRight(decoded) && !isRight(oldDecoded)) {
+ return {
+ errors: {
+ typeCheckFailure: 'Provided parameters do not conform to the expected type.',
+ typeCheckParsingMessage: PathReporter.report(decoded),
+ },
+ };
+ }
+ if (isRight(decoded)) {
const { numTimes, timerangeCount } = decoded.right;
if (numTimes < 1) {
errors.invalidNumTimes = 'Number of alert check down times must be an integer greater than 0';
@@ -44,15 +53,26 @@ const AlertMonitorStatus = React.lazy(() =>
);
export const initMonitorStatusAlertType: AlertTypeInitializer = ({
- autocomplete,
+ core,
+ plugins,
}): AlertTypeModel => ({
id: CLIENT_ALERT_TYPES.MONITOR_STATUS,
- name: ,
- iconClass: 'uptimeApp',
- alertParamsExpression: (params: any) => (
-
+ name: (
+
+
+
),
+ iconClass: 'uptimeApp',
+ alertParamsExpression: (params: any) => {
+ return (
+
+
+
+
+
+ );
+ },
validate,
defaultActionMessage,
- requiresAppContext: true,
+ requiresAppContext: false,
});
diff --git a/x-pack/plugins/uptime/public/lib/alert_types/monitor_status_title.tsx b/x-pack/plugins/uptime/public/lib/alert_types/monitor_status_title.tsx
index 3fe497f9e88bc..1e2751a4ac388 100644
--- a/x-pack/plugins/uptime/public/lib/alert_types/monitor_status_title.tsx
+++ b/x-pack/plugins/uptime/public/lib/alert_types/monitor_status_title.tsx
@@ -5,30 +5,13 @@
*/
import React from 'react';
-import { useSelector } from 'react-redux';
import { FormattedMessage } from '@kbn/i18n/react';
-import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner, EuiText } from '@elastic/eui';
-import { snapshotDataSelector } from '../../state/selectors';
export const MonitorStatusTitle = () => {
- const { count, loading } = useSelector(snapshotDataSelector);
return (
-
-
- {' '}
-
-
- {!loading ? (
-
- {count.total} monitors
-
- ) : (
-
- )}
-
-
+
);
};
diff --git a/x-pack/plugins/uptime/public/lib/alert_types/tls.tsx b/x-pack/plugins/uptime/public/lib/alert_types/tls.tsx
index 15ac849fe871d..c541ea4ae1331 100644
--- a/x-pack/plugins/uptime/public/lib/alert_types/tls.tsx
+++ b/x-pack/plugins/uptime/public/lib/alert_types/tls.tsx
@@ -5,21 +5,30 @@
*/
import React from 'react';
+import { Provider as ReduxProvider } from 'react-redux';
import { AlertTypeModel } from '../../../../triggers_actions_ui/public';
import { CLIENT_ALERT_TYPES } from '../../../common/constants';
import { TlsTranslations } from './translations';
import { AlertTypeInitializer } from '.';
+import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
+import { store } from '../../state';
const { name, defaultActionMessage } = TlsTranslations;
-
-export const initTlsAlertType: AlertTypeInitializer = (): AlertTypeModel => ({
+const TlsAlertExpression = React.lazy(() =>
+ import('../../components/overview/alerts/alerts_containers/alert_tls')
+);
+export const initTlsAlertType: AlertTypeInitializer = ({ core, plugins }): AlertTypeModel => ({
id: CLIENT_ALERT_TYPES.TLS,
iconClass: 'uptimeApp',
- alertParamsExpression: React.lazy(() =>
- import('../../components/overview/alerts/alerts_containers/alert_tls')
+ alertParamsExpression: (_params: any) => (
+
+
+
+
+
),
name,
validate: () => ({ errors: {} }),
defaultActionMessage,
- requiresAppContext: true,
+ requiresAppContext: false,
});
diff --git a/x-pack/plugins/uptime/public/lib/helper/helper_with_redux.tsx b/x-pack/plugins/uptime/public/lib/helper/helper_with_redux.tsx
new file mode 100644
index 0000000000000..a68184dbdff97
--- /dev/null
+++ b/x-pack/plugins/uptime/public/lib/helper/helper_with_redux.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 { Provider as ReduxProvider } from 'react-redux';
+
+export const MountWithReduxProvider: React.FC = ({ children }) => (
+
+ {children}
+
+);
diff --git a/x-pack/plugins/uptime/public/lib/helper/index.ts b/x-pack/plugins/uptime/public/lib/helper/index.ts
index cf49328141b83..10663163e8fda 100644
--- a/x-pack/plugins/uptime/public/lib/helper/index.ts
+++ b/x-pack/plugins/uptime/public/lib/helper/index.ts
@@ -9,3 +9,4 @@ export * from './observability_integration';
export { getChartDateLabel } from './charts';
export { seriesHasDownValues } from './series_has_down_values';
export { UptimeUrlParams, getSupportedUrlParams } from './url_params';
+export { MountWithReduxProvider } from './helper_with_redux';
diff --git a/x-pack/plugins/uptime/public/lib/index.ts b/x-pack/plugins/uptime/public/lib/index.ts
index 06ac06e647adc..92787737d579f 100644
--- a/x-pack/plugins/uptime/public/lib/index.ts
+++ b/x-pack/plugins/uptime/public/lib/index.ts
@@ -4,4 +4,5 @@
* you may not use this file except in compliance with the Elastic License.
*/
+export { MountWithReduxProvider } from './helper';
export { renderWithRouter, shallowWithRouter, mountWithRouter } from './helper/helper_with_router';
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
index c9e4eef386764..63d4c24f965d9 100644
--- a/x-pack/plugins/uptime/public/pages/__tests__/page_header.test.tsx
+++ b/x-pack/plugins/uptime/public/pages/__tests__/page_header.test.tsx
@@ -6,47 +6,33 @@
import React from 'react';
import { PageHeader } from '../page_header';
-import { renderWithRouter } from '../../lib';
-import { Provider } from 'react-redux';
+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');
});
});
-
-const MockReduxProvider = ({ children }: { children: React.ReactElement }) => (
-
- {children}
-
-);
diff --git a/x-pack/plugins/uptime/public/state/actions/overview_filters.ts b/x-pack/plugins/uptime/public/state/actions/overview_filters.ts
index dbbd01e34b4d4..8eefa701a240a 100644
--- a/x-pack/plugins/uptime/public/state/actions/overview_filters.ts
+++ b/x-pack/plugins/uptime/public/state/actions/overview_filters.ts
@@ -9,6 +9,7 @@ import { OverviewFilters } from '../../../common/runtime_types';
export const FETCH_OVERVIEW_FILTERS = 'FETCH_OVERVIEW_FILTERS';
export const FETCH_OVERVIEW_FILTERS_FAIL = 'FETCH_OVERVIEW_FILTERS_FAIL';
export const FETCH_OVERVIEW_FILTERS_SUCCESS = 'FETCH_OVERVIEW_FILTERS_SUCCESS';
+export const SET_OVERVIEW_FILTERS = 'SET_OVERVIEW_FILTERS';
export interface GetOverviewFiltersPayload {
dateRangeStart: string;
@@ -36,10 +37,16 @@ interface GetOverviewFiltersFailAction {
payload: Error;
}
+interface SetOverviewFiltersAction {
+ type: typeof SET_OVERVIEW_FILTERS;
+ payload: OverviewFilters;
+}
+
export type OverviewFiltersAction =
| GetOverviewFiltersFetchAction
| GetOverviewFiltersSuccessAction
- | GetOverviewFiltersFailAction;
+ | GetOverviewFiltersFailAction
+ | SetOverviewFiltersAction;
export const fetchOverviewFilters = (
payload: GetOverviewFiltersPayload
@@ -59,3 +66,8 @@ export const fetchOverviewFiltersSuccess = (
type: FETCH_OVERVIEW_FILTERS_SUCCESS,
payload: filters,
});
+
+export const setOverviewFilters = (filters: OverviewFilters): SetOverviewFiltersAction => ({
+ type: SET_OVERVIEW_FILTERS,
+ payload: filters,
+});
diff --git a/x-pack/plugins/uptime/public/state/actions/selected_filters.ts b/x-pack/plugins/uptime/public/state/actions/selected_filters.ts
new file mode 100644
index 0000000000000..11c159b09a157
--- /dev/null
+++ b/x-pack/plugins/uptime/public/state/actions/selected_filters.ts
@@ -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 { createAction } from 'redux-actions';
+
+export interface SelectedFilters {
+ locations: string[];
+ ports: number[];
+ schemes: string[];
+ tags: string[];
+}
+
+export type SelectedFiltersPayload = SelectedFilters;
+
+export const getSelectedFilters = createAction('GET SELECTED FILTERS');
+export const setSelectedFilters = createAction(
+ 'SET_SELECTED_FILTERS'
+);
diff --git a/x-pack/plugins/uptime/public/state/index.ts b/x-pack/plugins/uptime/public/state/index.ts
index e3563c74294d2..1f4ce7103afbc 100644
--- a/x-pack/plugins/uptime/public/state/index.ts
+++ b/x-pack/plugins/uptime/public/state/index.ts
@@ -9,12 +9,12 @@ import createSagaMiddleware from 'redux-saga';
import { rootEffect } from './effects';
import { rootReducer } from './reducers';
+export type AppState = ReturnType;
+
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const sagaMW = createSagaMiddleware();
export const store = createStore(rootReducer, composeEnhancers(applyMiddleware(sagaMW)));
-export type AppState = ReturnType;
-
sagaMW.run(rootEffect);
diff --git a/x-pack/plugins/uptime/public/state/reducers/__tests__/ui.test.ts b/x-pack/plugins/uptime/public/state/reducers/__tests__/ui.test.ts
index 3b8447ec2d713..4683c654270db 100644
--- a/x-pack/plugins/uptime/public/state/reducers/__tests__/ui.test.ts
+++ b/x-pack/plugins/uptime/public/state/reducers/__tests__/ui.test.ts
@@ -4,7 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { setBasePath, toggleIntegrationsPopover, setAlertFlyoutVisible } from '../../actions';
+import {
+ setBasePath,
+ toggleIntegrationsPopover,
+ setAlertFlyoutVisible,
+ setSearchTextAction,
+} from '../../actions';
import { uiReducer } from '../ui';
import { Action } from 'redux-actions';
@@ -67,4 +72,28 @@ describe('ui reducer', () => {
}
`);
});
+
+ it('sets the search text', () => {
+ const action = setSearchTextAction('lorem ipsum') as Action;
+ expect(
+ uiReducer(
+ {
+ alertFlyoutVisible: false,
+ basePath: '',
+ esKuery: '',
+ integrationsPopoverOpen: null,
+ searchText: '',
+ },
+ action
+ )
+ ).toMatchInlineSnapshot(`
+ Object {
+ "alertFlyoutVisible": false,
+ "basePath": "",
+ "esKuery": "",
+ "integrationsPopoverOpen": null,
+ "searchText": "lorem ipsum",
+ }
+ `);
+ });
});
diff --git a/x-pack/plugins/uptime/public/state/reducers/index.ts b/x-pack/plugins/uptime/public/state/reducers/index.ts
index ead7f5b46431b..c05c740ab8ebf 100644
--- a/x-pack/plugins/uptime/public/state/reducers/index.ts
+++ b/x-pack/plugins/uptime/public/state/reducers/index.ts
@@ -19,6 +19,7 @@ import { monitorDurationReducer } from './monitor_duration';
import { indexStatusReducer } from './index_status';
import { mlJobsReducer } from './ml_anomaly';
import { certificatesReducer } from '../certificates/certificates';
+import { selectedFiltersReducer } from './selected_filters';
export const rootReducer = combineReducers({
monitor: monitorReducer,
@@ -35,4 +36,5 @@ export const rootReducer = combineReducers({
monitorDuration: monitorDurationReducer,
indexStatus: indexStatusReducer,
certificates: certificatesReducer,
+ selectedFilters: selectedFiltersReducer,
});
diff --git a/x-pack/plugins/uptime/public/state/reducers/overview_filters.ts b/x-pack/plugins/uptime/public/state/reducers/overview_filters.ts
index 0b67d8b0e7689..4548627d9dcb8 100644
--- a/x-pack/plugins/uptime/public/state/reducers/overview_filters.ts
+++ b/x-pack/plugins/uptime/public/state/reducers/overview_filters.ts
@@ -10,6 +10,7 @@ import {
FETCH_OVERVIEW_FILTERS_FAIL,
FETCH_OVERVIEW_FILTERS_SUCCESS,
OverviewFiltersAction,
+ SET_OVERVIEW_FILTERS,
} from '../actions';
export interface OverviewFiltersState {
@@ -51,6 +52,11 @@ export function overviewFiltersReducer(
errors: [...state.errors, action.payload],
loading: false,
};
+ case SET_OVERVIEW_FILTERS:
+ return {
+ ...state,
+ filters: action.payload,
+ };
default:
return state;
}
diff --git a/x-pack/plugins/uptime/public/state/reducers/selected_filters.ts b/x-pack/plugins/uptime/public/state/reducers/selected_filters.ts
new file mode 100644
index 0000000000000..921754c93078a
--- /dev/null
+++ b/x-pack/plugins/uptime/public/state/reducers/selected_filters.ts
@@ -0,0 +1,32 @@
+/*
+ * 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 { Action } from 'redux-actions';
+import {
+ getSelectedFilters,
+ setSelectedFilters,
+ SelectedFilters,
+} from '../actions/selected_filters';
+
+const initialState: SelectedFilters | null = null;
+
+export function selectedFiltersReducer(
+ state = initialState,
+ action: Action
+): SelectedFilters | null {
+ switch (action.type) {
+ case String(getSelectedFilters):
+ return state;
+ case String(setSelectedFilters):
+ if (state === null) return { ...action.payload };
+ return {
+ ...(state || {}),
+ ...action.payload,
+ };
+ default:
+ return state;
+ }
+}
diff --git a/x-pack/plugins/uptime/public/state/selectors/__tests__/index.test.ts b/x-pack/plugins/uptime/public/state/selectors/__tests__/index.test.ts
index 2eb0f1e8cb0ee..b1885ddeeba3f 100644
--- a/x-pack/plugins/uptime/public/state/selectors/__tests__/index.test.ts
+++ b/x-pack/plugins/uptime/public/state/selectors/__tests__/index.test.ts
@@ -107,6 +107,7 @@ describe('state selectors', () => {
loading: false,
},
},
+ selectedFilters: null,
};
it('selects base path from state', () => {
diff --git a/x-pack/plugins/uptime/public/state/selectors/index.ts b/x-pack/plugins/uptime/public/state/selectors/index.ts
index b088c346ad811..d08db2ccf5f2d 100644
--- a/x-pack/plugins/uptime/public/state/selectors/index.ts
+++ b/x-pack/plugins/uptime/public/state/selectors/index.ts
@@ -86,3 +86,5 @@ export const overviewFiltersSelector = ({ overviewFilters }: AppState) => overvi
export const esKuerySelector = ({ ui: { esKuery } }: AppState) => esKuery;
export const searchTextSelector = ({ ui: { searchText } }: AppState) => searchText;
+
+export const selectedFiltersSelector = ({ selectedFilters }: AppState) => selectedFilters;
diff --git a/x-pack/plugins/uptime/public/uptime_app.tsx b/x-pack/plugins/uptime/public/uptime_app.tsx
index cc6475d6c9d90..4208d79e761ed 100644
--- a/x-pack/plugins/uptime/public/uptime_app.tsx
+++ b/x-pack/plugins/uptime/public/uptime_app.tsx
@@ -20,14 +20,13 @@ import {
UptimeStartupPluginsContextProvider,
} from './contexts';
import { CommonlyUsedRange } from './components/common/uptime_date_picker';
-import { store } from './state';
import { setBasePath } from './state/actions';
import { PageRouter } from './routes';
import {
UptimeAlertsContextProvider,
UptimeAlertsFlyoutWrapper,
} from './components/overview/alerts';
-import { kibanaService } from './state/kibana_service';
+import { store } from './state';
export interface UptimeAppColors {
danger: string;
@@ -87,8 +86,6 @@ const Application = (props: UptimeAppProps) => {
);
}, [canSave, renderGlobalHelpControls, setBadge]);
- kibanaService.core = core;
-
store.dispatch(setBasePath(basePath));
return (