From 14bb0d1e58b0312643cbc2e822a163c046acd081 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 16 Apr 2020 21:13:35 +0200 Subject: [PATCH 1/5] [Uptime] Certificate expiration threshold settings (#63682) * update settings * added cert form * update settings * update types * update test * updated tests * updated snapshots --- .../common/runtime_types/dynamic_settings.ts | 19 +- .../certificate_form.test.tsx.snap | 69 ++++++++ .../__snapshots__/indices_form.test.tsx.snap | 69 ++++++++ .../__tests__/certificate_form.test.tsx | 27 +++ .../settings/__tests__/indices_form.test.tsx | 27 +++ .../components/settings/certificate_form.tsx | 160 +++++++++++++++++ .../components/settings/indices_form.tsx | 90 ++++++++++ .../plugins/uptime/public/pages/settings.tsx | 163 ++++++------------ .../lib/alerts/__tests__/status_check.test.ts | 8 + .../uptime/server/lib/saved_objects.ts | 16 +- .../apis/uptime/rest/dynamic_settings.ts | 8 +- .../test/functional/apps/uptime/settings.ts | 36 +++- .../functional/services/uptime/settings.ts | 33 +++- 13 files changed, 601 insertions(+), 124 deletions(-) create mode 100644 x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/certificate_form.test.tsx.snap create mode 100644 x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/indices_form.test.tsx.snap create mode 100644 x-pack/legacy/plugins/uptime/public/components/settings/__tests__/certificate_form.test.tsx create mode 100644 x-pack/legacy/plugins/uptime/public/components/settings/__tests__/indices_form.test.tsx create mode 100644 x-pack/legacy/plugins/uptime/public/components/settings/certificate_form.tsx create mode 100644 x-pack/legacy/plugins/uptime/public/components/settings/indices_form.tsx diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/dynamic_settings.ts b/x-pack/legacy/plugins/uptime/common/runtime_types/dynamic_settings.ts index 6f844447d5b4a4..dc9670bb23d851 100644 --- a/x-pack/legacy/plugins/uptime/common/runtime_types/dynamic_settings.ts +++ b/x-pack/legacy/plugins/uptime/common/runtime_types/dynamic_settings.ts @@ -6,10 +6,20 @@ import * as t from 'io-ts'; -export const DynamicSettingsType = t.type({ - heartbeatIndices: t.string, +export const CertificatesStatesThresholdType = t.interface({ + warningState: t.number, + errorState: t.number, }); +export const DynamicSettingsType = t.intersection([ + t.type({ + heartbeatIndices: t.string, + }), + t.partial({ + certificatesThresholds: CertificatesStatesThresholdType, + }), +]); + export const DynamicSettingsSaveType = t.intersection([ t.type({ success: t.boolean, @@ -21,7 +31,12 @@ export const DynamicSettingsSaveType = t.intersection([ export type DynamicSettings = t.TypeOf; export type DynamicSettingsSaveResponse = t.TypeOf; +export type CertificatesStatesThreshold = t.TypeOf; export const defaultDynamicSettings: DynamicSettings = { heartbeatIndices: 'heartbeat-7*', + certificatesThresholds: { + errorState: 7, + warningState: 30, + }, }; diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/certificate_form.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/certificate_form.test.tsx.snap new file mode 100644 index 00000000000000..36bc9bb8602111 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/certificate_form.test.tsx.snap @@ -0,0 +1,69 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`CertificateForm shallow renders expected elements for valid props 1`] = ` + + + +`; diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/indices_form.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/indices_form.test.tsx.snap new file mode 100644 index 00000000000000..93151198c0f494 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/indices_form.test.tsx.snap @@ -0,0 +1,69 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`CertificateForm shallow renders expected elements for valid props 1`] = ` + + + +`; diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/certificate_form.test.tsx b/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/certificate_form.test.tsx new file mode 100644 index 00000000000000..a3158f3d724456 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/certificate_form.test.tsx @@ -0,0 +1,27 @@ +/* + * 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 { CertificateExpirationForm } from '../certificate_form'; +import { shallowWithRouter } from '../../../lib'; + +describe('CertificateForm', () => { + it('shallow renders expected elements for valid props', () => { + expect( + shallowWithRouter( + + ) + ).toMatchSnapshot(); + }); +}); diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/indices_form.test.tsx b/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/indices_form.test.tsx new file mode 100644 index 00000000000000..654d51019d4e57 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/indices_form.test.tsx @@ -0,0 +1,27 @@ +/* + * 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 { IndicesForm } from '../indices_form'; +import { shallowWithRouter } from '../../../lib'; + +describe('CertificateForm', () => { + it('shallow renders expected elements for valid props', () => { + expect( + shallowWithRouter( + + ) + ).toMatchSnapshot(); + }); +}); diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/certificate_form.tsx b/x-pack/legacy/plugins/uptime/public/components/settings/certificate_form.tsx new file mode 100644 index 00000000000000..5103caee1e1c05 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/settings/certificate_form.tsx @@ -0,0 +1,160 @@ +/* + * 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 { FormattedMessage } from '@kbn/i18n/react'; +import { useSelector } from 'react-redux'; +import { + EuiDescribedFormGroup, + EuiFormRow, + EuiCode, + EuiFieldNumber, + EuiTitle, + EuiSpacer, + EuiSelect, + EuiFlexGroup, + EuiFlexItem, +} from '@elastic/eui'; +import { defaultDynamicSettings, DynamicSettings } from '../../../common/runtime_types'; +import { selectDynamicSettings } from '../../state/selectors'; + +type NumStr = string | number; + +export type OnFieldChangeType = (field: string, value?: NumStr) => void; + +export interface SettingsFormProps { + onChange: OnFieldChangeType; + formFields: DynamicSettings | null; + fieldErrors: any; + isDisabled: boolean; +} + +export const CertificateExpirationForm: React.FC = ({ + onChange, + formFields, + fieldErrors, + isDisabled, +}) => { + const dss = useSelector(selectDynamicSettings); + + return ( + <> + +

+ +

+
+ + + + + } + description={ + + } + > + {defaultDynamicSettings?.certificatesThresholds?.errorState} + ), + }} + /> + } + isInvalid={!!fieldErrors?.certificatesThresholds?.errorState} + label={ + + } + > + + + + onChange( + 'certificatesThresholds.errorState', + value === '' ? undefined : Number(value) + ) + } + /> + + + + + + + {defaultDynamicSettings?.certificatesThresholds?.warningState} + ), + }} + /> + } + isInvalid={!!fieldErrors?.certificatesThresholds?.warningState} + label={ + + } + > + + + + onChange('certificatesThresholds.warningState', Number(event.currentTarget.value)) + } + /> + + + + + + + + + ); +}; diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/indices_form.tsx b/x-pack/legacy/plugins/uptime/public/components/settings/indices_form.tsx new file mode 100644 index 00000000000000..c28eca2ea229e5 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/settings/indices_form.tsx @@ -0,0 +1,90 @@ +/* + * 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 { FormattedMessage } from '@kbn/i18n/react'; +import { useSelector } from 'react-redux'; +import { + EuiDescribedFormGroup, + EuiFormRow, + EuiCode, + EuiFieldText, + EuiTitle, + EuiSpacer, +} from '@elastic/eui'; +import { defaultDynamicSettings } from '../../../common/runtime_types'; +import { selectDynamicSettings } from '../../state/selectors'; +import { SettingsFormProps } from './certificate_form'; + +export const IndicesForm: React.FC = ({ + onChange, + formFields, + fieldErrors, + isDisabled, +}) => { + const dss = useSelector(selectDynamicSettings); + + return ( + <> + +

+ +

+
+ + + + + } + description={ + + } + > + {defaultDynamicSettings.heartbeatIndices}, + }} + /> + } + isInvalid={!!fieldErrors?.heartbeatIndices} + label={ + + } + > + onChange('heartbeatIndices', event.currentTarget.value)} + /> + + + + ); +}; diff --git a/x-pack/legacy/plugins/uptime/public/pages/settings.tsx b/x-pack/legacy/plugins/uptime/public/pages/settings.tsx index 765b0e3c664bc0..049dffecd3f2ef 100644 --- a/x-pack/legacy/plugins/uptime/public/pages/settings.tsx +++ b/x-pack/legacy/plugins/uptime/public/pages/settings.tsx @@ -9,46 +9,54 @@ import { EuiButton, EuiButtonEmpty, EuiCallOut, - EuiCode, - EuiDescribedFormGroup, - EuiFieldText, EuiFlexGroup, EuiFlexItem, EuiForm, - EuiFormRow, EuiPanel, EuiSpacer, - EuiTitle, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { connect } from 'react-redux'; -import { isEqual } from 'lodash'; +import { useDispatch, useSelector } from 'react-redux'; +import { cloneDeep, isEqual, set } from 'lodash'; import { i18n } from '@kbn/i18n'; import { Link } from 'react-router-dom'; -import { AppState } from '../state'; import { selectDynamicSettings } from '../state/selectors'; -import { DynamicSettingsState } from '../state/reducers/dynamic_settings'; import { getDynamicSettings, setDynamicSettings } from '../state/actions/dynamic_settings'; -import { defaultDynamicSettings, DynamicSettings } from '../../common/runtime_types'; +import { DynamicSettings } from '../../common/runtime_types'; import { useBreadcrumbs } from '../hooks/use_breadcrumbs'; import { OVERVIEW_ROUTE } from '../../common/constants'; import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; import { UptimePage, useUptimeTelemetry } from '../hooks'; +import { IndicesForm } from '../components/settings/indices_form'; +import { + CertificateExpirationForm, + OnFieldChangeType, +} from '../components/settings/certificate_form'; + +const getFieldErrors = (formFields: DynamicSettings | null) => { + if (formFields) { + const blankStr = 'May not be blank'; + const { certificatesThresholds, heartbeatIndices } = formFields; + const heartbeatIndErr = heartbeatIndices.match(/^\S+$/) ? '' : blankStr; + const errorStateErr = certificatesThresholds?.errorState ? null : blankStr; + const warningStateErr = certificatesThresholds?.warningState ? null : blankStr; + return { + heartbeatIndices: heartbeatIndErr, + certificatesThresholds: + errorStateErr || warningStateErr + ? { + errorState: errorStateErr, + warningState: warningStateErr, + } + : null, + }; + } + return null; +}; -interface Props { - dynamicSettingsState: DynamicSettingsState; -} - -interface DispatchProps { - dispatchGetDynamicSettings: typeof getDynamicSettings; - dispatchSetDynamicSettings: typeof setDynamicSettings; -} +export const SettingsPage = () => { + const dss = useSelector(selectDynamicSettings); -export const SettingsPageComponent = ({ - dynamicSettingsState: dss, - dispatchGetDynamicSettings, - dispatchSetDynamicSettings, -}: Props & DispatchProps) => { const settingsBreadcrumbText = i18n.translate('xpack.uptime.settingsBreadcrumbText', { defaultMessage: 'Settings', }); @@ -56,9 +64,11 @@ export const SettingsPageComponent = ({ useUptimeTelemetry(UptimePage.Settings); + const dispatch = useDispatch(); + useEffect(() => { - dispatchGetDynamicSettings({}); - }, [dispatchGetDynamicSettings]); + dispatch(getDynamicSettings({})); + }, [dispatch]); const [formFields, setFormFields] = useState(dss.settings || null); @@ -66,22 +76,22 @@ export const SettingsPageComponent = ({ setFormFields({ ...dss.settings }); } - const fieldErrors = formFields && { - heartbeatIndices: formFields.heartbeatIndices.match(/^\S+$/) ? null : 'May not be blank', - }; + const fieldErrors = getFieldErrors(formFields); + const isFormValid = !(fieldErrors && Object.values(fieldErrors).find(v => !!v)); - const onChangeFormField = (field: keyof DynamicSettings, value: any) => { + const onChangeFormField: OnFieldChangeType = (field, value) => { if (formFields) { - formFields[field] = value; - setFormFields({ ...formFields }); + const newFormFields = cloneDeep(formFields); + set(newFormFields, field, value); + setFormFields(cloneDeep(newFormFields)); } }; const onApply = (event: React.FormEvent) => { event.preventDefault(); if (formFields) { - dispatchSetDynamicSettings(formFields); + dispatch(setDynamicSettings(formFields)); } }; @@ -128,68 +138,18 @@ export const SettingsPageComponent = ({
- -

- -

-
- - - - - } - description={ - - } - > - {defaultDynamicSettings.heartbeatIndices} - ), - }} - /> - } - isInvalid={!!fieldErrors?.heartbeatIndices} - label={ - - } - > - - onChangeFormField('heartbeatIndices', event.currentTarget.value) - } - /> - - + + @@ -230,18 +190,3 @@ export const SettingsPageComponent = ({ ); }; - -const mapStateToProps = (state: AppState) => ({ - dynamicSettingsState: selectDynamicSettings(state), -}); - -const mapDispatchToProps = (dispatch: any) => ({ - dispatchGetDynamicSettings: () => { - return dispatch(getDynamicSettings({})); - }, - dispatchSetDynamicSettings: (settings: DynamicSettings) => { - return dispatch(setDynamicSettings(settings)); - }, -}); - -export const SettingsPage = connect(mapStateToProps, mapDispatchToProps)(SettingsPageComponent); diff --git a/x-pack/plugins/uptime/server/lib/alerts/__tests__/status_check.test.ts b/x-pack/plugins/uptime/server/lib/alerts/__tests__/status_check.test.ts index 0d90026e59fb16..f94b3f7545fb30 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/__tests__/status_check.test.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/__tests__/status_check.test.ts @@ -89,6 +89,10 @@ describe('status check alert', () => { "callES": [MockFunction], "dynamicSettings": Object { "heartbeatIndices": "heartbeat-7*", + "certificatesThresholds": Object { + "errorState": 7, + "warningState": 30, + }, }, "locations": Array [], "numTimes": 5, @@ -132,6 +136,10 @@ describe('status check alert', () => { "callES": [MockFunction], "dynamicSettings": Object { "heartbeatIndices": "heartbeat-7*", + "certificatesThresholds": Object { + "errorState": 7, + "warningState": 30, + }, }, "locations": Array [], "numTimes": 5, diff --git a/x-pack/plugins/uptime/server/lib/saved_objects.ts b/x-pack/plugins/uptime/server/lib/saved_objects.ts index 01004ad7c6424a..3ccfd498c44bfc 100644 --- a/x-pack/plugins/uptime/server/lib/saved_objects.ts +++ b/x-pack/plugins/uptime/server/lib/saved_objects.ts @@ -7,14 +7,10 @@ import { DynamicSettings, defaultDynamicSettings, -} from '../../../../legacy/plugins/uptime/common/runtime_types/dynamic_settings'; +} from '../../../../legacy/plugins/uptime/common/runtime_types'; import { SavedObjectsType, SavedObjectsErrorHelpers } from '../../../../../src/core/server'; import { UMSavedObjectsQueryFn } from './adapters'; -export interface UMDynamicSettingsType { - heartbeatIndices: string; -} - export interface UMSavedObjectsAdapter { getUptimeDynamicSettings: UMSavedObjectsQueryFn; setUptimeDynamicSettings: UMSavedObjectsQueryFn; @@ -32,6 +28,16 @@ export const umDynamicSettings: SavedObjectsType = { heartbeatIndices: { type: 'keyword', }, + certificatesThresholds: { + properties: { + errorState: { + type: 'long', + }, + warningState: { + type: 'long', + }, + }, + }, }, }, }; diff --git a/x-pack/test/api_integration/apis/uptime/rest/dynamic_settings.ts b/x-pack/test/api_integration/apis/uptime/rest/dynamic_settings.ts index f4dd7c244f8b51..a1b731169f0a0d 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/dynamic_settings.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/dynamic_settings.ts @@ -18,7 +18,13 @@ export default function({ getService }: FtrProviderContext) { }); it('can change the settings', async () => { - const newSettings = { heartbeatIndices: 'myIndex1*' }; + const newSettings = { + heartbeatIndices: 'myIndex1*', + certificatesThresholds: { + errorState: 5, + warningState: 15, + }, + }; const postResponse = await supertest .post(`/api/uptime/dynamic_settings`) .set('kbn-xsrf', 'true') diff --git a/x-pack/test/functional/apps/uptime/settings.ts b/x-pack/test/functional/apps/uptime/settings.ts index e6314d3d30a7a5..e81bbc5ae42f92 100644 --- a/x-pack/test/functional/apps/uptime/settings.ts +++ b/x-pack/test/functional/apps/uptime/settings.ts @@ -74,7 +74,41 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { // Verify that the settings page shows the value we previously saved await settings.go(); const fields = await settings.loadFields(); - expect(fields).to.eql(newFieldValues); + expect(fields.heartbeatIndices).to.eql(newFieldValues.heartbeatIndices); + }); + + it('changing certificate expiration error threshold is reflected in settings page', async () => { + const settings = uptimeService.settings; + + await settings.go(); + + const newErrorThreshold = '5'; + await settings.changeErrorThresholdInput(newErrorThreshold); + await settings.apply(); + + await uptimePage.goToRoot(); + + // Verify that the settings page shows the value we previously saved + await settings.go(); + const fields = await settings.loadFields(); + expect(fields.certificatesThresholds.errorState).to.eql(newErrorThreshold); + }); + + it('changing certificate expiration warning threshold is reflected in settings page', async () => { + const settings = uptimeService.settings; + + await settings.go(); + + const newWarningThreshold = '15'; + await settings.changeWarningThresholdInput(newWarningThreshold); + await settings.apply(); + + await uptimePage.goToRoot(); + + // Verify that the settings page shows the value we previously saved + await settings.go(); + const fields = await settings.loadFields(); + expect(fields.certificatesThresholds.warningState).to.eql(newWarningThreshold); }); }); }; diff --git a/x-pack/test/functional/services/uptime/settings.ts b/x-pack/test/functional/services/uptime/settings.ts index a64d39cd62a6d4..14cab368b766a2 100644 --- a/x-pack/test/functional/services/uptime/settings.ts +++ b/x-pack/test/functional/services/uptime/settings.ts @@ -10,20 +10,41 @@ export function UptimeSettingsProvider({ getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const retry = getService('retry'); + const changeInputField = async (text: string, field: string) => { + const input = await testSubjects.find(field, 5000); + await input.clearValueWithKeyboard(); + await input.type(text); + }; + return { go: async () => { await testSubjects.click('settings-page-link', 5000); }, + changeHeartbeatIndicesInput: async (text: string) => { - const input = await testSubjects.find('heartbeat-indices-input-loaded', 5000); - await input.clearValueWithKeyboard(); - await input.type(text); + await changeInputField(text, 'heartbeat-indices-input-loaded'); + }, + changeErrorThresholdInput: async (text: string) => { + await changeInputField(text, 'error-state-threshold-input-loaded'); + }, + changeWarningThresholdInput: async (text: string) => { + await changeInputField(text, 'warning-state-threshold-input-loaded'); }, loadFields: async () => { - const input = await testSubjects.find('heartbeat-indices-input-loaded', 5000); - const heartbeatIndices = await input.getAttribute('value'); + const indInput = await testSubjects.find('heartbeat-indices-input-loaded', 5000); + const errorInput = await testSubjects.find('error-state-threshold-input-loaded', 5000); + const warningInput = await testSubjects.find('warning-state-threshold-input-loaded', 5000); + const heartbeatIndices = await indInput.getAttribute('value'); + const errorThreshold = await errorInput.getAttribute('value'); + const warningThreshold = await warningInput.getAttribute('value'); - return { heartbeatIndices }; + return { + heartbeatIndices, + certificatesThresholds: { + errorState: errorThreshold, + warningState: warningThreshold, + }, + }; }, applyButtonIsDisabled: async () => { return !!(await (await testSubjects.find('apply-settings-button')).getAttribute('disabled')); From d7ab11126b613565a9729aca0f5a91b0b8dba812 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Sat, 18 Apr 2020 13:41:11 +0200 Subject: [PATCH 2/5] =?UTF-8?q?[Uptime]=20Refresh=20index=20and=20also=20s?= =?UTF-8?q?how=20more=20info=20to=20user=20regardi=E2=80=A6=20(#62606)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refresh index and also show more info to user * updated type * updated type * updated test * updated formatting * update text * updated types * updated translation * update * fixed types * updated code * fixed types Co-authored-by: Elastic Machine --- .../connected/empty_state/empty_state.tsx | 22 +- .../__snapshots__/data_missing.test.tsx.snap | 52 - .../data_or_index_missing.test.tsx.snap | 92 ++ .../__snapshots__/empty_state.test.tsx.snap | 1141 ----------------- .../__tests__/data_missing.test.tsx | 16 - .../__tests__/data_or_index_missing.test.tsx | 24 + .../__tests__/empty_state.test.tsx | 14 +- .../functional/empty_state/data_missing.tsx | 64 - .../empty_state/data_or_index_missing.tsx | 86 ++ .../functional/empty_state/empty_index.tsx | 67 - .../functional/empty_state/empty_state.tsx | 34 +- .../uptime/public/pages/page_header.tsx | 9 +- .../plugins/uptime/public/pages/settings.tsx | 4 +- .../public/state/actions/dynamic_settings.ts | 3 +- .../public/state/api/dynamic_settings.ts | 13 +- .../public/state/effects/dynamic_settings.ts | 6 +- .../translations/translations/ja-JP.json | 5 - .../translations/translations/zh-CN.json | 5 - 18 files changed, 264 insertions(+), 1393 deletions(-) delete mode 100644 x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/data_missing.test.tsx.snap create mode 100644 x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/data_or_index_missing.test.tsx.snap delete mode 100644 x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap delete mode 100644 x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/data_missing.test.tsx create mode 100644 x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/data_or_index_missing.test.tsx delete mode 100644 x-pack/legacy/plugins/uptime/public/components/functional/empty_state/data_missing.tsx create mode 100644 x-pack/legacy/plugins/uptime/public/components/functional/empty_state/data_or_index_missing.tsx delete mode 100644 x-pack/legacy/plugins/uptime/public/components/functional/empty_state/empty_index.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/empty_state/empty_state.tsx b/x-pack/legacy/plugins/uptime/public/components/connected/empty_state/empty_state.tsx index 55c92e70b6066d..b0868af70480a5 100644 --- a/x-pack/legacy/plugins/uptime/public/components/connected/empty_state/empty_state.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/connected/empty_state/empty_state.tsx @@ -7,26 +7,44 @@ import React, { useContext, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { indexStatusAction } from '../../../state/actions'; -import { indexStatusSelector } from '../../../state/selectors'; +import { indexStatusSelector, selectDynamicSettings } from '../../../state/selectors'; import { EmptyStateComponent } from '../../functional/empty_state/empty_state'; import { UptimeRefreshContext } from '../../../contexts'; +import { getDynamicSettings } from '../../../state/actions/dynamic_settings'; export const EmptyState: React.FC = ({ children }) => { const { data, loading, error } = useSelector(indexStatusSelector); const { lastRefresh } = useContext(UptimeRefreshContext); + const { settings } = useSelector(selectDynamicSettings); + + const heartbeatIndices = settings?.heartbeatIndices || ''; + const dispatch = useDispatch(); useEffect(() => { - dispatch(indexStatusAction.get()); + if (!data || data?.docCount === 0 || data?.indexExists === false) { + dispatch(indexStatusAction.get()); + } + // Don't add data , it will create endless loop + // eslint-disable-next-line react-hooks/exhaustive-deps }, [dispatch, lastRefresh]); + useEffect(() => { + dispatch(indexStatusAction.get()); + }, [dispatch, heartbeatIndices]); + + useEffect(() => { + dispatch(getDynamicSettings()); + }, [dispatch]); + return ( ); }; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/data_missing.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/data_missing.test.tsx.snap deleted file mode 100644 index 20a66cacb50e73..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/data_missing.test.tsx.snap +++ /dev/null @@ -1,52 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`DataMissing component renders basePath and headingMessage 1`] = ` - - - - - - - - , - } - } - /> -

- } - iconType="uptimeApp" - title={ - -

- bar -

-
- } - /> -
-
-
-`; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/data_or_index_missing.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/data_or_index_missing.test.tsx.snap new file mode 100644 index 00000000000000..25ac5a1f0974e9 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/data_or_index_missing.test.tsx.snap @@ -0,0 +1,92 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DataOrIndexMissing component renders headingMessage 1`] = ` + + + + + + + + + + + + + + + + + } + body={ + +

+ +

+

+ +

+
+ } + iconType="logoUptime" + title={ + +

+ + heartbeat-* + , + } + } + /> +

+
+ } + /> +
+
+
+`; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap deleted file mode 100644 index 66100f717244d5..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap +++ /dev/null @@ -1,1141 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`EmptyState component does not render empty state with appropriate base path and no docs 1`] = ` - - - -
- -
- -
- - -
- - - - , - } - } - /> -

- } - iconType="uptimeApp" - title={ - -

- No uptime data found -

-
- } - > -
- -
- - -
- - - - - -

- No uptime data found -

-
-
- -
- - -
-

- - - , - } - } - > - - - - Configure Heartbeat - - - - to start logging uptime data. - -

-
-
- - -
- -
- -
- -
- - - -`; - -exports[`EmptyState component doesn't render child components when count is falsy 1`] = ` - - - - - - -

- Loading… -

-
- - } - > -
- - - -
- - - - -
- - -

- Loading… -

-
-
- - - -
- - - -`; - -exports[`EmptyState component notifies when index does not exist 1`] = ` - - - -
- -
- -
- - -
- - - - , - } - } - /> -

- } - iconType="uptimeApp" - title={ - -

- Uptime index not found -

-
- } - > -
- -
- - -
- - - - - -

- Uptime index not found -

-
-
- -
- - -
-

- - - , - } - } - > - - - - Configure Heartbeat - - - - to start logging uptime data. - -

-
-
- - -
- -
- -
- -
- - - -`; - -exports[`EmptyState component renders child components when count is truthy 1`] = ` - -
- Foo -
-
- Bar -
-
- Baz -
-
-`; - -exports[`EmptyState component renders error message when an error occurs 1`] = ` - - - -
- -
- -
- -

- There was an error fetching your data. -

- - } - iconColor="subdued" - iconType="securityApp" - title={ - -

- Error -

-
- } - > -
- -
- - -
- - - - - -

- Error -

-
-
- -
- - -
-

- There was an error fetching your data. -

-
-
- - -
- -
- -
- -
- - - -`; - -exports[`EmptyState component renders loading state if no errors or doc count 1`] = ` - - - - - - -

- Loading… -

-
- - } - > -
- - - -
- - - - -
- - -

- Loading… -

-
-
- - - -
- - - -`; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/data_missing.test.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/data_missing.test.tsx deleted file mode 100644 index 8605d2966aaaec..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/data_missing.test.tsx +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { shallowWithIntl } from 'test_utils/enzyme_helpers'; -import React from 'react'; -import { DataMissing } from '../data_missing'; - -describe('DataMissing component', () => { - it('renders basePath and headingMessage', () => { - const component = shallowWithIntl(); - expect(component).toMatchSnapshot(); - }); -}); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/data_or_index_missing.test.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/data_or_index_missing.test.tsx new file mode 100644 index 00000000000000..333802962fd3e1 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/data_or_index_missing.test.tsx @@ -0,0 +1,24 @@ +/* + * 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 { shallowWithIntl } from 'test_utils/enzyme_helpers'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { DataOrIndexMissing } from '../data_or_index_missing'; + +describe('DataOrIndexMissing component', () => { + it('renders headingMessage', () => { + const headingMessage = ( + heartbeat-* }} + /> + ); + const component = shallowWithIntl(); + expect(component).toMatchSnapshot(); + }); +}); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/empty_state.test.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/empty_state.test.tsx index a74ad543c3318f..acfe2ada5b68d1 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/empty_state.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/empty_state.test.tsx @@ -5,11 +5,11 @@ */ import React from 'react'; -import { mountWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers'; import { EmptyStateComponent } from '../empty_state'; import { StatesIndexStatus } from '../../../../../common/runtime_types'; import { IHttpFetchError } from '../../../../../../../../../target/types/core/public/http'; import { HttpFetchError } from '../../../../../../../../../src/core/public/http/http_fetch_error'; +import { mountWithRouter, shallowWithRouter } from '../../../../lib'; describe('EmptyState component', () => { let statesIndexStatus: StatesIndexStatus; @@ -22,7 +22,7 @@ describe('EmptyState component', () => { }); it('renders child components when count is truthy', () => { - const component = shallowWithIntl( + const component = shallowWithRouter(
Foo
Bar
@@ -33,7 +33,7 @@ describe('EmptyState component', () => { }); it(`doesn't render child components when count is falsy`, () => { - const component = mountWithIntl( + const component = mountWithRouter(
Shouldn't be rendered
@@ -45,7 +45,7 @@ describe('EmptyState component', () => { const errors: IHttpFetchError[] = [ new HttpFetchError('There was an error fetching your data.', 'error', {} as any), ]; - const component = mountWithIntl( + const component = mountWithRouter(
Shouldn't appear...
@@ -54,7 +54,7 @@ describe('EmptyState component', () => { }); it('renders loading state if no errors or doc count', () => { - const component = mountWithIntl( + const component = mountWithRouter(
Should appear even while loading...
@@ -67,7 +67,7 @@ describe('EmptyState component', () => { docCount: 0, indexExists: true, }; - const component = mountWithIntl( + const component = mountWithRouter(
If this is in the snapshot the test should fail
@@ -77,7 +77,7 @@ describe('EmptyState component', () => { it('notifies when index does not exist', () => { statesIndexStatus.indexExists = false; - const component = mountWithIntl( + const component = mountWithRouter(
This text should not render
diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/data_missing.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/data_missing.tsx deleted file mode 100644 index e931ba5cce3f0a..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/data_missing.tsx +++ /dev/null @@ -1,64 +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 { - EuiFlexGroup, - EuiEmptyPrompt, - EuiFlexItem, - EuiSpacer, - EuiPanel, - EuiTitle, - EuiLink, -} from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; -import React, { useContext } from 'react'; -import { UptimeSettingsContext } from '../../../contexts'; - -interface DataMissingProps { - headingMessage: string; -} - -export const DataMissing = ({ headingMessage }: DataMissingProps) => { - const { basePath } = useContext(UptimeSettingsContext); - return ( - - - - - -

{headingMessage}

- - } - body={ -

- - - - ), - }} - /> -

- } - /> -
-
-
- ); -}; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/data_or_index_missing.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/data_or_index_missing.tsx new file mode 100644 index 00000000000000..88c0920138f682 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/data_or_index_missing.tsx @@ -0,0 +1,86 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiFlexGroup, + EuiEmptyPrompt, + EuiFlexItem, + EuiSpacer, + EuiPanel, + EuiTitle, + EuiButton, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import React, { useContext } from 'react'; +import { UptimeSettingsContext } from '../../../contexts'; +import { DynamicSettings } from '../../../../common/runtime_types'; + +interface DataMissingProps { + headingMessage: JSX.Element; + settings?: DynamicSettings; +} + +export const DataOrIndexMissing = ({ headingMessage, settings }: DataMissingProps) => { + const { basePath } = useContext(UptimeSettingsContext); + return ( + + + + + +

{headingMessage}

+ + } + body={ + <> +

+ +

+

+ +

+ + } + actions={ + + + + + + + + + + + + + } + /> +
+
+
+ ); +}; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/empty_index.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/empty_index.tsx deleted file mode 100644 index 13c1206fe5aed2..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/empty_index.tsx +++ /dev/null @@ -1,67 +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 { - EuiEmptyPrompt, - EuiFlexGroup, - EuiFlexItem, - EuiLink, - EuiPanel, - EuiSpacer, - EuiTitle, -} from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; -import React, { Fragment } from 'react'; - -interface EmptyIndexProps { - basePath: string; -} - -export const EmptyIndex = ({ basePath }: EmptyIndexProps) => ( - - - - - -

- -

- - } - body={ - -

- - - - ), - }} - /> -

-
- } - /> -
-
-
-); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/empty_state.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/empty_state.tsx index ae6a1b892bc991..651103a34bf212 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/empty_state.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/empty_state.tsx @@ -5,11 +5,11 @@ */ import React, { Fragment } from 'react'; -import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; import { EmptyStateError } from './empty_state_error'; import { EmptyStateLoading } from './empty_state_loading'; -import { DataMissing } from './data_missing'; -import { StatesIndexStatus } from '../../../../common/runtime_types'; +import { DataOrIndexMissing } from './data_or_index_missing'; +import { DynamicSettings, StatesIndexStatus } from '../../../../common/runtime_types'; import { IHttpFetchError } from '../../../../../../../../target/types/core/public/http'; interface EmptyStateProps { @@ -17,6 +17,7 @@ interface EmptyStateProps { statesIndexStatus: StatesIndexStatus | null; loading: boolean; errors?: IHttpFetchError[]; + settings?: DynamicSettings; } export const EmptyStateComponent = ({ @@ -24,6 +25,7 @@ export const EmptyStateComponent = ({ statesIndexStatus, loading, errors, + settings, }: EmptyStateProps) => { if (errors?.length) { return ; @@ -32,18 +34,28 @@ export const EmptyStateComponent = ({ const { indexExists, docCount } = statesIndexStatus; if (!indexExists) { return ( - {settings?.heartbeatIndices} }} + /> + } /> ); } else if (indexExists && docCount === 0) { return ( - {settings?.heartbeatIndices} }} + /> + } /> ); } 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 821a70c85dc7c5..49e6ddb56602ca 100644 --- a/x-pack/legacy/plugins/uptime/public/pages/page_header.tsx +++ b/x-pack/legacy/plugins/uptime/public/pages/page_header.tsx @@ -17,7 +17,9 @@ interface PageHeaderProps { extraLinks?: boolean; datePicker?: boolean; } - +const SETTINGS_LINK_TEXT = i18n.translate('xpack.uptime.page_header.settingsLink', { + defaultMessage: 'Settings', +}); export const PageHeader = React.memo( ({ headingText, extraLinks = false, datePicker = true }: PageHeaderProps) => { const datePickerComponent = datePicker ? ( @@ -26,9 +28,6 @@ export const PageHeader = React.memo( ) : null; - const settingsLinkText = i18n.translate('xpack.uptime.page_header.settingsLink', { - defaultMessage: 'Settings', - }); const extraLinkComponents = !extraLinks ? null : ( @@ -37,7 +36,7 @@ export const PageHeader = React.memo( - {settingsLinkText} + {SETTINGS_LINK_TEXT} diff --git a/x-pack/legacy/plugins/uptime/public/pages/settings.tsx b/x-pack/legacy/plugins/uptime/public/pages/settings.tsx index 765b0e3c664bc0..15b65bdea332bb 100644 --- a/x-pack/legacy/plugins/uptime/public/pages/settings.tsx +++ b/x-pack/legacy/plugins/uptime/public/pages/settings.tsx @@ -57,8 +57,8 @@ export const SettingsPageComponent = ({ useUptimeTelemetry(UptimePage.Settings); useEffect(() => { - dispatchGetDynamicSettings({}); - }, [dispatchGetDynamicSettings]); + dispatch(getDynamicSettings()); + }, [dispatch]); const [formFields, setFormFields] = useState(dss.settings || null); diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/dynamic_settings.ts b/x-pack/legacy/plugins/uptime/public/state/actions/dynamic_settings.ts index d78c725c4b599d..3dbb1aa2346216 100644 --- a/x-pack/legacy/plugins/uptime/public/state/actions/dynamic_settings.ts +++ b/x-pack/legacy/plugins/uptime/public/state/actions/dynamic_settings.ts @@ -6,7 +6,7 @@ import { createAction } from 'redux-actions'; import { DynamicSettings } from '../../../common/runtime_types'; -export const getDynamicSettings = createAction<{}>('GET_DYNAMIC_SETTINGS'); +export const getDynamicSettings = createAction('GET_DYNAMIC_SETTINGS'); export const getDynamicSettingsSuccess = createAction( 'GET_DYNAMIC_SETTINGS_SUCCESS' ); @@ -17,4 +17,3 @@ export const setDynamicSettingsSuccess = createAction( 'SET_DYNAMIC_SETTINGS_SUCCESS' ); export const setDynamicSettingsFail = createAction('SET_DYNAMIC_SETTINGS_FAIL'); -export const acknowledgeSetDynamicSettings = createAction<{}>('ACKNOWLEDGE_SET_DYNAMIC_SETTINGS'); diff --git a/x-pack/legacy/plugins/uptime/public/state/api/dynamic_settings.ts b/x-pack/legacy/plugins/uptime/public/state/api/dynamic_settings.ts index 8ade2aa4595dcd..e52e40c53513cb 100644 --- a/x-pack/legacy/plugins/uptime/public/state/api/dynamic_settings.ts +++ b/x-pack/legacy/plugins/uptime/public/state/api/dynamic_settings.ts @@ -14,22 +14,15 @@ import { apiService } from './utils'; const apiPath = '/api/uptime/dynamic_settings'; -interface BaseApiRequest { - basePath: string; -} - -type SaveApiRequest = BaseApiRequest & { +interface SaveApiRequest { settings: DynamicSettings; -}; +} -export const getDynamicSettings = async ({ - basePath, -}: BaseApiRequest): Promise => { +export const getDynamicSettings = async (): Promise => { return await apiService.get(apiPath, undefined, DynamicSettingsType); }; export const setDynamicSettings = async ({ - basePath, settings, }: SaveApiRequest): Promise => { return await apiService.post(apiPath, settings, DynamicSettingsSaveType); diff --git a/x-pack/legacy/plugins/uptime/public/state/effects/dynamic_settings.ts b/x-pack/legacy/plugins/uptime/public/state/effects/dynamic_settings.ts index 9bc8bd95be68c6..bee92813aa1f0a 100644 --- a/x-pack/legacy/plugins/uptime/public/state/effects/dynamic_settings.ts +++ b/x-pack/legacy/plugins/uptime/public/state/effects/dynamic_settings.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { takeLatest, put, call, select } from 'redux-saga/effects'; +import { takeLatest, put, call } from 'redux-saga/effects'; import { Action } from 'redux-actions'; import { i18n } from '@kbn/i18n'; import { fetchEffectFactory } from './fetch_effect'; @@ -21,7 +21,6 @@ import { setDynamicSettings as setDynamicSettingsAPI, } from '../api'; import { DynamicSettings } from '../../../common/runtime_types'; -import { getBasePath } from '../selectors'; import { kibanaService } from '../kibana_service'; export function* fetchDynamicSettingsEffect() { @@ -46,8 +45,7 @@ export function* setDynamicSettingsEffect() { }); return; } - const basePath = yield select(getBasePath); - yield call(setDynamicSettingsAPI, { settings: action.payload, basePath }); + yield call(setDynamicSettingsAPI, { settings: action.payload }); yield put(setDynamicSettingsSuccess(action.payload)); kibanaService.core.notifications.toasts.addSuccess('Settings saved!'); } catch (err) { diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 7f5bd0eda809b3..41820305ee308f 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -16253,12 +16253,7 @@ "xpack.uptime.dataMissing.configureHeartbeatToGetStartedMessage": "アップタイムデータのロギングを開始するには{configureHeartbeatLink}。", "xpack.uptime.durationChart.emptyPrompt.description": "このモニターは選択された時間範囲で一度も {emphasizedText} していません。", "xpack.uptime.durationChart.emptyPrompt.title": "利用可能な期間データがありません", - "xpack.uptime.emptyState.configureHeartbeatLinkText": "Heartbeat を構成", - "xpack.uptime.emptyState.configureHeartbeatToGetStartedMessage": "アップタイムデータの収集を開始するには {configureHeartbeatLink}。", "xpack.uptime.emptyState.loadingMessage": "読み込み中…", - "xpack.uptime.emptyState.noDataMessage": "アップタイムデータが見つかりませんでした", - "xpack.uptime.emptyState.noDataTitle": "利用可能なアップタイムデータがありません", - "xpack.uptime.emptyState.noIndexTitle": "アップタイムインデックスが見つかりません", "xpack.uptime.emptyStateError.notAuthorized": "アップタイムデータの表示が承認されていません。システム管理者にお問い合わせください。", "xpack.uptime.emptyStateError.notFoundPage": "ページが見つかりません", "xpack.uptime.emptyStateError.title": "エラー", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 6fc2e1f146086a..68e4f62f1f2ce4 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -16258,12 +16258,7 @@ "xpack.uptime.dataMissing.configureHeartbeatToGetStartedMessage": "{configureHeartbeatLink}以开始记录运行时间数据。", "xpack.uptime.durationChart.emptyPrompt.description": "在选定时间范围内此监测从未{emphasizedText}。", "xpack.uptime.durationChart.emptyPrompt.title": "没有持续时间数据", - "xpack.uptime.emptyState.configureHeartbeatLinkText": "配置 Heartbeat", - "xpack.uptime.emptyState.configureHeartbeatToGetStartedMessage": "{configureHeartbeatLink}以开始收集运行时间数据。", "xpack.uptime.emptyState.loadingMessage": "正在加载……", - "xpack.uptime.emptyState.noDataMessage": "未找到任何运行时间数据", - "xpack.uptime.emptyState.noDataTitle": "没有可用的运行时间数据", - "xpack.uptime.emptyState.noIndexTitle": "找不到运行时间索引", "xpack.uptime.emptyStateError.notAuthorized": "您无权查看 Uptime 数据,请联系系统管理员。", "xpack.uptime.emptyStateError.notFoundPage": "未找到页面", "xpack.uptime.emptyStateError.title": "错误", From a95789d0d3c2436df795ed4993525f4bbcd9cc63 Mon Sep 17 00:00:00 2001 From: shahzad Date: Wed, 22 Apr 2020 13:41:02 +0200 Subject: [PATCH 3/5] updated snapshots --- .../__snapshots__/empty_state.test.tsx.snap | 1627 +++++++++++++++++ 1 file changed, 1627 insertions(+) create mode 100644 x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap new file mode 100644 index 00000000000000..d0e7af24e1c1b9 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap @@ -0,0 +1,1627 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EmptyState component does not render empty state with appropriate base path and no docs 1`] = ` + + + , + } + } + /> + } + > + +
+ +
+ +
+ + +
+ + + + + + + + + + + + + } + body={ + +

+ +

+

+ +

+
+ } + iconType="logoUptime" + title={ + +

+ , + } + } + /> +

+
+ } + > +
+ +
+ + +
+ + + + + +

+ , + } + } + > + No uptime data found in index + + +

+
+
+ +
+ + +
+

+ + If you have not setup heartbeat yet, you can setup heartbeat to start monitoring your services. + +

+

+ + If you have setup heartbeat and confirmed data is being sent to Elasticsearch, update your index pattern settings and insure they are aligned with your Heartbeat config. + +

+
+
+ + + + + +
+ +
+ + + + +`; + +exports[`EmptyState component doesn't render child components when count is falsy 1`] = ` + + + + + + + +

+ Loading… +

+
+ + } + > +
+ + + +
+ + + + +
+ + +

+ Loading… +

+
+
+ + + +
+ + + + +`; + +exports[`EmptyState component notifies when index does not exist 1`] = ` + + + , + } + } + /> + } + > + +
+ +
+ +
+ + +
+ + + + + + + + + + + + + } + body={ + +

+ +

+

+ +

+
+ } + iconType="logoUptime" + title={ + +

+ , + } + } + /> +

+
+ } + > +
+ +
+ + +
+ + + + + +

+ , + } + } + > + No indices found matching pattern + + +

+
+
+ +
+ + +
+

+ + If you have not setup heartbeat yet, you can setup heartbeat to start monitoring your services. + +

+

+ + If you have setup heartbeat and confirmed data is being sent to Elasticsearch, update your index pattern settings and insure they are aligned with your Heartbeat config. + +

+
+
+ + + + + +
+ +
+ + + + +`; + +exports[`EmptyState component renders child components when count is truthy 1`] = ` + + +
+ Foo +
+
+ Bar +
+
+ Baz +
+
+
+`; + +exports[`EmptyState component renders error message when an error occurs 1`] = ` + + + + +
+ +
+ +
+ +

+ There was an error fetching your data. +

+ + } + iconColor="subdued" + iconType="securityApp" + title={ + +

+ Error +

+
+ } + > +
+ +
+ + +
+ + + + + +

+ Error +

+
+
+ +
+ + +
+

+ There was an error fetching your data. +

+
+
+ + +
+ +
+ +
+ +
+ + + + +`; + +exports[`EmptyState component renders loading state if no errors or doc count 1`] = ` + + + + + + + +

+ Loading… +

+
+ + } + > +
+ + + +
+ + + + +
+ + +

+ Loading… +

+
+
+ + + +
+ + + + +`; From dc2839f7c547b3edf2fd678b014189b2d82433d7 Mon Sep 17 00:00:00 2001 From: shahzad Date: Wed, 22 Apr 2020 18:10:34 +0200 Subject: [PATCH 4/5] up snapshots --- .../uptime/server/lib/alerts/__tests__/status_check.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/uptime/server/lib/alerts/__tests__/status_check.test.ts b/x-pack/plugins/uptime/server/lib/alerts/__tests__/status_check.test.ts index f94b3f7545fb30..55c8a69df6c4c2 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/__tests__/status_check.test.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/__tests__/status_check.test.ts @@ -88,11 +88,11 @@ describe('status check alert', () => { Object { "callES": [MockFunction], "dynamicSettings": Object { - "heartbeatIndices": "heartbeat-7*", "certificatesThresholds": Object { "errorState": 7, "warningState": 30, }, + "heartbeatIndices": "heartbeat-7*", }, "locations": Array [], "numTimes": 5, @@ -135,11 +135,11 @@ describe('status check alert', () => { Object { "callES": [MockFunction], "dynamicSettings": Object { - "heartbeatIndices": "heartbeat-7*", "certificatesThresholds": Object { "errorState": 7, "warningState": 30, }, + "heartbeatIndices": "heartbeat-7*", }, "locations": Array [], "numTimes": 5, From 23e1ac3c4e235e5369b6129b743685c070aa9ef1 Mon Sep 17 00:00:00 2001 From: shahzad Date: Thu, 23 Apr 2020 19:12:46 +0200 Subject: [PATCH 5/5] update trans --- x-pack/plugins/translations/translations/ja-JP.json | 1 - x-pack/plugins/translations/translations/zh-CN.json | 1 - 2 files changed, 2 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 29dba3667c5d68..b86025780b1377 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -16234,7 +16234,6 @@ "xpack.uptime.charts.mlAnnotation.header": "スコア: {score}", "xpack.uptime.charts.mlAnnotation.severity": "深刻度: {severity}", "xpack.uptime.components.embeddables.embeddedMap.embeddablePanelTitle": "オブザーバー位置情報マップを監視", - "xpack.uptime.dataMissing.configureHeartbeatToGetStartedMessage": "アップタイムデータのロギングを開始するには{configureHeartbeatLink}。", "xpack.uptime.durationChart.emptyPrompt.description": "このモニターは選択された時間範囲で一度も {emphasizedText} していません。", "xpack.uptime.durationChart.emptyPrompt.title": "利用可能な期間データがありません", "xpack.uptime.emptyState.loadingMessage": "読み込み中…", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index e1eb9ef4c5f97b..7164bbc10689bf 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -16239,7 +16239,6 @@ "xpack.uptime.charts.mlAnnotation.header": "分数:{score}", "xpack.uptime.charts.mlAnnotation.severity": "严重性:{severity}", "xpack.uptime.components.embeddables.embeddedMap.embeddablePanelTitle": "监测观察者位置地图", - "xpack.uptime.dataMissing.configureHeartbeatToGetStartedMessage": "{configureHeartbeatLink}以开始记录运行时间数据。", "xpack.uptime.durationChart.emptyPrompt.description": "在选定时间范围内此监测从未{emphasizedText}。", "xpack.uptime.durationChart.emptyPrompt.title": "没有持续时间数据", "xpack.uptime.emptyState.loadingMessage": "正在加载……",