[Security-Solution] Adds warning message for selected ML jobs not running, adds tooltip to combobox (#97764)

* [Security-Solution] Adds warning message for selected ML jobs not running, adds tooltip to combobox

* updates i18n

* update strings

* updates strings

* fixes i18n error
This commit is contained in:
Ece Özalp 2021-04-20 23:08:02 -04:00 committed by GitHub
parent 15ae3c0cd6
commit e39b8c6d36
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 115 additions and 59 deletions

View file

@ -0,0 +1,22 @@
/*
* 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 { shallow } from 'enzyme';
import { HelpText } from './help_text';
describe('MlJobSelect help text', () => {
it('does not show warning if all jobs are running', () => {
const wrapper = shallow(<HelpText href={'https://test.com'} notRunningJobIds={[]} />);
expect(wrapper.find('[data-test-subj="ml-warning-not-running-jobs"]')).toHaveLength(0);
});
it('shows warning if there are jobs not running', () => {
const wrapper = shallow(<HelpText href={'https://test.com'} notRunningJobIds={['id']} />);
expect(wrapper.find('[data-test-subj="ml-warning-not-running-jobs"]')).toHaveLength(1);
});
});

View file

@ -0,0 +1,68 @@
/*
* 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 { EuiIcon, EuiLink, EuiText } from '@elastic/eui';
import styled from 'styled-components';
import { FormattedMessage } from '@kbn/i18n/react';
const HelpTextWarningContainer = styled.div`
margin-top: 10px;
`;
const HelpTextComponent: React.FC<{ href: string; notRunningJobIds: string[] }> = ({
href,
notRunningJobIds,
}) => (
<>
<FormattedMessage
id="xpack.securitySolution.detectionEngine.createRule.stepDefineRule.machineLearningJobIdHelpText"
defaultMessage="We've provided a few common jobs to get you started. To add your own custom jobs, assign a group of 'security' to those jobs in the {machineLearning} application to make them appear here."
values={{
machineLearning: (
<EuiLink href={href} target="_blank">
<FormattedMessage
id="xpack.securitySolution.components.mlJobSelect.machineLearningLink"
defaultMessage="Machine Learning"
/>
</EuiLink>
),
}}
/>
{notRunningJobIds.length > 0 && (
<HelpTextWarningContainer data-test-subj="ml-warning-not-running-jobs">
<EuiText size="xs" color="warning">
<EuiIcon type="alert" />
<span>
{notRunningJobIds.length === 1 ? (
<FormattedMessage
id="xpack.securitySolution.detectionEngine.createRule.stepDefineRule.mlEnableJobSingle"
defaultMessage="The selected ML job, {jobName}, is not currently running. Please set {jobName} to run via 'ML job settings' before activating this rule."
values={{
jobName: notRunningJobIds[0],
}}
/>
) : (
<FormattedMessage
id="xpack.securitySolution.detectionEngine.createRule.stepDefineRule.mlEnableJobMulti"
defaultMessage="The selected ML jobs, {jobNames}, are not currently running. Please set all of these jobs to run via 'ML job settings' before activating this rule."
values={{
jobNames: notRunningJobIds.reduce(
(acc, value, i, array) => acc + (i < array.length - 1 ? ', ' : ', and ') + value
),
}}
/>
)}
</span>
</EuiText>
</HelpTextWarningContainer>
)}
</>
);
export const HelpText = React.memo(HelpTextComponent);

View file

@ -6,15 +6,13 @@
*/
import React, { useCallback, useMemo } from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import {
EuiComboBox,
EuiComboBoxOptionOption,
EuiFlexGroup,
EuiFlexItem,
EuiFormRow,
EuiIcon,
EuiLink,
EuiToolTip,
EuiText,
} from '@elastic/eui';
@ -23,63 +21,36 @@ import { isJobStarted } from '../../../../../common/machine_learning/helpers';
import { FieldHook, getFieldValidityAndErrorMessage } from '../../../../shared_imports';
import { useSecurityJobs } from '../../../../common/components/ml_popover/hooks/use_security_jobs';
import { useKibana } from '../../../../common/lib/kibana';
import {
ML_JOB_SELECT_PLACEHOLDER_TEXT,
ENABLE_ML_JOB_WARNING,
} from '../step_define_rule/translations';
import { ML_JOB_SELECT_PLACEHOLDER_TEXT } from '../step_define_rule/translations';
import { HelpText } from './help_text';
interface MlJobValue {
id: string;
description: string;
}
type MlJobOption = EuiComboBoxOptionOption<MlJobValue>;
const HelpTextWarningContainer = styled.div`
margin-top: 10px;
const JobDisplayContainer = styled.div`
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
`;
type MlJobOption = EuiComboBoxOptionOption<MlJobValue>;
const MlJobSelectEuiFlexGroup = styled(EuiFlexGroup)`
margin-bottom: 5px;
`;
const HelpText: React.FC<{ href: string; showEnableWarning: boolean }> = ({
href,
showEnableWarning = false,
}) => (
<>
<FormattedMessage
id="xpack.securitySolution.detectionEngine.createRule.stepDefineRule.machineLearningJobIdHelpText"
defaultMessage="We've provided a few common jobs to get you started. To add your own custom jobs, assign a group of “security” to those jobs in the {machineLearning} application to make them appear here."
values={{
machineLearning: (
<EuiLink href={href} target="_blank">
<FormattedMessage
id="xpack.securitySolution.components.mlJobSelect.machineLearningLink"
defaultMessage="Machine Learning"
/>
</EuiLink>
),
}}
/>
{showEnableWarning && (
<HelpTextWarningContainer>
<EuiText size="xs" color="warning">
<EuiIcon type="alert" />
<span>{ENABLE_ML_JOB_WARNING}</span>
</EuiText>
</HelpTextWarningContainer>
)}
</>
);
const JobDisplay: React.FC<MlJobValue> = ({ id, description }) => (
<>
<JobDisplayContainer>
<strong>{id}</strong>
<EuiText size="xs" color="subdued">
<p>{description}</p>
</EuiText>
</>
<EuiToolTip content={description}>
<EuiText size="xs" color="subdued">
<p>{description}</p>
</EuiText>
</EuiToolTip>
</JobDisplayContainer>
);
interface MlJobSelectProps {
@ -114,9 +85,14 @@ export const MlJobSelect: React.FC<MlJobSelectProps> = ({ describedByIds = [], f
const selectedJobOptions = jobOptions.filter((option) => jobIds.includes(option.value.id));
const allJobsRunning = useMemo(() => {
const notRunningJobIds = useMemo<string[]>(() => {
const selectedJobs = jobs.filter(({ id }) => jobIds.includes(id));
return selectedJobs.every((job) => isJobStarted(job.jobState, job.datafeedState));
return selectedJobs.reduce((acc, job) => {
if (!isJobStarted(job.jobState, job.datafeedState)) {
acc.push(job.id);
}
return acc;
}, [] as string[]);
}, [jobs, jobIds]);
return (
@ -124,7 +100,7 @@ export const MlJobSelect: React.FC<MlJobSelectProps> = ({ describedByIds = [], f
<EuiFlexItem>
<EuiFormRow
label={field.label}
helpText={<HelpText href={mlUrl} showEnableWarning={!allJobsRunning} />}
helpText={<HelpText href={mlUrl} notRunningJobIds={notRunningJobIds} />}
isInvalid={isInvalid}
error={errorMessage}
data-test-subj="mlJobSelect"

View file

@ -64,14 +64,6 @@ export const ML_JOB_SELECT_PLACEHOLDER_TEXT = i18n.translate(
}
);
export const ENABLE_ML_JOB_WARNING = i18n.translate(
'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.mlEnableJobWarningTitle',
{
defaultMessage:
'One or more selected ML jobs are not currently running. Please set these job(s) to run via "ML job settings" before activating this rule.',
}
);
export const QUERY_BAR_LABEL = i18n.translate(
'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.fieldQuerBarLabel',
{

View file

@ -18327,7 +18327,6 @@
"xpack.securitySolution.detectionEngine.createRule.stepDefineRule.indicesHelperDescription": "このルールを実行するElasticsearchインデックスのパターンを入力します。デフォルトでは、セキュリティソリューション詳細設定で定義されたインデックスパターンが含まれます。",
"xpack.securitySolution.detectionEngine.createRule.stepDefineRule.machineLearningJobIdHelpText": "手始めに使えるように、一般的なジョブがいくつか提供されています。独自のカスタムジョブを追加するには、{machineLearning} アプリケーションでジョブに「security」のグループを割り当て、ここに表示されるようにします。",
"xpack.securitySolution.detectionEngine.createRule.stepDefineRule.machineLearningJobIdRequired": "機械学習ジョブが必要です。",
"xpack.securitySolution.detectionEngine.createRule.stepDefineRule.mlEnableJobWarningTitle": "このMLジョブは現在実行されていません。このルールを有効にする前に、このジョブを「MLジョブ設定」で実行するように設定してください。",
"xpack.securitySolution.detectionEngine.createRule.stepDefineRule.mlJobSelectPlaceholderText": "ジョブを選択してください",
"xpack.securitySolution.detectionEngine.createRule.stepDefineRule.outputIndiceNameFieldRequiredError": "インデックスパターンが最低1つ必要です。",
"xpack.securitySolution.detectionEngine.createRule.stepDefineRule.referencesUrlInvalidError": "URLの形式が無効です",

View file

@ -18596,7 +18596,6 @@
"xpack.securitySolution.detectionEngine.createRule.stepDefineRule.indicesHelperDescription": "输入要运行此规则的 Elasticsearch 索引的模式。默认情况下,将包括 Security Solution 高级设置中定义的索引模式。",
"xpack.securitySolution.detectionEngine.createRule.stepDefineRule.machineLearningJobIdHelpText": "我们提供了一些常见作业来帮助您入门。要添加自己的定制规则,请在 {machineLearning} 应用程序中将一组“security”分配给这些作业以使其显示在此处。",
"xpack.securitySolution.detectionEngine.createRule.stepDefineRule.machineLearningJobIdRequired": "Machine Learning 作业必填。",
"xpack.securitySolution.detectionEngine.createRule.stepDefineRule.mlEnableJobWarningTitle": "此 ML 作业当前未运行。在激活此规则之前请通过“ML 作业设置”设置此作业以使其运行。",
"xpack.securitySolution.detectionEngine.createRule.stepDefineRule.mlJobSelectPlaceholderText": "选择作业",
"xpack.securitySolution.detectionEngine.createRule.stepDefineRule.outputIndiceNameFieldRequiredError": "至少需要一个索引模式。",
"xpack.securitySolution.detectionEngine.createRule.stepDefineRule.referencesUrlInvalidError": "Url 的格式无效",