[Uptime] Fix uptime amsterdam UI issues (#103683)

* Uptime - update monitor type format in StatusBar and update UI for define connectors switch

* update define_connectors

* Resolve type error.

* Add tests for `renderMonitorType`.

* remove unnecessary async specifier

* update i18n

* remove unused imports

* update i18n

Co-authored-by: Justin Kambic <justin.kambic@elastic.co>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Dominique Clarke 2021-07-01 15:58:52 -04:00 committed by GitHub
parent 9e60da5b46
commit b7dc2c1d8c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 231 additions and 83 deletions

View file

@ -23592,7 +23592,6 @@
"xpack.uptime.monitorDetails.title.pingType.icmp": "ICMP ping",
"xpack.uptime.monitorDetails.title.pingType.tcp": "TCP ping",
"xpack.uptime.monitorList.anomalyColumn.label": "レスポンス異常スコア",
"xpack.uptime.monitorList.defineConnector.description": "アラートを有効にするには、デフォルトのアラートアクションコネクターを定義してください。",
"xpack.uptime.monitorList.downLineSeries.downLabel": "ダウン",
"xpack.uptime.monitorList.drawer.missingLocation": "一部の Heartbeat インスタンスには位置情報が定義されていません。Heartbeat 構成への{link}。",
"xpack.uptime.monitorList.drawer.mostRecentRun": "直近のテスト実行",
@ -24216,4 +24215,4 @@
"xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "フィールドを選択してください。",
"xpack.watcher.watcherDescription": "アラートの作成、管理、監視によりデータへの変更を検知します。"
}
}
}

View file

@ -23960,7 +23960,6 @@
"xpack.uptime.monitorDetails.title.pingType.icmp": "ICMP ping",
"xpack.uptime.monitorDetails.title.pingType.tcp": "TCP ping",
"xpack.uptime.monitorList.anomalyColumn.label": "响应异常分数",
"xpack.uptime.monitorList.defineConnector.description": "要开始启用告警,请在以下位置定义默认告警操作连接器",
"xpack.uptime.monitorList.downLineSeries.downLabel": "关闭检查",
"xpack.uptime.monitorList.drawer.missingLocation": "某些 Heartbeat 实例未定义位置。{link}到您的 Heartbeat 配置。",
"xpack.uptime.monitorList.drawer.mostRecentRun": "最新测试运行",
@ -24594,4 +24593,4 @@
"xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "此字段必填。",
"xpack.watcher.watcherDescription": "通过创建、管理和监测警报来检测数据中的更改。"
}
}
}

View file

@ -89,17 +89,9 @@ export const MonitorPageTitle: React.FC = () => {
return (
<>
<EuiFlexGroup wrap={false} data-test-subj="monitorTitle">
<EuiFlexItem grow={false}>
<EuiTitle>
<h1 className="eui-textNoWrap">{nameOrId}</h1>
</EuiTitle>
<EuiSpacer size="xs" />
</EuiFlexItem>
<EuiFlexItem grow={false} style={{ justifyContent: 'center' }}>
<EnableMonitorAlert monitorId={monitorId} selectedMonitor={selectedMonitor!} />
</EuiFlexItem>
</EuiFlexGroup>
<EuiTitle>
<h1 className="eui-textNoWrap">{nameOrId}</h1>
</EuiTitle>
<EuiSpacer size="s" />
<EuiFlexGroup wrap={false} gutterSize="s" alignItems="center">
<EuiFlexItem grow={false}>
@ -126,6 +118,7 @@ export const MonitorPageTitle: React.FC = () => {
</EuiFlexItem>
)}
</EuiFlexGroup>
<EnableMonitorAlert monitorId={monitorId} selectedMonitor={selectedMonitor!} />
</>
);
};

View file

@ -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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { renderMonitorType } from './status_bar';
describe('StatusBar component', () => {
describe('renderMonitorType', () => {
it('handles http type', () => {
expect(renderMonitorType('http')).toBe('HTTP');
});
it('handles tcp type', () => {
expect(renderMonitorType('tcp')).toBe('TCP');
});
it('handles icmp type', () => {
expect(renderMonitorType('icmp')).toBe('ICMP');
});
it('handles browser type', () => {
expect(renderMonitorType('browser')).toBe('Browser');
});
it('returns empty string for `undefined`', () => {
expect(renderMonitorType(undefined)).toBe('');
});
});
});

View file

@ -15,6 +15,7 @@ import {
EuiDescriptionListDescription,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import { MonitorSSLCertificate } from './ssl_certificate';
import * as labels from '../translations';
import { StatusByLocations } from './status_by_location';
@ -40,6 +41,29 @@ export const MonListDescription = styled(EuiDescriptionListDescription)`
}
`;
export const renderMonitorType = (type: string | undefined) => {
switch (type) {
case 'http':
return i18n.translate('xpack.uptime.monitorDetails.statusBar.pingType.http', {
defaultMessage: 'HTTP',
});
case 'tcp':
return i18n.translate('xpack.uptime.monitorDetails.statusBar.pingType.tcp', {
defaultMessage: 'TCP',
});
case 'icmp':
return i18n.translate('xpack.uptime.monitorDetails.statusBar.pingType.icmp', {
defaultMessage: 'ICMP',
});
case 'browser':
return i18n.translate('xpack.uptime.monitorDetails.statusBar.pingType.browser', {
defaultMessage: 'Browser',
});
default:
return '';
}
};
export const MonitorStatusBar: React.FC = () => {
const { monitorId, monitorStatus, monitorLocations = {} } = useStatusBar();
@ -77,7 +101,7 @@ export const MonitorStatusBar: React.FC = () => {
<>
<MonListTitle aria-label={labels.typeAriaLabel}>{labels.typeLabel}</MonListTitle>
<MonListDescription data-test-subj="monitor-page-type">
{monitorStatus.monitor.type}
{renderMonitorType(monitorStatus?.monitor?.type)}
</MonListDescription>
</>
)}

View file

@ -1299,28 +1299,37 @@ exports[`MonitorList component renders the monitor list 1`] = `
class="euiPopover__anchor"
>
<div
class="euiSwitch euiSwitch--compressed"
class="euiFormRow"
id="generated-id-row"
>
<button
aria-checked="false"
aria-label="Enable rule"
class="euiSwitch__button"
data-test-subj="uptimeDisplayDefineConnector"
id="defineAlertSettingsSwitch"
role="switch"
type="button"
<div
class="euiFormRow__fieldWrapper"
>
<span
class="euiSwitch__body"
<div
class="euiSwitch euiSwitch--compressed"
>
<span
class="euiSwitch__thumb"
/>
<span
class="euiSwitch__track"
/>
</span>
</button>
<button
aria-checked="false"
aria-label="Enable status alerts"
class="euiSwitch__button"
data-test-subj="uptimeDisplayDefineConnector"
id="generated-id"
role="switch"
type="button"
>
<span
class="euiSwitch__body"
>
<span
class="euiSwitch__thumb"
/>
<span
class="euiSwitch__track"
/>
</span>
</button>
</div>
</div>
</div>
</div>
</div>
@ -1552,28 +1561,37 @@ exports[`MonitorList component renders the monitor list 1`] = `
class="euiPopover__anchor"
>
<div
class="euiSwitch euiSwitch--compressed"
class="euiFormRow"
id="generated-id-row"
>
<button
aria-checked="false"
aria-label="Enable rule"
class="euiSwitch__button"
data-test-subj="uptimeDisplayDefineConnector"
id="defineAlertSettingsSwitch"
role="switch"
type="button"
<div
class="euiFormRow__fieldWrapper"
>
<span
class="euiSwitch__body"
<div
class="euiSwitch euiSwitch--compressed"
>
<span
class="euiSwitch__thumb"
/>
<span
class="euiSwitch__track"
/>
</span>
</button>
<button
aria-checked="false"
aria-label="Enable status alerts"
class="euiSwitch__button"
data-test-subj="uptimeDisplayDefineConnector"
id="generated-id"
role="switch"
type="button"
>
<span
class="euiSwitch__body"
>
<span
class="euiSwitch__thumb"
/>
<span
class="euiSwitch__track"
/>
</span>
</button>
</div>
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,44 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { DefineAlertConnectors } from './define_connectors';
import { screen } from '@testing-library/react';
import { fireEvent } from '@testing-library/dom';
import { ENABLE_STATUS_ALERT } from './translations';
import { render } from '../../../../lib/helper/rtl_helpers';
describe('EnableAlertComponent', () => {
it('does not showHelpText or render popover when showHelpText and renderPopOver are false', () => {
render(<DefineAlertConnectors />);
expect(screen.getByTestId('uptimeDisplayDefineConnector')).toBeInTheDocument();
expect(screen.queryByText(ENABLE_STATUS_ALERT)).not.toBeInTheDocument();
expect(screen.queryByText(/Define a default connector/)).not.toBeInTheDocument();
fireEvent.click(screen.getByTestId('uptimeDisplayDefineConnector'));
expect(screen.queryByTestId('uptimeSettingsDefineConnector')).not.toBeInTheDocument();
});
it('shows label when showLabel is true', () => {
render(<DefineAlertConnectors showLabel />);
expect(screen.getByText(ENABLE_STATUS_ALERT)).toBeInTheDocument();
});
it('shows helpText when showHelpText is true', () => {
render(<DefineAlertConnectors showHelpText />);
expect(screen.getByText(/Define a default connector/)).toBeInTheDocument();
});
it('renders popover on click when showPopover is true', () => {
render(<DefineAlertConnectors showPopover />);
fireEvent.click(screen.getByTestId('uptimeDisplayDefineConnector'));
expect(screen.getByTestId('uptimeSettingsDefineConnector')).toBeInTheDocument();
});
});

View file

@ -6,41 +6,72 @@
*/
import React, { useState } from 'react';
import { EuiPopover, EuiSwitch, EuiText } from '@elastic/eui';
import { useRouteMatch } from 'react-router-dom';
import { i18n } from '@kbn/i18n';
import { EuiSwitch, EuiPopover, EuiText, EuiFormRow } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { ReactRouterEuiLink } from '../../../common/react_router_helpers';
import { MONITOR_ROUTE, SETTINGS_ROUTE } from '../../../../../common/constants';
import { SETTINGS_ROUTE } from '../../../../../common/constants';
import { ENABLE_STATUS_ALERT } from './translations';
const SETTINGS_LINK_TEXT = i18n.translate('xpack.uptime.page_header.defineConnector', {
defaultMessage: 'Define a default connector',
});
interface Props {
showPopover?: boolean;
showHelpText?: boolean;
showLabel?: boolean;
}
export const DefineAlertConnectors = () => {
export const DefineAlertConnectors = ({
showPopover = false,
showHelpText = false,
showLabel = false,
}: Props) => {
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const onButtonClick = () => setIsPopoverOpen((val) => !val);
const closePopover = () => setIsPopoverOpen(false);
const isMonitorPage = useRouteMatch(MONITOR_ROUTE);
return (
<EuiPopover
button={
<EuiSwitch
id={'defineAlertSettingsSwitch'}
label={ENABLE_STATUS_ALERT}
showLabel={!!isMonitorPage}
aria-label={ENABLE_STATUS_ALERT}
onChange={onButtonClick}
checked={false}
compressed={!isMonitorPage}
data-test-subj={'uptimeDisplayDefineConnector'}
/>
<>
<EuiFormRow
helpText={
showHelpText ? (
<FormattedMessage
id="xpack.uptime.monitorList.defineConnector.description"
defaultMessage="Define a default connector in {link} to enable monitor status alerts."
values={{
link: (
<ReactRouterEuiLink
to={SETTINGS_ROUTE + '?focusConnectorField=true'}
data-test-subj={'uptimeSettingsLink'}
target="_blank"
>
<FormattedMessage
id="xpack.uptime.page_header.defineConnector.settingsLink"
defaultMessage="Settings"
/>
</ReactRouterEuiLink>
),
}}
/>
) : undefined
}
>
<EuiSwitch
id={'defineAlertSettingsSwitch'}
label={ENABLE_STATUS_ALERT}
showLabel={showLabel}
aria-label={ENABLE_STATUS_ALERT}
// this switch is read only, no onChange applied
onChange={showPopover ? onButtonClick : () => {}}
checked={false}
compressed={true}
disabled={!showPopover}
data-test-subj={'uptimeDisplayDefineConnector'}
/>
</EuiFormRow>
</>
}
isOpen={isPopoverOpen}
isOpen={showPopover ? isPopoverOpen : false}
closePopover={closePopover}
>
<EuiText style={{ width: '350px' }} data-test-subj={'uptimeSettingsDefineConnector'}>
@ -48,10 +79,13 @@ export const DefineAlertConnectors = () => {
to={SETTINGS_ROUTE + '?focusConnectorField=true'}
data-test-subj={'uptimeSettingsLink'}
>
{SETTINGS_LINK_TEXT}
<FormattedMessage
id="xpack.uptime.page_header.defineConnector.popover.defaultLink"
defaultMessage="Define a default connector"
/>
</ReactRouterEuiLink>{' '}
<FormattedMessage
id="xpack.uptime.monitorList.defineConnector.description"
id="xpack.uptime.monitorList.defineConnector.popover.description"
defaultMessage="to receive status alerts."
/>
</EuiText>

View file

@ -18,7 +18,7 @@ import { AlertsResult } from '../../../../state/actions/types';
describe('EnableAlertComponent', () => {
it('it displays define connectors when there is none', () => {
const { getByTestId, getByLabelText, getByText } = render(
const { getByTestId, getByLabelText, getByText, getByRole } = render(
<EnableMonitorAlert
monitorId={'testMonitor'}
selectedMonitor={makePing({ name: 'My website' })}
@ -29,11 +29,12 @@ describe('EnableAlertComponent', () => {
fireEvent.click(getByTestId('uptimeDisplayDefineConnector'));
expect(getByTestId('uptimeSettingsLink')).toHaveAttribute(
expect(getByRole('link', { name: 'Define a default connector' })).toHaveAttribute(
'href',
'/settings?focusConnectorField=true'
);
expect(getByText('to receive status alerts.'));
expect(getByText(/Define a default connector/));
expect(getByText(/to receive status alerts./));
});
it('does not displays define connectors when there is connector', () => {

View file

@ -125,6 +125,10 @@ export const EnableMonitorAlert = ({ monitorId, selectedMonitor }: Props) => {
</EuiToolTip>
</div>
) : (
<DefineAlertConnectors />
<DefineAlertConnectors
showPopover={!isMonitorPage}
showHelpText={!!isMonitorPage}
showLabel={!!isMonitorPage}
/>
);
};

View file

@ -8,11 +8,11 @@
import { i18n } from '@kbn/i18n';
export const ENABLE_STATUS_ALERT = i18n.translate('xpack.uptime.monitorList.enableDownAlert', {
defaultMessage: 'Enable rule',
defaultMessage: 'Enable status alerts',
});
export const DISABLE_STATUS_ALERT = i18n.translate('xpack.uptime.monitorList.disableDownAlert', {
defaultMessage: 'Disable rule',
defaultMessage: 'Disable status alerts',
});
export const EXPAND_TAGS_LABEL = i18n.translate('xpack.uptime.monitorList.tags.expand', {