mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[i18n] Translate ML - components - rule editor (#28262)
* Translate rule editor * Fix 'then' -> 'than' * Update snapshots * Fix rule description * Resolve issues from review comments * Remove extra space * Update snapshots * Resolve review comments * Update snapshots
This commit is contained in:
parent
90fbaf11c2
commit
89543df907
35 changed files with 1156 additions and 320 deletions
|
@ -7,7 +7,11 @@ exports[`ActionsSection renders with no actions selected 1`] = `
|
|||
size="m"
|
||||
>
|
||||
<p>
|
||||
Choose the action(s) to take when the rule matches an anomaly.
|
||||
<FormattedMessage
|
||||
defaultMessage="Choose the action(s) to take when the rule matches an anomaly."
|
||||
id="xpack.ml.ruleEditor.actionsSection.chooseActionsDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
|
@ -32,7 +36,13 @@ exports[`ActionsSection renders with no actions selected 1`] = `
|
|||
disabled={false}
|
||||
id="skip_result_cb"
|
||||
indeterminate={false}
|
||||
label="Skip result (recommended)"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Skip result (recommended)"
|
||||
id="xpack.ml.ruleEditor.actionsSection.skipResultLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction]}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
|
@ -42,7 +52,13 @@ exports[`ActionsSection renders with no actions selected 1`] = `
|
|||
>
|
||||
<EuiIconTip
|
||||
aria-label="Info"
|
||||
content="The result will not be created."
|
||||
content={
|
||||
<FormattedMessage
|
||||
defaultMessage="The result will not be created."
|
||||
id="xpack.ml.ruleEditor.actionsSection.resultWillNotBeCreatedTooltip"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
position="right"
|
||||
size="s"
|
||||
type="questionInCircle"
|
||||
|
@ -71,7 +87,13 @@ exports[`ActionsSection renders with no actions selected 1`] = `
|
|||
disabled={false}
|
||||
id="skip_model_update_cb"
|
||||
indeterminate={false}
|
||||
label="Skip model update"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Skip model update"
|
||||
id="xpack.ml.ruleEditor.actionsSection.skipModelUpdateLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction]}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
|
@ -81,7 +103,13 @@ exports[`ActionsSection renders with no actions selected 1`] = `
|
|||
>
|
||||
<EuiIconTip
|
||||
aria-label="Info"
|
||||
content="The value for that series will not be used to update the model."
|
||||
content={
|
||||
<FormattedMessage
|
||||
defaultMessage="The value for that series will not be used to update the model."
|
||||
id="xpack.ml.ruleEditor.actionsSection.valueWillNotBeUsedToUpdateModelTooltip"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
position="right"
|
||||
size="s"
|
||||
type="questionInCircle"
|
||||
|
@ -98,7 +126,11 @@ exports[`ActionsSection renders with skip_result and skip_model_update selected
|
|||
size="m"
|
||||
>
|
||||
<p>
|
||||
Choose the action(s) to take when the rule matches an anomaly.
|
||||
<FormattedMessage
|
||||
defaultMessage="Choose the action(s) to take when the rule matches an anomaly."
|
||||
id="xpack.ml.ruleEditor.actionsSection.chooseActionsDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
|
@ -123,7 +155,13 @@ exports[`ActionsSection renders with skip_result and skip_model_update selected
|
|||
disabled={false}
|
||||
id="skip_result_cb"
|
||||
indeterminate={false}
|
||||
label="Skip result (recommended)"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Skip result (recommended)"
|
||||
id="xpack.ml.ruleEditor.actionsSection.skipResultLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
onChange={[Function]}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
|
@ -133,7 +171,13 @@ exports[`ActionsSection renders with skip_result and skip_model_update selected
|
|||
>
|
||||
<EuiIconTip
|
||||
aria-label="Info"
|
||||
content="The result will not be created."
|
||||
content={
|
||||
<FormattedMessage
|
||||
defaultMessage="The result will not be created."
|
||||
id="xpack.ml.ruleEditor.actionsSection.resultWillNotBeCreatedTooltip"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
position="right"
|
||||
size="s"
|
||||
type="questionInCircle"
|
||||
|
@ -162,7 +206,13 @@ exports[`ActionsSection renders with skip_result and skip_model_update selected
|
|||
disabled={false}
|
||||
id="skip_model_update_cb"
|
||||
indeterminate={false}
|
||||
label="Skip model update"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Skip model update"
|
||||
id="xpack.ml.ruleEditor.actionsSection.skipModelUpdateLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
onChange={[Function]}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
|
@ -172,7 +222,13 @@ exports[`ActionsSection renders with skip_result and skip_model_update selected
|
|||
>
|
||||
<EuiIconTip
|
||||
aria-label="Info"
|
||||
content="The value for that series will not be used to update the model."
|
||||
content={
|
||||
<FormattedMessage
|
||||
defaultMessage="The value for that series will not be used to update the model."
|
||||
id="xpack.ml.ruleEditor.actionsSection.valueWillNotBeUsedToUpdateModelTooltip"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
position="right"
|
||||
size="s"
|
||||
type="questionInCircle"
|
||||
|
@ -189,7 +245,11 @@ exports[`ActionsSection renders with skip_result selected 1`] = `
|
|||
size="m"
|
||||
>
|
||||
<p>
|
||||
Choose the action(s) to take when the rule matches an anomaly.
|
||||
<FormattedMessage
|
||||
defaultMessage="Choose the action(s) to take when the rule matches an anomaly."
|
||||
id="xpack.ml.ruleEditor.actionsSection.chooseActionsDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
|
@ -214,7 +274,13 @@ exports[`ActionsSection renders with skip_result selected 1`] = `
|
|||
disabled={false}
|
||||
id="skip_result_cb"
|
||||
indeterminate={false}
|
||||
label="Skip result (recommended)"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Skip result (recommended)"
|
||||
id="xpack.ml.ruleEditor.actionsSection.skipResultLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction]}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
|
@ -224,7 +290,13 @@ exports[`ActionsSection renders with skip_result selected 1`] = `
|
|||
>
|
||||
<EuiIconTip
|
||||
aria-label="Info"
|
||||
content="The result will not be created."
|
||||
content={
|
||||
<FormattedMessage
|
||||
defaultMessage="The result will not be created."
|
||||
id="xpack.ml.ruleEditor.actionsSection.resultWillNotBeCreatedTooltip"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
position="right"
|
||||
size="s"
|
||||
type="questionInCircle"
|
||||
|
@ -253,7 +325,13 @@ exports[`ActionsSection renders with skip_result selected 1`] = `
|
|||
disabled={false}
|
||||
id="skip_model_update_cb"
|
||||
indeterminate={false}
|
||||
label="Skip model update"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Skip model update"
|
||||
id="xpack.ml.ruleEditor.actionsSection.skipModelUpdateLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction]}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
|
@ -263,7 +341,13 @@ exports[`ActionsSection renders with skip_result selected 1`] = `
|
|||
>
|
||||
<EuiIconTip
|
||||
aria-label="Info"
|
||||
content="The value for that series will not be used to update the model."
|
||||
content={
|
||||
<FormattedMessage
|
||||
defaultMessage="The value for that series will not be used to update the model."
|
||||
id="xpack.ml.ruleEditor.actionsSection.valueWillNotBeUsedToUpdateModelTooltip"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
position="right"
|
||||
size="s"
|
||||
type="questionInCircle"
|
||||
|
|
|
@ -19,7 +19,13 @@ exports[`ConditionExpression renders with appliesTo, operator and value supplied
|
|||
button={
|
||||
<EuiExpression
|
||||
color="secondary"
|
||||
description="when"
|
||||
description={
|
||||
<FormattedMessage
|
||||
defaultMessage="when"
|
||||
id="xpack.ml.ruleEditor.conditionExpression.appliesToButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
isActive={false}
|
||||
onClick={[Function]}
|
||||
uppercase={true}
|
||||
|
@ -42,7 +48,11 @@ exports[`ConditionExpression renders with appliesTo, operator and value supplied
|
|||
}
|
||||
>
|
||||
<EuiPopoverTitle>
|
||||
When
|
||||
<FormattedMessage
|
||||
defaultMessage="When"
|
||||
id="xpack.ml.ruleEditor.conditionExpression.appliesToPopoverTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiPopoverTitle>
|
||||
<div
|
||||
className="euiExpression"
|
||||
|
@ -89,7 +99,17 @@ exports[`ConditionExpression renders with appliesTo, operator and value supplied
|
|||
button={
|
||||
<EuiExpression
|
||||
color="secondary"
|
||||
description="is greater than"
|
||||
description={
|
||||
<FormattedMessage
|
||||
defaultMessage="is {operator}"
|
||||
id="xpack.ml.ruleEditor.conditionExpression.operatorValueButtonLabel"
|
||||
values={
|
||||
Object {
|
||||
"operator": "greater than",
|
||||
}
|
||||
}
|
||||
/>
|
||||
}
|
||||
isActive={false}
|
||||
onClick={[Function]}
|
||||
uppercase={true}
|
||||
|
@ -112,7 +132,11 @@ exports[`ConditionExpression renders with appliesTo, operator and value supplied
|
|||
}
|
||||
>
|
||||
<EuiPopoverTitle>
|
||||
Is
|
||||
<FormattedMessage
|
||||
defaultMessage="Is"
|
||||
id="xpack.ml.ruleEditor.conditionExpression.operatorValuePopoverTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiPopoverTitle>
|
||||
<div
|
||||
className="euiExpression"
|
||||
|
@ -196,7 +220,7 @@ exports[`ConditionExpression renders with appliesTo, operator and value supplied
|
|||
grow={false}
|
||||
>
|
||||
<EuiButtonIcon
|
||||
aria-label="Next"
|
||||
aria-label="Delete condition"
|
||||
color="danger"
|
||||
iconSize="m"
|
||||
iconType="trash"
|
||||
|
@ -227,7 +251,13 @@ exports[`ConditionExpression renders with only value supplied 1`] = `
|
|||
button={
|
||||
<EuiExpression
|
||||
color="secondary"
|
||||
description="when"
|
||||
description={
|
||||
<FormattedMessage
|
||||
defaultMessage="when"
|
||||
id="xpack.ml.ruleEditor.conditionExpression.appliesToButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
isActive={false}
|
||||
onClick={[Function]}
|
||||
uppercase={true}
|
||||
|
@ -250,7 +280,11 @@ exports[`ConditionExpression renders with only value supplied 1`] = `
|
|||
}
|
||||
>
|
||||
<EuiPopoverTitle>
|
||||
When
|
||||
<FormattedMessage
|
||||
defaultMessage="When"
|
||||
id="xpack.ml.ruleEditor.conditionExpression.appliesToPopoverTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiPopoverTitle>
|
||||
<div
|
||||
className="euiExpression"
|
||||
|
@ -296,7 +330,17 @@ exports[`ConditionExpression renders with only value supplied 1`] = `
|
|||
button={
|
||||
<EuiExpression
|
||||
color="secondary"
|
||||
description="is "
|
||||
description={
|
||||
<FormattedMessage
|
||||
defaultMessage="is {operator}"
|
||||
id="xpack.ml.ruleEditor.conditionExpression.operatorValueButtonLabel"
|
||||
values={
|
||||
Object {
|
||||
"operator": "",
|
||||
}
|
||||
}
|
||||
/>
|
||||
}
|
||||
isActive={false}
|
||||
onClick={[Function]}
|
||||
uppercase={true}
|
||||
|
@ -319,7 +363,11 @@ exports[`ConditionExpression renders with only value supplied 1`] = `
|
|||
}
|
||||
>
|
||||
<EuiPopoverTitle>
|
||||
Is
|
||||
<FormattedMessage
|
||||
defaultMessage="Is"
|
||||
id="xpack.ml.ruleEditor.conditionExpression.operatorValuePopoverTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiPopoverTitle>
|
||||
<div
|
||||
className="euiExpression"
|
||||
|
@ -402,7 +450,7 @@ exports[`ConditionExpression renders with only value supplied 1`] = `
|
|||
grow={false}
|
||||
>
|
||||
<EuiButtonIcon
|
||||
aria-label="Next"
|
||||
aria-label="Delete condition"
|
||||
color="danger"
|
||||
iconSize="m"
|
||||
iconType="trash"
|
||||
|
|
|
@ -15,7 +15,11 @@ exports[`ConditionsSectionExpression renders when enabled with empty conditions
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Add new condition
|
||||
<FormattedMessage
|
||||
defaultMessage="Add new condition"
|
||||
id="xpack.ml.ruleEditor.conditionsSection.addNewConditionButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</React.Fragment>
|
||||
`;
|
||||
|
@ -31,14 +35,18 @@ exports[`ConditionsSectionExpression renders when enabled with no conditions sup
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Add new condition
|
||||
<FormattedMessage
|
||||
defaultMessage="Add new condition"
|
||||
id="xpack.ml.ruleEditor.conditionsSection.addNewConditionButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</React.Fragment>
|
||||
`;
|
||||
|
||||
exports[`ConditionsSectionExpression renders when enabled with one condition 1`] = `
|
||||
<React.Fragment>
|
||||
<ConditionExpression
|
||||
<InjectIntl(ConditionExpression)
|
||||
appliesTo="actual"
|
||||
deleteCondition={[MockFunction]}
|
||||
index={0}
|
||||
|
@ -56,14 +64,18 @@ exports[`ConditionsSectionExpression renders when enabled with one condition 1`]
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Add new condition
|
||||
<FormattedMessage
|
||||
defaultMessage="Add new condition"
|
||||
id="xpack.ml.ruleEditor.conditionsSection.addNewConditionButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</React.Fragment>
|
||||
`;
|
||||
|
||||
exports[`ConditionsSectionExpression renders when enabled with two conditions 1`] = `
|
||||
<React.Fragment>
|
||||
<ConditionExpression
|
||||
<InjectIntl(ConditionExpression)
|
||||
appliesTo="actual"
|
||||
deleteCondition={[MockFunction]}
|
||||
index={0}
|
||||
|
@ -72,7 +84,7 @@ exports[`ConditionsSectionExpression renders when enabled with two conditions 1`
|
|||
updateCondition={[MockFunction]}
|
||||
value={1}
|
||||
/>
|
||||
<ConditionExpression
|
||||
<InjectIntl(ConditionExpression)
|
||||
appliesTo="typical"
|
||||
deleteCondition={[MockFunction]}
|
||||
index={1}
|
||||
|
@ -90,7 +102,11 @@ exports[`ConditionsSectionExpression renders when enabled with two conditions 1`
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Add new condition
|
||||
<FormattedMessage
|
||||
defaultMessage="Add new condition"
|
||||
id="xpack.ml.ruleEditor.conditionsSection.addNewConditionButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</React.Fragment>
|
||||
`;
|
||||
|
|
|
@ -26,7 +26,11 @@ exports[`RuleEditorFlyout renders the flyout after adding a condition to a rule
|
|||
<h1
|
||||
id="flyoutTitle"
|
||||
>
|
||||
Create Rule
|
||||
<FormattedMessage
|
||||
defaultMessage="Create Rule"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.createRuleTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</EuiFlyoutHeader>
|
||||
|
@ -95,15 +99,26 @@ exports[`RuleEditorFlyout renders the flyout after adding a condition to a rule
|
|||
size="m"
|
||||
>
|
||||
<p>
|
||||
Rules instruct anomaly detectors to change their behavior based on domain-specific knowledge that you provide. When you create a rule, you can specify conditions, scope, and actions. When the conditions of a rule are satisfied, its actions are triggered.
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href="https://www.elastic.co/guide/en/elastic-stack-overview/my-metadata-branch/ml-rules.html"
|
||||
target="_blank"
|
||||
type="button"
|
||||
>
|
||||
Learn more
|
||||
</EuiLink>
|
||||
<FormattedMessage
|
||||
defaultMessage="Rules instruct anomaly detectors to change their behavior based on domain-specific knowledge that you provide. When you create a rule, you can specify conditions, scope, and actions. When the conditions of a rule are satisfied, its actions are triggered. {learnMoreLink}"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.rulesDescription"
|
||||
values={
|
||||
Object {
|
||||
"learnMoreLink": <EuiLink
|
||||
color="primary"
|
||||
href="https://www.elastic.co/guide/en/elastic-stack-overview/my-metadata-branch/ml-rules.html"
|
||||
target="_blank"
|
||||
type="button"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Learn more"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.rulesDescription.learnMoreLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
|
@ -114,7 +129,11 @@ exports[`RuleEditorFlyout renders the flyout after adding a condition to a rule
|
|||
textTransform="none"
|
||||
>
|
||||
<h2>
|
||||
Action
|
||||
<FormattedMessage
|
||||
defaultMessage="Action"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.actionTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<ActionsSection
|
||||
|
@ -134,7 +153,11 @@ exports[`RuleEditorFlyout renders the flyout after adding a condition to a rule
|
|||
textTransform="none"
|
||||
>
|
||||
<h2>
|
||||
Conditions
|
||||
<FormattedMessage
|
||||
defaultMessage="Conditions"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.conditionsTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer
|
||||
|
@ -182,13 +205,27 @@ exports[`RuleEditorFlyout renders the flyout after adding a condition to a rule
|
|||
color="warning"
|
||||
iconType="help"
|
||||
size="m"
|
||||
title="Rerun job"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Rerun job"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.rerunJobTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
Changes to rules take effect for new results only.
|
||||
<FormattedMessage
|
||||
defaultMessage="Changes to rules take effect for new results only."
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.whenChangesTakeEffectDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
To apply these changes to existing results you must clone and rerun the job. Note rerunning the job may take some time and should only be done once you have completed all your changes to the rules for this job.
|
||||
<FormattedMessage
|
||||
defaultMessage="To apply these changes to existing results you must clone and rerun the job. Note rerunning the job may take some time and should only be done once you have completed all your changes to the rules for this job."
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.howToApplyChangesToExistingResultsDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiFlyoutBody>
|
||||
|
@ -214,7 +251,11 @@ exports[`RuleEditorFlyout renders the flyout after adding a condition to a rule
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Close
|
||||
<FormattedMessage
|
||||
defaultMessage="Close"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.closeButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
|
@ -229,7 +270,11 @@ exports[`RuleEditorFlyout renders the flyout after adding a condition to a rule
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Save
|
||||
<FormattedMessage
|
||||
defaultMessage="Save"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.saveButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
@ -260,7 +305,11 @@ exports[`RuleEditorFlyout renders the flyout after setting the rule to edit 1`]
|
|||
<h1
|
||||
id="flyoutTitle"
|
||||
>
|
||||
Edit Rule
|
||||
<FormattedMessage
|
||||
defaultMessage="Edit Rule"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.editRuleTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</EuiFlyoutHeader>
|
||||
|
@ -343,15 +392,26 @@ exports[`RuleEditorFlyout renders the flyout after setting the rule to edit 1`]
|
|||
size="m"
|
||||
>
|
||||
<p>
|
||||
Rules instruct anomaly detectors to change their behavior based on domain-specific knowledge that you provide. When you create a rule, you can specify conditions, scope, and actions. When the conditions of a rule are satisfied, its actions are triggered.
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href="https://www.elastic.co/guide/en/elastic-stack-overview/my-metadata-branch/ml-rules.html"
|
||||
target="_blank"
|
||||
type="button"
|
||||
>
|
||||
Learn more
|
||||
</EuiLink>
|
||||
<FormattedMessage
|
||||
defaultMessage="Rules instruct anomaly detectors to change their behavior based on domain-specific knowledge that you provide. When you create a rule, you can specify conditions, scope, and actions. When the conditions of a rule are satisfied, its actions are triggered. {learnMoreLink}"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.rulesDescription"
|
||||
values={
|
||||
Object {
|
||||
"learnMoreLink": <EuiLink
|
||||
color="primary"
|
||||
href="https://www.elastic.co/guide/en/elastic-stack-overview/my-metadata-branch/ml-rules.html"
|
||||
target="_blank"
|
||||
type="button"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Learn more"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.rulesDescription.learnMoreLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
|
@ -362,7 +422,11 @@ exports[`RuleEditorFlyout renders the flyout after setting the rule to edit 1`]
|
|||
textTransform="none"
|
||||
>
|
||||
<h2>
|
||||
Action
|
||||
<FormattedMessage
|
||||
defaultMessage="Action"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.actionTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<ActionsSection
|
||||
|
@ -382,7 +446,11 @@ exports[`RuleEditorFlyout renders the flyout after setting the rule to edit 1`]
|
|||
textTransform="none"
|
||||
>
|
||||
<h2>
|
||||
Conditions
|
||||
<FormattedMessage
|
||||
defaultMessage="Conditions"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.conditionsTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer
|
||||
|
@ -430,13 +498,27 @@ exports[`RuleEditorFlyout renders the flyout after setting the rule to edit 1`]
|
|||
color="warning"
|
||||
iconType="help"
|
||||
size="m"
|
||||
title="Rerun job"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Rerun job"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.rerunJobTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
Changes to rules take effect for new results only.
|
||||
<FormattedMessage
|
||||
defaultMessage="Changes to rules take effect for new results only."
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.whenChangesTakeEffectDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
To apply these changes to existing results you must clone and rerun the job. Note rerunning the job may take some time and should only be done once you have completed all your changes to the rules for this job.
|
||||
<FormattedMessage
|
||||
defaultMessage="To apply these changes to existing results you must clone and rerun the job. Note rerunning the job may take some time and should only be done once you have completed all your changes to the rules for this job."
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.howToApplyChangesToExistingResultsDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiFlyoutBody>
|
||||
|
@ -462,7 +544,11 @@ exports[`RuleEditorFlyout renders the flyout after setting the rule to edit 1`]
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Close
|
||||
<FormattedMessage
|
||||
defaultMessage="Close"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.closeButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
|
@ -477,7 +563,11 @@ exports[`RuleEditorFlyout renders the flyout after setting the rule to edit 1`]
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Save
|
||||
<FormattedMessage
|
||||
defaultMessage="Save"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.saveButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
@ -508,7 +598,11 @@ exports[`RuleEditorFlyout renders the flyout for creating a rule with conditions
|
|||
<h1
|
||||
id="flyoutTitle"
|
||||
>
|
||||
Create Rule
|
||||
<FormattedMessage
|
||||
defaultMessage="Create Rule"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.createRuleTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</EuiFlyoutHeader>
|
||||
|
@ -577,15 +671,26 @@ exports[`RuleEditorFlyout renders the flyout for creating a rule with conditions
|
|||
size="m"
|
||||
>
|
||||
<p>
|
||||
Rules instruct anomaly detectors to change their behavior based on domain-specific knowledge that you provide. When you create a rule, you can specify conditions, scope, and actions. When the conditions of a rule are satisfied, its actions are triggered.
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href="https://www.elastic.co/guide/en/elastic-stack-overview/my-metadata-branch/ml-rules.html"
|
||||
target="_blank"
|
||||
type="button"
|
||||
>
|
||||
Learn more
|
||||
</EuiLink>
|
||||
<FormattedMessage
|
||||
defaultMessage="Rules instruct anomaly detectors to change their behavior based on domain-specific knowledge that you provide. When you create a rule, you can specify conditions, scope, and actions. When the conditions of a rule are satisfied, its actions are triggered. {learnMoreLink}"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.rulesDescription"
|
||||
values={
|
||||
Object {
|
||||
"learnMoreLink": <EuiLink
|
||||
color="primary"
|
||||
href="https://www.elastic.co/guide/en/elastic-stack-overview/my-metadata-branch/ml-rules.html"
|
||||
target="_blank"
|
||||
type="button"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Learn more"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.rulesDescription.learnMoreLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
|
@ -596,7 +701,11 @@ exports[`RuleEditorFlyout renders the flyout for creating a rule with conditions
|
|||
textTransform="none"
|
||||
>
|
||||
<h2>
|
||||
Action
|
||||
<FormattedMessage
|
||||
defaultMessage="Action"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.actionTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<ActionsSection
|
||||
|
@ -616,7 +725,11 @@ exports[`RuleEditorFlyout renders the flyout for creating a rule with conditions
|
|||
textTransform="none"
|
||||
>
|
||||
<h2>
|
||||
Conditions
|
||||
<FormattedMessage
|
||||
defaultMessage="Conditions"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.conditionsTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer
|
||||
|
@ -656,13 +769,27 @@ exports[`RuleEditorFlyout renders the flyout for creating a rule with conditions
|
|||
color="warning"
|
||||
iconType="help"
|
||||
size="m"
|
||||
title="Rerun job"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Rerun job"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.rerunJobTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
Changes to rules take effect for new results only.
|
||||
<FormattedMessage
|
||||
defaultMessage="Changes to rules take effect for new results only."
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.whenChangesTakeEffectDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
To apply these changes to existing results you must clone and rerun the job. Note rerunning the job may take some time and should only be done once you have completed all your changes to the rules for this job.
|
||||
<FormattedMessage
|
||||
defaultMessage="To apply these changes to existing results you must clone and rerun the job. Note rerunning the job may take some time and should only be done once you have completed all your changes to the rules for this job."
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.howToApplyChangesToExistingResultsDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
</EuiFlyoutBody>
|
||||
|
@ -688,7 +815,11 @@ exports[`RuleEditorFlyout renders the flyout for creating a rule with conditions
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Close
|
||||
<FormattedMessage
|
||||
defaultMessage="Close"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.closeButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
|
@ -703,7 +834,11 @@ exports[`RuleEditorFlyout renders the flyout for creating a rule with conditions
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Save
|
||||
<FormattedMessage
|
||||
defaultMessage="Save"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.saveButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
@ -734,7 +869,11 @@ exports[`RuleEditorFlyout renders the select action component for a detector wit
|
|||
<h1
|
||||
id="flyoutTitle"
|
||||
>
|
||||
Edit Rules
|
||||
<FormattedMessage
|
||||
defaultMessage="Edit Rules"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.editRulesTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</EuiFlyoutHeader>
|
||||
|
@ -814,7 +953,11 @@ exports[`RuleEditorFlyout renders the select action component for a detector wit
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Close
|
||||
<FormattedMessage
|
||||
defaultMessage="Close"
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.closeButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -31,7 +31,13 @@ exports[`ScopeExpression renders when empty list of filter IDs is supplied 1`] =
|
|||
<EuiExpression
|
||||
className="scope-field-button"
|
||||
color="secondary"
|
||||
description="when"
|
||||
description={
|
||||
<FormattedMessage
|
||||
defaultMessage="when"
|
||||
id="xpack.ml.ruleEditor.scopeExpression.scopeFieldWhenLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
isActive={false}
|
||||
onClick={[Function]}
|
||||
uppercase={true}
|
||||
|
@ -72,7 +78,13 @@ exports[`ScopeExpression renders when enabled set to false 1`] = `
|
|||
<EuiExpression
|
||||
className="scope-field-button"
|
||||
color="secondary"
|
||||
description="when"
|
||||
description={
|
||||
<FormattedMessage
|
||||
defaultMessage="when"
|
||||
id="xpack.ml.ruleEditor.scopeExpression.scopeFieldWhenLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
isActive={false}
|
||||
onClick={[Function]}
|
||||
uppercase={true}
|
||||
|
@ -88,7 +100,17 @@ exports[`ScopeExpression renders when enabled set to false 1`] = `
|
|||
button={
|
||||
<EuiExpression
|
||||
color="secondary"
|
||||
description="is in"
|
||||
description={
|
||||
<FormattedMessage
|
||||
defaultMessage="is {filterType}"
|
||||
id="xpack.ml.ruleEditor.scopeExpression.scopeFilterTypeButtonLabel"
|
||||
values={
|
||||
Object {
|
||||
"filterType": "in",
|
||||
}
|
||||
}
|
||||
/>
|
||||
}
|
||||
isActive={false}
|
||||
onClick={[Function]}
|
||||
uppercase={true}
|
||||
|
@ -111,7 +133,11 @@ exports[`ScopeExpression renders when enabled set to false 1`] = `
|
|||
}
|
||||
>
|
||||
<EuiPopoverTitle>
|
||||
Is
|
||||
<FormattedMessage
|
||||
defaultMessage="Is"
|
||||
id="xpack.ml.ruleEditor.scopeExpression.scopeFilterTypePopoverTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiPopoverTitle>
|
||||
<div
|
||||
className="euiExpression"
|
||||
|
@ -233,7 +259,13 @@ exports[`ScopeExpression renders when filter ID and type supplied 1`] = `
|
|||
<EuiExpression
|
||||
className="scope-field-button"
|
||||
color="secondary"
|
||||
description="when"
|
||||
description={
|
||||
<FormattedMessage
|
||||
defaultMessage="when"
|
||||
id="xpack.ml.ruleEditor.scopeExpression.scopeFieldWhenLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
isActive={false}
|
||||
onClick={[Function]}
|
||||
uppercase={true}
|
||||
|
@ -249,7 +281,17 @@ exports[`ScopeExpression renders when filter ID and type supplied 1`] = `
|
|||
button={
|
||||
<EuiExpression
|
||||
color="secondary"
|
||||
description="is in"
|
||||
description={
|
||||
<FormattedMessage
|
||||
defaultMessage="is {filterType}"
|
||||
id="xpack.ml.ruleEditor.scopeExpression.scopeFilterTypeButtonLabel"
|
||||
values={
|
||||
Object {
|
||||
"filterType": "in",
|
||||
}
|
||||
}
|
||||
/>
|
||||
}
|
||||
isActive={false}
|
||||
onClick={[Function]}
|
||||
uppercase={true}
|
||||
|
@ -272,7 +314,11 @@ exports[`ScopeExpression renders when filter ID and type supplied 1`] = `
|
|||
}
|
||||
>
|
||||
<EuiPopoverTitle>
|
||||
Is
|
||||
<FormattedMessage
|
||||
defaultMessage="Is"
|
||||
id="xpack.ml.ruleEditor.scopeExpression.scopeFilterTypePopoverTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiPopoverTitle>
|
||||
<div
|
||||
className="euiExpression"
|
||||
|
@ -394,7 +440,13 @@ exports[`ScopeExpression renders when no filter ID or type supplied 1`] = `
|
|||
<EuiExpression
|
||||
className="scope-field-button"
|
||||
color="secondary"
|
||||
description="when"
|
||||
description={
|
||||
<FormattedMessage
|
||||
defaultMessage="when"
|
||||
id="xpack.ml.ruleEditor.scopeExpression.scopeFieldWhenLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
isActive={false}
|
||||
onClick={[Function]}
|
||||
uppercase={true}
|
||||
|
@ -410,7 +462,17 @@ exports[`ScopeExpression renders when no filter ID or type supplied 1`] = `
|
|||
button={
|
||||
<EuiExpression
|
||||
color="secondary"
|
||||
description="is "
|
||||
description={
|
||||
<FormattedMessage
|
||||
defaultMessage="is {filterType}"
|
||||
id="xpack.ml.ruleEditor.scopeExpression.scopeFilterTypeButtonLabel"
|
||||
values={
|
||||
Object {
|
||||
"filterType": "",
|
||||
}
|
||||
}
|
||||
/>
|
||||
}
|
||||
isActive={false}
|
||||
onClick={[Function]}
|
||||
uppercase={true}
|
||||
|
@ -433,7 +495,11 @@ exports[`ScopeExpression renders when no filter ID or type supplied 1`] = `
|
|||
}
|
||||
>
|
||||
<EuiPopoverTitle>
|
||||
Is
|
||||
<FormattedMessage
|
||||
defaultMessage="Is"
|
||||
id="xpack.ml.ruleEditor.scopeExpression.scopeFilterTypePopoverTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiPopoverTitle>
|
||||
<div
|
||||
className="euiExpression"
|
||||
|
|
|
@ -9,7 +9,11 @@ exports[`ScopeSection false canGetFilters privilege show NoPermissionCallOut whe
|
|||
textTransform="none"
|
||||
>
|
||||
<h2>
|
||||
Scope
|
||||
<FormattedMessage
|
||||
defaultMessage="Scope"
|
||||
id="xpack.ml.ruleEditor.scopeSection.scopeTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer
|
||||
|
@ -21,7 +25,13 @@ exports[`ScopeSection false canGetFilters privilege show NoPermissionCallOut whe
|
|||
disabled={false}
|
||||
id="enable_scope_checkbox"
|
||||
indeterminate={false}
|
||||
label="Add a filter list to limit where the rule applies."
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Add a filter list to limit where the rule applies."
|
||||
id="xpack.ml.ruleEditor.scopeSection.addFilterListLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction]}
|
||||
/>
|
||||
<EuiSpacer
|
||||
|
@ -43,7 +53,11 @@ exports[`ScopeSection renders when enabled with no scope supplied 1`] = `
|
|||
textTransform="none"
|
||||
>
|
||||
<h2>
|
||||
Scope
|
||||
<FormattedMessage
|
||||
defaultMessage="Scope"
|
||||
id="xpack.ml.ruleEditor.scopeSection.scopeTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer
|
||||
|
@ -55,7 +69,13 @@ exports[`ScopeSection renders when enabled with no scope supplied 1`] = `
|
|||
disabled={false}
|
||||
id="enable_scope_checkbox"
|
||||
indeterminate={false}
|
||||
label="Add a filter list to limit where the rule applies."
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Add a filter list to limit where the rule applies."
|
||||
id="xpack.ml.ruleEditor.scopeSection.addFilterListLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction]}
|
||||
/>
|
||||
<EuiSpacer
|
||||
|
@ -91,7 +111,11 @@ exports[`ScopeSection renders when enabled with scope supplied 1`] = `
|
|||
textTransform="none"
|
||||
>
|
||||
<h2>
|
||||
Scope
|
||||
<FormattedMessage
|
||||
defaultMessage="Scope"
|
||||
id="xpack.ml.ruleEditor.scopeSection.scopeTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer
|
||||
|
@ -103,7 +127,13 @@ exports[`ScopeSection renders when enabled with scope supplied 1`] = `
|
|||
disabled={false}
|
||||
id="enable_scope_checkbox"
|
||||
indeterminate={false}
|
||||
label="Add a filter list to limit where the rule applies."
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Add a filter list to limit where the rule applies."
|
||||
id="xpack.ml.ruleEditor.scopeSection.addFilterListLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction]}
|
||||
/>
|
||||
<EuiSpacer
|
||||
|
@ -139,7 +169,11 @@ exports[`ScopeSection renders when not enabled 1`] = `
|
|||
textTransform="none"
|
||||
>
|
||||
<h2>
|
||||
Scope
|
||||
<FormattedMessage
|
||||
defaultMessage="Scope"
|
||||
id="xpack.ml.ruleEditor.scopeSection.scopeTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer
|
||||
|
@ -151,7 +185,13 @@ exports[`ScopeSection renders when not enabled 1`] = `
|
|||
disabled={false}
|
||||
id="enable_scope_checkbox"
|
||||
indeterminate={false}
|
||||
label="Add a filter list to limit where the rule applies."
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Add a filter list to limit where the rule applies."
|
||||
id="xpack.ml.ruleEditor.scopeSection.addFilterListLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction]}
|
||||
/>
|
||||
<EuiSpacer
|
||||
|
@ -170,7 +210,11 @@ exports[`ScopeSection show NoFilterListsCallOut when no filter list IDs 1`] = `
|
|||
textTransform="none"
|
||||
>
|
||||
<h2>
|
||||
Scope
|
||||
<FormattedMessage
|
||||
defaultMessage="Scope"
|
||||
id="xpack.ml.ruleEditor.scopeSection.scopeTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer
|
||||
|
@ -182,7 +226,13 @@ exports[`ScopeSection show NoFilterListsCallOut when no filter list IDs 1`] = `
|
|||
disabled={false}
|
||||
id="enable_scope_checkbox"
|
||||
indeterminate={false}
|
||||
label="Add a filter list to limit where the rule applies."
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Add a filter list to limit where the rule applies."
|
||||
id="xpack.ml.ruleEditor.scopeSection.addFilterListLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
onChange={[MockFunction]}
|
||||
/>
|
||||
<EuiSpacer
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
} from '@elastic/eui';
|
||||
|
||||
import { ACTION } from '../../../common/constants/detector_rule';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
export function ActionsSection({
|
||||
actions,
|
||||
|
@ -32,7 +33,10 @@ export function ActionsSection({
|
|||
<React.Fragment>
|
||||
<EuiText>
|
||||
<p>
|
||||
Choose the action(s) to take when the rule matches an anomaly.
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.actionsSection.chooseActionsDescription"
|
||||
defaultMessage="Choose the action(s) to take when the rule matches an anomaly."
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer size="s" />
|
||||
|
@ -40,7 +44,10 @@ export function ActionsSection({
|
|||
<EuiFlexItem grow={false}>
|
||||
<EuiCheckbox
|
||||
id="skip_result_cb"
|
||||
label="Skip result (recommended)"
|
||||
label={<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.actionsSection.skipResultLabel"
|
||||
defaultMessage="Skip result (recommended)"
|
||||
/>}
|
||||
checked={actions.indexOf(ACTION.SKIP_RESULT) > -1}
|
||||
onChange={onSkipResultChange}
|
||||
/>
|
||||
|
@ -48,7 +55,10 @@ export function ActionsSection({
|
|||
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIconTip
|
||||
content="The result will not be created."
|
||||
content={<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.actionsSection.resultWillNotBeCreatedTooltip"
|
||||
defaultMessage="The result will not be created."
|
||||
/>}
|
||||
size="s"
|
||||
position="right"
|
||||
/>
|
||||
|
@ -61,7 +71,10 @@ export function ActionsSection({
|
|||
<EuiFlexItem grow={false}>
|
||||
<EuiCheckbox
|
||||
id="skip_model_update_cb"
|
||||
label="Skip model update"
|
||||
label={<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.actionsSection.skipModelUpdateLabel"
|
||||
defaultMessage="Skip model update"
|
||||
/>}
|
||||
checked={actions.indexOf(ACTION.SKIP_MODEL_UPDATE) > -1}
|
||||
onChange={onSkipModelUpdateChange}
|
||||
/>
|
||||
|
@ -69,7 +82,10 @@ export function ActionsSection({
|
|||
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIconTip
|
||||
content="The value for that series will not be used to update the model."
|
||||
content={<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.actionsSection.valueWillNotBeUsedToUpdateModelTooltip"
|
||||
defaultMessage="The value for that series will not be used to update the model."
|
||||
/>}
|
||||
size="s"
|
||||
position="right"
|
||||
/>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import React from 'react';
|
||||
|
||||
import { ActionsSection } from './actions_section';
|
||||
|
@ -27,7 +27,7 @@ describe('ActionsSection', () => {
|
|||
actions: [],
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ActionsSection {...props} />
|
||||
);
|
||||
|
||||
|
@ -41,7 +41,7 @@ describe('ActionsSection', () => {
|
|||
actions: [ACTION.SKIP_RESULT],
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ActionsSection {...props} />
|
||||
);
|
||||
|
||||
|
@ -52,7 +52,7 @@ describe('ActionsSection', () => {
|
|||
|
||||
test('renders with skip_result and skip_model_update selected', () => {
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ActionsSection
|
||||
actions={[ACTION.SKIP_RESULT, ACTION.SKIP_MODEL_UPDATE]}
|
||||
onSkipResultChange={() => {}}
|
||||
|
|
|
@ -9,15 +9,36 @@ exports[`DetectorDescriptionList render for detector with anomaly values 1`] = `
|
|||
Array [
|
||||
Object {
|
||||
"description": "responsetimes",
|
||||
"title": "Job ID",
|
||||
"title": <FormattedMessage
|
||||
defaultMessage="Job ID"
|
||||
id="xpack.ml.ruleEditor.detectorDescriptionList.jobIdTitle"
|
||||
values={Object {}}
|
||||
/>,
|
||||
},
|
||||
Object {
|
||||
"description": "mean response time",
|
||||
"title": "Detector",
|
||||
"title": <FormattedMessage
|
||||
defaultMessage="Detector"
|
||||
id="xpack.ml.ruleEditor.detectorDescriptionList.detectorTitle"
|
||||
values={Object {}}
|
||||
/>,
|
||||
},
|
||||
Object {
|
||||
"description": "actual 50, typical 1.23",
|
||||
"title": "Selected anomaly",
|
||||
"description": <FormattedMessage
|
||||
defaultMessage="actual {actual}, typical {typical}"
|
||||
id="xpack.ml.ruleEditor.detectorDescriptionList.selectedAnomalyDescription"
|
||||
values={
|
||||
Object {
|
||||
"actual": 50,
|
||||
"typical": 1.23,
|
||||
}
|
||||
}
|
||||
/>,
|
||||
"title": <FormattedMessage
|
||||
defaultMessage="Selected anomaly"
|
||||
id="xpack.ml.ruleEditor.detectorDescriptionList.selectedAnomalyTitle"
|
||||
values={Object {}}
|
||||
/>,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -35,11 +56,19 @@ exports[`DetectorDescriptionList render for population detector with no anomaly
|
|||
Array [
|
||||
Object {
|
||||
"description": "population",
|
||||
"title": "Job ID",
|
||||
"title": <FormattedMessage
|
||||
defaultMessage="Job ID"
|
||||
id="xpack.ml.ruleEditor.detectorDescriptionList.jobIdTitle"
|
||||
values={Object {}}
|
||||
/>,
|
||||
},
|
||||
Object {
|
||||
"description": "count by status over clientip",
|
||||
"title": "Detector",
|
||||
"title": <FormattedMessage
|
||||
defaultMessage="Detector"
|
||||
id="xpack.ml.ruleEditor.detectorDescriptionList.detectorTitle"
|
||||
values={Object {}}
|
||||
/>,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ import {
|
|||
|
||||
import { formatValue } from '../../../../formatters/format_value';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
export function DetectorDescriptionList({
|
||||
job,
|
||||
detector,
|
||||
|
@ -26,11 +28,21 @@ export function DetectorDescriptionList({
|
|||
|
||||
const listItems = [
|
||||
{
|
||||
title: 'Job ID',
|
||||
title: (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.detectorDescriptionList.jobIdTitle"
|
||||
defaultMessage="Job ID"
|
||||
/>
|
||||
),
|
||||
description: job.job_id,
|
||||
},
|
||||
{
|
||||
title: 'Detector',
|
||||
title: (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.detectorDescriptionList.detectorTitle"
|
||||
defaultMessage="Detector"
|
||||
/>
|
||||
),
|
||||
description: detector.detector_description,
|
||||
}
|
||||
];
|
||||
|
@ -44,8 +56,19 @@ export function DetectorDescriptionList({
|
|||
|
||||
listItems.push(
|
||||
{
|
||||
title: 'Selected anomaly',
|
||||
description: `actual ${actual}, typical ${typical}`,
|
||||
title: (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.detectorDescriptionList.selectedAnomalyTitle"
|
||||
defaultMessage="Selected anomaly"
|
||||
/>
|
||||
),
|
||||
description: (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.detectorDescriptionList.selectedAnomalyDescription"
|
||||
defaultMessage="actual {actual}, typical {typical}"
|
||||
values={{ actual, typical }}
|
||||
/>
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import React from 'react';
|
||||
|
||||
import { DetectorDescriptionList } from './detector_description_list';
|
||||
|
@ -28,7 +28,7 @@ describe('DetectorDescriptionList', () => {
|
|||
},
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<DetectorDescriptionList {...props} />
|
||||
);
|
||||
|
||||
|
@ -60,7 +60,7 @@ describe('DetectorDescriptionList', () => {
|
|||
},
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<DetectorDescriptionList {...props} />
|
||||
);
|
||||
|
||||
|
|
|
@ -27,12 +27,31 @@ import {
|
|||
|
||||
import { APPLIES_TO, OPERATOR } from '../../../common/constants/detector_rule';
|
||||
import { appliesToText, operatorToText } from './utils';
|
||||
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
||||
|
||||
// Raise the popovers above GuidePageSideNav
|
||||
const POPOVER_STYLE = { zIndex: '200' };
|
||||
|
||||
|
||||
export class ConditionExpression extends Component {
|
||||
export const ConditionExpression = injectI18n(class ConditionExpression extends Component {
|
||||
static propTypes = {
|
||||
index: PropTypes.number.isRequired,
|
||||
appliesTo: PropTypes.oneOf([
|
||||
APPLIES_TO.ACTUAL,
|
||||
APPLIES_TO.TYPICAL,
|
||||
APPLIES_TO.DIFF_FROM_TYPICAL
|
||||
]),
|
||||
operator: PropTypes.oneOf([
|
||||
OPERATOR.LESS_THAN,
|
||||
OPERATOR.LESS_THAN_OR_EQUAL,
|
||||
OPERATOR.GREATER_THAN,
|
||||
OPERATOR.GREATER_THAN_OR_EQUAL
|
||||
]),
|
||||
value: PropTypes.number.isRequired,
|
||||
updateCondition: PropTypes.func.isRequired,
|
||||
deleteCondition: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
|
@ -98,7 +117,12 @@ export class ConditionExpression extends Component {
|
|||
renderAppliesToPopover() {
|
||||
return (
|
||||
<div style={POPOVER_STYLE}>
|
||||
<EuiPopoverTitle>When</EuiPopoverTitle>
|
||||
<EuiPopoverTitle>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.conditionExpression.appliesToPopoverTitle"
|
||||
defaultMessage="When"
|
||||
/>
|
||||
</EuiPopoverTitle>
|
||||
<div className="euiExpression" style={{ width: 200 }}>
|
||||
<EuiSelect
|
||||
value={this.props.appliesTo}
|
||||
|
@ -117,7 +141,12 @@ export class ConditionExpression extends Component {
|
|||
renderOperatorValuePopover() {
|
||||
return (
|
||||
<div style={POPOVER_STYLE}>
|
||||
<EuiPopoverTitle>Is</EuiPopoverTitle>
|
||||
<EuiPopoverTitle>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.conditionExpression.operatorValuePopoverTitle"
|
||||
defaultMessage="Is"
|
||||
/>
|
||||
</EuiPopoverTitle>
|
||||
<div className="euiExpression">
|
||||
<EuiFlexGroup style={{ maxWidth: 450 }}>
|
||||
<EuiFlexItem grow={false} style={{ width: 250 }}>
|
||||
|
@ -161,7 +190,10 @@ export class ConditionExpression extends Component {
|
|||
id="appliesToPopover"
|
||||
button={(
|
||||
<EuiExpression
|
||||
description="when"
|
||||
description={(<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.conditionExpression.appliesToButtonLabel"
|
||||
defaultMessage="when"
|
||||
/>)}
|
||||
value={appliesToText(appliesTo)}
|
||||
isActive={this.state.isAppliesToOpen}
|
||||
onClick={this.openAppliesTo}
|
||||
|
@ -183,7 +215,11 @@ export class ConditionExpression extends Component {
|
|||
id="operatorValuePopover"
|
||||
button={(
|
||||
<EuiExpression
|
||||
description={`is ${operatorToText(operator)}`}
|
||||
description={(<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.conditionExpression.operatorValueButtonLabel"
|
||||
defaultMessage="is {operator}"
|
||||
values={{ operator: operatorToText(operator) }}
|
||||
/>)}
|
||||
value={`${value}`}
|
||||
isActive={this.state.isOperatorValueOpen}
|
||||
onClick={this.openOperatorValue}
|
||||
|
@ -205,27 +241,13 @@ export class ConditionExpression extends Component {
|
|||
color="danger"
|
||||
onClick={() => deleteCondition(index)}
|
||||
iconType="trash"
|
||||
aria-label="Next"
|
||||
aria-label={this.props.intl.formatMessage({
|
||||
id: 'xpack.ml.ruleEditor.conditionExpression.deleteConditionButtonAriaLabel',
|
||||
defaultMessage: 'Delete condition'
|
||||
})}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
}
|
||||
}
|
||||
ConditionExpression.propTypes = {
|
||||
index: PropTypes.number.isRequired,
|
||||
appliesTo: PropTypes.oneOf([
|
||||
APPLIES_TO.ACTUAL,
|
||||
APPLIES_TO.TYPICAL,
|
||||
APPLIES_TO.DIFF_FROM_TYPICAL
|
||||
]),
|
||||
operator: PropTypes.oneOf([
|
||||
OPERATOR.LESS_THAN,
|
||||
OPERATOR.LESS_THAN_OR_EQUAL,
|
||||
OPERATOR.GREATER_THAN,
|
||||
OPERATOR.GREATER_THAN_OR_EQUAL
|
||||
]),
|
||||
value: PropTypes.number.isRequired,
|
||||
updateCondition: PropTypes.func.isRequired,
|
||||
deleteCondition: PropTypes.func.isRequired
|
||||
};
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// Mock the mlJobService that is imported for saving rules.
|
||||
jest.mock('../../services/job_service.js', () => 'mlJobService');
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import React from 'react';
|
||||
|
||||
import { ConditionExpression } from './condition_expression';
|
||||
|
@ -30,8 +30,8 @@ describe('ConditionExpression', () => {
|
|||
value: 123,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
<ConditionExpression {...props} />
|
||||
const component = shallowWithIntl(
|
||||
<ConditionExpression.WrappedComponent {...props} />
|
||||
);
|
||||
|
||||
expect(component).toMatchSnapshot();
|
||||
|
@ -45,8 +45,8 @@ describe('ConditionExpression', () => {
|
|||
value: 123,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
<ConditionExpression {...props} />
|
||||
const component = shallowWithIntl(
|
||||
<ConditionExpression.WrappedComponent {...props} />
|
||||
);
|
||||
|
||||
expect(component).toMatchSnapshot();
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
} from '@elastic/eui';
|
||||
|
||||
import { ConditionExpression } from './condition_expression';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
|
||||
export function ConditionsSection({
|
||||
|
@ -55,7 +56,10 @@ export function ConditionsSection({
|
|||
<EuiButtonEmpty
|
||||
onClick={() => addCondition()}
|
||||
>
|
||||
Add new condition
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.conditionsSection.addNewConditionButtonLabel"
|
||||
defaultMessage="Add new condition"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// Mock the mlJobService that is imported for saving rules.
|
||||
jest.mock('../../services/job_service.js', () => 'mlJobService');
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import React from 'react';
|
||||
|
||||
import { ConditionsSection } from './conditions_section';
|
||||
|
@ -38,7 +38,7 @@ describe('ConditionsSectionExpression', () => {
|
|||
isEnabled: false,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ConditionsSection {...props} />
|
||||
);
|
||||
|
||||
|
@ -51,7 +51,7 @@ describe('ConditionsSectionExpression', () => {
|
|||
isEnabled: true,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ConditionsSection {...props} />
|
||||
);
|
||||
|
||||
|
@ -65,7 +65,7 @@ describe('ConditionsSectionExpression', () => {
|
|||
conditions: [],
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ConditionsSection {...props} />
|
||||
);
|
||||
|
||||
|
@ -79,7 +79,7 @@ describe('ConditionsSectionExpression', () => {
|
|||
conditions: [getNewConditionDefaults()],
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ConditionsSection {...props} />
|
||||
);
|
||||
|
||||
|
@ -93,7 +93,7 @@ describe('ConditionsSectionExpression', () => {
|
|||
conditions: [getNewConditionDefaults(), testCondition],
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ConditionsSection {...props} />
|
||||
);
|
||||
|
||||
|
@ -107,7 +107,7 @@ describe('ConditionsSectionExpression', () => {
|
|||
conditions: [getNewConditionDefaults(), testCondition],
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ConditionsSection {...props} />
|
||||
);
|
||||
|
||||
|
|
|
@ -52,11 +52,17 @@ import { getPartitioningFieldNames } from '../../../common/util/job_utils';
|
|||
import { mlJobService } from '../../services/job_service';
|
||||
import { ml } from '../../services/ml_api_service';
|
||||
import { metadata } from 'ui/metadata';
|
||||
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
||||
|
||||
// metadata.branch corresponds to the version used in documentation links.
|
||||
const docsUrl = `https://www.elastic.co/guide/en/elastic-stack-overview/${metadata.branch}/ml-rules.html`;
|
||||
|
||||
export class RuleEditorFlyout extends Component {
|
||||
export const RuleEditorFlyout = injectI18n(class RuleEditorFlyout extends Component {
|
||||
static propTypes = {
|
||||
setShowFunction: PropTypes.func.isRequired,
|
||||
unsetShowFunction: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
|
@ -90,12 +96,17 @@ export class RuleEditorFlyout extends Component {
|
|||
|
||||
showFlyout = (anomaly) => {
|
||||
let ruleIndex = -1;
|
||||
const { intl } = this.props;
|
||||
const job = mlJobService.getJob(anomaly.jobId);
|
||||
if (job === undefined) {
|
||||
// No details found for this job, display an error and
|
||||
// don't open the Flyout as no edits can be made without the job.
|
||||
toastNotifications.addDanger(
|
||||
`Unable to configure rules as an error occurred obtaining details for job ID ${anomaly.jobId}`);
|
||||
intl.formatMessage({
|
||||
id: 'xpack.ml.ruleEditor.ruleEditorFlyout.unableToConfigureRulesNotificationMesssage',
|
||||
defaultMessage: 'Unable to configure rules as an error occurred obtaining details for job ID {jobId}'
|
||||
}, { jobId: anomaly.jobId })
|
||||
);
|
||||
this.setState({
|
||||
job,
|
||||
isFlyoutVisible: false
|
||||
|
@ -139,7 +150,12 @@ export class RuleEditorFlyout extends Component {
|
|||
})
|
||||
.catch((resp) => {
|
||||
console.log('Error loading list of filters:', resp);
|
||||
toastNotifications.addDanger('Error loading the filter lists used in the rule scope');
|
||||
toastNotifications.addDanger(
|
||||
intl.formatMessage({
|
||||
id: 'xpack.ml.ruleEditor.ruleEditorFlyout.errorWithLoadingFilterListsNotificationMesssage',
|
||||
defaultMessage: 'Error loading the filter lists used in the rule scope'
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -312,6 +328,7 @@ export class RuleEditorFlyout extends Component {
|
|||
}
|
||||
|
||||
updateRuleAtIndex = (ruleIndex, editedRule) => {
|
||||
const { intl } = this.props;
|
||||
const {
|
||||
job,
|
||||
anomaly,
|
||||
|
@ -325,24 +342,41 @@ export class RuleEditorFlyout extends Component {
|
|||
if (resp.success) {
|
||||
toastNotifications.add(
|
||||
{
|
||||
title: `Changes to ${jobId} detector rules saved`,
|
||||
title: intl.formatMessage({
|
||||
id: 'xpack.ml.ruleEditor.ruleEditorFlyout.changesToJobDetectorRulesSavedNotificationMessageTitle',
|
||||
defaultMessage: 'Changes to {jobId} detector rules saved'
|
||||
}, { jobId }),
|
||||
color: 'success',
|
||||
iconType: 'check',
|
||||
text: 'Note that changes will take effect for new results only.'
|
||||
text: intl.formatMessage({
|
||||
id: 'xpack.ml.ruleEditor.ruleEditorFlyout.changesToJobDetectorRulesSavedNotificationMessageDescription',
|
||||
defaultMessage: 'Note that changes will take effect for new results only.'
|
||||
})
|
||||
}
|
||||
);
|
||||
this.closeFlyout();
|
||||
} else {
|
||||
toastNotifications.addDanger(`Error saving changes to ${jobId} detector rules`);
|
||||
toastNotifications.addDanger(
|
||||
intl.formatMessage({
|
||||
id: 'xpack.ml.ruleEditor.ruleEditorFlyout.errorWithSavingChangesToJobDetectorRulesNotificationMessage',
|
||||
defaultMessage: 'Error saving changes to {jobId} detector rules'
|
||||
}, { jobId })
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
toastNotifications.addDanger(`Error saving changes to ${jobId} detector rules`);
|
||||
toastNotifications.addDanger(
|
||||
intl.formatMessage({
|
||||
id: 'xpack.ml.ruleEditor.ruleEditorFlyout.errorWithSavingChangesToJobDetectorRulesNotificationMessage',
|
||||
defaultMessage: 'Error saving changes to {jobId} detector rules'
|
||||
}, { jobId })
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
deleteRuleAtIndex = (index) => {
|
||||
const { intl } = this.props;
|
||||
const {
|
||||
job,
|
||||
anomaly
|
||||
|
@ -353,15 +387,28 @@ export class RuleEditorFlyout extends Component {
|
|||
deleteJobRule(job, detectorIndex, index)
|
||||
.then((resp) => {
|
||||
if (resp.success) {
|
||||
toastNotifications.addSuccess(`Rule deleted from ${jobId} detector`);
|
||||
toastNotifications.addSuccess(
|
||||
intl.formatMessage({
|
||||
id: 'xpack.ml.ruleEditor.ruleEditorFlyout.ruleDeletedFromJobDetectorNotificationMessage',
|
||||
defaultMessage: 'Rule deleted from {jobId} detector'
|
||||
}, { jobId })
|
||||
);
|
||||
this.closeFlyout();
|
||||
} else {
|
||||
toastNotifications.addDanger(`Error deleting rule from ${jobId} detector`);
|
||||
toastNotifications.addDanger(
|
||||
intl.formatMessage({
|
||||
id: 'xpack.ml.ruleEditor.ruleEditorFlyout.errorWithDeletingRuleFromJobDetectorNotificationMessage',
|
||||
defaultMessage: 'Error deleting rule from {jobId} detector'
|
||||
}, { jobId })
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
let errorMessage = `Error deleting rule from ${jobId} detector`;
|
||||
let errorMessage = intl.formatMessage({
|
||||
id: 'xpack.ml.ruleEditor.ruleEditorFlyout.errorWithDeletingRuleFromJobDetectorNotificationMessage',
|
||||
defaultMessage: 'Error deleting rule from {jobId} detector'
|
||||
}, { jobId });
|
||||
if (error.message) {
|
||||
errorMessage += ` : ${error.message}`;
|
||||
}
|
||||
|
@ -370,15 +417,22 @@ export class RuleEditorFlyout extends Component {
|
|||
}
|
||||
|
||||
addItemToFilterList = (item, filterId, closeFlyoutOnAdd) => {
|
||||
const { intl } = this.props;
|
||||
addItemToFilter(item, filterId)
|
||||
.then(() => {
|
||||
if (closeFlyoutOnAdd === true) {
|
||||
toastNotifications.add(
|
||||
{
|
||||
title: `Added ${item} to ${filterId}`,
|
||||
title: intl.formatMessage({
|
||||
id: 'xpack.ml.ruleEditor.ruleEditorFlyout.addedItemToFilterListNotificationMessageTitle',
|
||||
defaultMessage: 'Added {item} to {filterId}'
|
||||
}, { item, filterId }),
|
||||
color: 'success',
|
||||
iconType: 'check',
|
||||
text: 'Note that changes will take effect for new results only.'
|
||||
text: intl.formatMessage({
|
||||
id: 'xpack.ml.ruleEditor.ruleEditorFlyout.addedItemToFilterListNotificationMessageDescription',
|
||||
defaultMessage: 'Note that changes will take effect for new results only.'
|
||||
})
|
||||
}
|
||||
);
|
||||
this.closeFlyout();
|
||||
|
@ -386,11 +440,17 @@ export class RuleEditorFlyout extends Component {
|
|||
})
|
||||
.catch((error) => {
|
||||
console.log(`Error adding ${item} to filter ${filterId}:`, error);
|
||||
toastNotifications.addDanger(`An error occurred adding ${item} to filter ${filterId}`);
|
||||
toastNotifications.addDanger(
|
||||
intl.formatMessage({
|
||||
id: 'xpack.ml.ruleEditor.ruleEditorFlyout.errorWithAddingItemToFilterListNotificationMessage',
|
||||
defaultMessage: 'An error occurred adding {item} to filter {filterId}'
|
||||
}, { item, filterId })
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl } = this.props;
|
||||
const {
|
||||
isFlyoutVisible,
|
||||
job,
|
||||
|
@ -417,7 +477,10 @@ export class RuleEditorFlyout extends Component {
|
|||
<EuiFlyoutHeader hasBorder={true}>
|
||||
<EuiTitle size="l">
|
||||
<h1 id="flyoutTitle">
|
||||
Edit Rules
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.editRulesTitle"
|
||||
defaultMessage="Edit Rules"
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</EuiFlyoutHeader>
|
||||
|
@ -441,7 +504,10 @@ export class RuleEditorFlyout extends Component {
|
|||
onClick={this.closeFlyout}
|
||||
flush="left"
|
||||
>
|
||||
Close
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.closeButtonLabel"
|
||||
defaultMessage="Close"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
@ -456,8 +522,10 @@ export class RuleEditorFlyout extends Component {
|
|||
|
||||
const hasPartitioningFields = (this.partitioningFieldNames && this.partitioningFieldNames.length > 0);
|
||||
const conditionSupported = (CONDITIONS_NOT_SUPPORTED_FUNCTIONS.indexOf(anomaly.source.function) === -1);
|
||||
const conditionsText = 'Add numeric conditions for when the rule applies. ' +
|
||||
'Multiple conditions are combined using AND.';
|
||||
const conditionsText = intl.formatMessage({
|
||||
id: 'xpack.ml.ruleEditor.ruleEditorFlyout.conditionsDescription',
|
||||
defaultMessage: 'Add numeric conditions for when the rule applies. Multiple conditions are combined using AND.'
|
||||
});
|
||||
|
||||
flyout = (
|
||||
<EuiFlyout
|
||||
|
@ -468,7 +536,17 @@ export class RuleEditorFlyout extends Component {
|
|||
<EuiFlyoutHeader hasBorder={true}>
|
||||
<EuiTitle size="l">
|
||||
<h1 id="flyoutTitle">
|
||||
{(isCreate === true) ? 'Create Rule' : 'Edit Rule'}
|
||||
{(isCreate === true) ? (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.createRuleTitle"
|
||||
defaultMessage="Create Rule"
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.editRuleTitle"
|
||||
defaultMessage="Edit Rule"
|
||||
/>
|
||||
)}
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</EuiFlyoutHeader>
|
||||
|
@ -482,16 +560,35 @@ export class RuleEditorFlyout extends Component {
|
|||
<EuiSpacer size="m" />
|
||||
<EuiText>
|
||||
<p>
|
||||
Rules instruct anomaly detectors to change their behavior based on domain-specific knowledge that you provide.
|
||||
When you create a rule, you can specify conditions, scope, and actions. When the conditions of a rule are
|
||||
satisfied, its actions are triggered. <EuiLink href={docsUrl} target="_blank">Learn more</EuiLink>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.rulesDescription"
|
||||
defaultMessage="Rules instruct anomaly detectors to change their behavior
|
||||
based on domain-specific knowledge that you provide.
|
||||
When you create a rule, you can specify conditions, scope, and actions. When the conditions of a rule are
|
||||
satisfied, its actions are triggered. {learnMoreLink}"
|
||||
values={{
|
||||
learnMoreLink: (
|
||||
<EuiLink href={docsUrl} target="_blank">
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.rulesDescription.learnMoreLinkText"
|
||||
defaultMessage="Learn more"
|
||||
/>
|
||||
</EuiLink>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
|
||||
<EuiSpacer />
|
||||
|
||||
<EuiTitle>
|
||||
<h2>Action</h2>
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.actionTitle"
|
||||
defaultMessage="Action"
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<ActionsSection
|
||||
actions={rule.actions}
|
||||
|
@ -502,7 +599,12 @@ export class RuleEditorFlyout extends Component {
|
|||
<EuiSpacer size="xl" />
|
||||
|
||||
<EuiTitle>
|
||||
<h2>Conditions</h2>
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.conditionsTitle"
|
||||
defaultMessage="Conditions"
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="s" />
|
||||
{(conditionSupported === true) ?
|
||||
|
@ -517,7 +619,11 @@ export class RuleEditorFlyout extends Component {
|
|||
/>
|
||||
) : (
|
||||
<EuiCallOut
|
||||
title={`Conditions are not supported for detectors using the ${anomaly.source.function} function`}
|
||||
title={<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.conditionsNotSupportedTitle"
|
||||
defaultMessage="Conditions are not supported for detectors using the {functionName} function"
|
||||
values={{ functionName: anomaly.source.function }}
|
||||
/>}
|
||||
iconType="iInCircle"
|
||||
/>
|
||||
)
|
||||
|
@ -543,17 +649,26 @@ export class RuleEditorFlyout extends Component {
|
|||
/>
|
||||
|
||||
<EuiCallOut
|
||||
title="Rerun job"
|
||||
title={<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.rerunJobTitle"
|
||||
defaultMessage="Rerun job"
|
||||
/>}
|
||||
color="warning"
|
||||
iconType="help"
|
||||
>
|
||||
<p>
|
||||
Changes to rules take effect for new results only.
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.whenChangesTakeEffectDescription"
|
||||
defaultMessage="Changes to rules take effect for new results only."
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
To apply these changes to existing results you must clone and rerun the job.
|
||||
Note rerunning the job may take some time and should only be done once
|
||||
you have completed all your changes to the rules for this job.
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.howToApplyChangesToExistingResultsDescription"
|
||||
defaultMessage="To apply these changes to existing results you must clone and rerun the job.
|
||||
Note rerunning the job may take some time and should only be done once
|
||||
you have completed all your changes to the rules for this job."
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
|
||||
|
@ -567,7 +682,10 @@ export class RuleEditorFlyout extends Component {
|
|||
onClick={this.closeFlyout}
|
||||
flush="left"
|
||||
>
|
||||
Close
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.closeButtonLabel"
|
||||
defaultMessage="Close"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
|
@ -576,7 +694,10 @@ export class RuleEditorFlyout extends Component {
|
|||
isDisabled={!isValidRule(rule)}
|
||||
fill
|
||||
>
|
||||
Save
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.ruleEditorFlyout.saveButtonLabel"
|
||||
defaultMessage="Save"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
@ -593,8 +714,4 @@ export class RuleEditorFlyout extends Component {
|
|||
);
|
||||
|
||||
}
|
||||
}
|
||||
RuleEditorFlyout.propTypes = {
|
||||
setShowFunction: PropTypes.func.isRequired,
|
||||
unsetShowFunction: PropTypes.func.isRequired,
|
||||
};
|
||||
});
|
||||
|
|
|
@ -52,7 +52,7 @@ jest.mock('../../privilege/check_privilege', () => ({
|
|||
checkPermission: () => true
|
||||
}));
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import React from 'react';
|
||||
|
||||
import { RuleEditorFlyout } from './rule_editor_flyout';
|
||||
|
@ -84,10 +84,10 @@ function prepareTest() {
|
|||
};
|
||||
|
||||
const component = (
|
||||
<RuleEditorFlyout {...requiredProps} />
|
||||
<RuleEditorFlyout.WrappedComponent {...requiredProps} />
|
||||
);
|
||||
|
||||
const wrapper = shallow(component);
|
||||
const wrapper = shallowWithIntl(component);
|
||||
|
||||
return { wrapper };
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import {
|
|||
|
||||
import { FILTER_TYPE } from '../../../common/constants/detector_rule';
|
||||
import { filterTypeToText } from './utils';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
// Raise the popovers above GuidePageSideNav
|
||||
const POPOVER_STYLE = { zIndex: '200' };
|
||||
|
@ -94,7 +95,12 @@ export class ScopeExpression extends Component {
|
|||
|
||||
return (
|
||||
<div style={POPOVER_STYLE}>
|
||||
<EuiPopoverTitle>Is</EuiPopoverTitle>
|
||||
<EuiPopoverTitle>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.scopeExpression.scopeFilterTypePopoverTitle"
|
||||
defaultMessage="Is"
|
||||
/>
|
||||
</EuiPopoverTitle>
|
||||
<div className="euiExpression">
|
||||
<EuiFlexGroup style={{ maxWidth: 450 }}>
|
||||
<EuiFlexItem grow={false} style={{ width: 150 }}>
|
||||
|
@ -142,7 +148,10 @@ export class ScopeExpression extends Component {
|
|||
<EuiFlexItem grow={false}>
|
||||
<EuiExpression
|
||||
className="scope-field-button"
|
||||
description="when"
|
||||
description={<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.scopeExpression.scopeFieldWhenLabel"
|
||||
defaultMessage="when"
|
||||
/>}
|
||||
value={fieldName}
|
||||
isActive={false}
|
||||
onClick={(event) => event.preventDefault()}
|
||||
|
@ -155,7 +164,11 @@ export class ScopeExpression extends Component {
|
|||
id="operatorValuePopover"
|
||||
button={(
|
||||
<EuiExpression
|
||||
description={`is ${filterTypeToText(filterType)}`}
|
||||
description={<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.scopeExpression.scopeFilterTypeButtonLabel"
|
||||
defaultMessage="is {filterType}"
|
||||
values={{ filterType: filterTypeToText(filterType) }}
|
||||
/>}
|
||||
value={filterId || ''}
|
||||
isActive={this.state.isFilterListOpen}
|
||||
onClick={this.openFilterList}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// Mock the mlJobService that is imported for saving rules.
|
||||
jest.mock('../../services/job_service.js', () => 'mlJobService');
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import React from 'react';
|
||||
|
||||
import { ScopeExpression } from './scope_expression';
|
||||
|
@ -36,7 +36,7 @@ describe('ScopeExpression', () => {
|
|||
enabled: true,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ScopeExpression {...props} />
|
||||
);
|
||||
|
||||
|
@ -50,7 +50,7 @@ describe('ScopeExpression', () => {
|
|||
enabled: true,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ScopeExpression {...props} />
|
||||
);
|
||||
|
||||
|
@ -66,7 +66,7 @@ describe('ScopeExpression', () => {
|
|||
enabled: true,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ScopeExpression {...props} />
|
||||
);
|
||||
|
||||
|
@ -82,7 +82,7 @@ describe('ScopeExpression', () => {
|
|||
enabled: false,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ScopeExpression {...props} />
|
||||
);
|
||||
|
||||
|
|
|
@ -23,18 +23,34 @@ import {
|
|||
import { ScopeExpression } from './scope_expression';
|
||||
import { checkPermission } from '../../privilege/check_privilege';
|
||||
import { getScopeFieldDefaults } from './utils';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
|
||||
function NoFilterListsCallOut() {
|
||||
return (
|
||||
<EuiCallOut
|
||||
title="No filter lists configured"
|
||||
title={<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.scopeSection.noFilterListsConfiguredTitle"
|
||||
defaultMessage="No filter lists configured"
|
||||
/>}
|
||||
iconType="gear"
|
||||
>
|
||||
<p>
|
||||
To configure scope, you must first use the
|
||||
<EuiLink href="#/settings/filter_lists">Filter Lists</EuiLink> settings page
|
||||
to create the list of values you want to include or exclude in the rule.
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.scopeSection.createFilterListsDescription"
|
||||
defaultMessage="To configure scope, you must first use the {filterListsLink} settings page
|
||||
to create the list of values you want to include or exclude in the rule."
|
||||
values={{
|
||||
filterListsLink: (
|
||||
<EuiLink href="#/settings/filter_lists">
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.scopeSection.createFilterListsDescription.filterListsLinkText"
|
||||
defaultMessage="Filter Lists"
|
||||
/>
|
||||
</EuiLink>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
);
|
||||
|
@ -43,7 +59,10 @@ function NoFilterListsCallOut() {
|
|||
function NoPermissionCallOut() {
|
||||
return (
|
||||
<EuiCallOut
|
||||
title="You do not have permission to view filter lists"
|
||||
title={<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.scopeSection.noPermissionToViewFilterListsTitle"
|
||||
defaultMessage="You do not have permission to view filter lists"
|
||||
/>}
|
||||
iconType="gear"
|
||||
/>
|
||||
);
|
||||
|
@ -94,12 +113,20 @@ export function ScopeSection({
|
|||
return (
|
||||
<React.Fragment>
|
||||
<EuiTitle>
|
||||
<h2>Scope</h2>
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.scopeSection.scopeTitle"
|
||||
defaultMessage="Scope"
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiCheckbox
|
||||
id="enable_scope_checkbox"
|
||||
label="Add a filter list to limit where the rule applies."
|
||||
label={<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.scopeSection.addFilterListLabel"
|
||||
defaultMessage="Add a filter list to limit where the rule applies."
|
||||
/>}
|
||||
checked={isEnabled}
|
||||
onChange={onEnabledChange}
|
||||
/>
|
||||
|
|
|
@ -16,7 +16,7 @@ jest.mock('../../privilege/check_privilege', () => ({
|
|||
checkPermission: (privilege) => mockCheckPermission(privilege)
|
||||
}));
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import React from 'react';
|
||||
|
||||
import { ScopeSection } from './scope_section';
|
||||
|
@ -55,7 +55,7 @@ describe('ScopeSection', () => {
|
|||
isEnabled: false,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ScopeSection {...props} />
|
||||
);
|
||||
|
||||
|
@ -69,7 +69,7 @@ describe('ScopeSection', () => {
|
|||
isEnabled: false,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ScopeSection {...props} />
|
||||
);
|
||||
|
||||
|
@ -84,7 +84,7 @@ describe('ScopeSection', () => {
|
|||
isEnabled: true,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ScopeSection {...props} />
|
||||
);
|
||||
|
||||
|
@ -98,7 +98,7 @@ describe('ScopeSection', () => {
|
|||
isEnabled: true,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ScopeSection {...props} />
|
||||
);
|
||||
|
||||
|
@ -113,7 +113,7 @@ describe('ScopeSection', () => {
|
|||
isEnabled: true,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ScopeSection {...props} />
|
||||
);
|
||||
|
||||
|
@ -150,7 +150,7 @@ describe('ScopeSection false canGetFilters privilege', () => {
|
|||
isEnabled: true,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<ScopeSection {...props} />
|
||||
);
|
||||
|
||||
|
|
|
@ -6,9 +6,15 @@ exports[`AddToFilterListLink renders the add to filter list link for a value 1`]
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Add
|
||||
elastic.co
|
||||
to
|
||||
safe_domains
|
||||
<FormattedMessage
|
||||
defaultMessage="Add {fieldValue} to {filterId}"
|
||||
id="xpack.ml.ruleEditor.addValueToFilterListLinkText"
|
||||
values={
|
||||
Object {
|
||||
"fieldValue": "elastic.co",
|
||||
"filterId": "safe_domains",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiLink>
|
||||
`;
|
||||
|
|
|
@ -7,7 +7,11 @@ exports[`DeleteRuleModal renders as delete button after opening and closing moda
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Delete rule
|
||||
<FormattedMessage
|
||||
defaultMessage="Delete rule"
|
||||
id="xpack.ml.ruleEditor.deleteRuleModal.deleteRuleLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>
|
||||
</React.Fragment>
|
||||
`;
|
||||
|
@ -19,7 +23,11 @@ exports[`DeleteRuleModal renders as delete button when not visible 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Delete rule
|
||||
<FormattedMessage
|
||||
defaultMessage="Delete rule"
|
||||
id="xpack.ml.ruleEditor.deleteRuleModal.deleteRuleLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>
|
||||
</React.Fragment>
|
||||
`;
|
||||
|
@ -31,20 +39,46 @@ exports[`DeleteRuleModal renders modal after clicking delete rule link 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Delete rule
|
||||
<FormattedMessage
|
||||
defaultMessage="Delete rule"
|
||||
id="xpack.ml.ruleEditor.deleteRuleModal.deleteRuleLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>
|
||||
<EuiOverlayMask>
|
||||
<EuiConfirmModal
|
||||
buttonColor="primary"
|
||||
cancelButtonText="Cancel"
|
||||
confirmButtonText="Delete"
|
||||
cancelButtonText={
|
||||
<FormattedMessage
|
||||
defaultMessage="Cancel"
|
||||
id="xpack.ml.ruleEditor.deleteRuleModal.cancelButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
confirmButtonText={
|
||||
<FormattedMessage
|
||||
defaultMessage="Delete"
|
||||
id="xpack.ml.ruleEditor.deleteRuleModal.deleteButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
defaultFocusedButton="confirm"
|
||||
onCancel={[Function]}
|
||||
onConfirm={[Function]}
|
||||
title="Delete rule"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Delete rule"
|
||||
id="xpack.ml.ruleEditor.deleteRuleModal.deleteRuleTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
Are you sure you want to delete this rule?
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to delete this rule?"
|
||||
id="xpack.ml.ruleEditor.deleteRuleModal.deleteRuleDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiConfirmModal>
|
||||
</EuiOverlayMask>
|
||||
|
|
|
@ -18,9 +18,15 @@ exports[`EditConditionLink renders for a condition using actual 1`] = `
|
|||
grow={true}
|
||||
size="m"
|
||||
>
|
||||
Update rule condition from
|
||||
5
|
||||
to
|
||||
<FormattedMessage
|
||||
defaultMessage="Update rule condition from {conditionValue} to"
|
||||
id="xpack.ml.ruleEditor.editConditionLink.updateRuleConditionFromText"
|
||||
values={
|
||||
Object {
|
||||
"conditionValue": 5,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
|
@ -48,7 +54,11 @@ exports[`EditConditionLink renders for a condition using actual 1`] = `
|
|||
size="s"
|
||||
type="button"
|
||||
>
|
||||
Update
|
||||
<FormattedMessage
|
||||
defaultMessage="Update"
|
||||
id="xpack.ml.ruleEditor.editConditionLink.updateLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
@ -72,9 +82,15 @@ exports[`EditConditionLink renders for a condition using diff from typical 1`] =
|
|||
grow={true}
|
||||
size="m"
|
||||
>
|
||||
Update rule condition from
|
||||
5
|
||||
to
|
||||
<FormattedMessage
|
||||
defaultMessage="Update rule condition from {conditionValue} to"
|
||||
id="xpack.ml.ruleEditor.editConditionLink.updateRuleConditionFromText"
|
||||
values={
|
||||
Object {
|
||||
"conditionValue": 5,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
|
@ -102,7 +118,11 @@ exports[`EditConditionLink renders for a condition using diff from typical 1`] =
|
|||
size="s"
|
||||
type="button"
|
||||
>
|
||||
Update
|
||||
<FormattedMessage
|
||||
defaultMessage="Update"
|
||||
id="xpack.ml.ruleEditor.editConditionLink.updateLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
@ -126,9 +146,15 @@ exports[`EditConditionLink renders for a condition using typical 1`] = `
|
|||
grow={true}
|
||||
size="m"
|
||||
>
|
||||
Update rule condition from
|
||||
5
|
||||
to
|
||||
<FormattedMessage
|
||||
defaultMessage="Update rule condition from {conditionValue} to"
|
||||
id="xpack.ml.ruleEditor.editConditionLink.updateRuleConditionFromText"
|
||||
values={
|
||||
Object {
|
||||
"conditionValue": 5,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
|
@ -156,7 +182,11 @@ exports[`EditConditionLink renders for a condition using typical 1`] = `
|
|||
size="s"
|
||||
type="button"
|
||||
>
|
||||
Update
|
||||
<FormattedMessage
|
||||
defaultMessage="Update"
|
||||
id="xpack.ml.ruleEditor.editConditionLink.updateLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -14,10 +14,14 @@ exports[`RuleActionPanel renders panel for rule with a condition 1`] = `
|
|||
Array [
|
||||
Object {
|
||||
"description": "skip result when actual is less than 1",
|
||||
"title": "rule",
|
||||
"title": <FormattedMessage
|
||||
defaultMessage="rule"
|
||||
id="xpack.ml.ruleEditor.ruleActionPanel.ruleTitle"
|
||||
values={Object {}}
|
||||
/>,
|
||||
},
|
||||
Object {
|
||||
"description": <EditConditionLink
|
||||
"description": <InjectIntl(EditConditionLink)
|
||||
anomaly={
|
||||
Object {
|
||||
"actual": Array [
|
||||
|
@ -48,7 +52,11 @@ exports[`RuleActionPanel renders panel for rule with a condition 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Edit rule
|
||||
<FormattedMessage
|
||||
defaultMessage="Edit rule"
|
||||
id="xpack.ml.ruleEditor.ruleActionPanel.editRuleLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
"title": "",
|
||||
},
|
||||
|
@ -81,7 +89,11 @@ exports[`RuleActionPanel renders panel for rule with a condition and scope, valu
|
|||
Array [
|
||||
Object {
|
||||
"description": "skip model update when airline is not in eu-airlines",
|
||||
"title": "rule",
|
||||
"title": <FormattedMessage
|
||||
defaultMessage="rule"
|
||||
id="xpack.ml.ruleEditor.ruleActionPanel.ruleTitle"
|
||||
values={Object {}}
|
||||
/>,
|
||||
},
|
||||
Object {
|
||||
"description": <AddToFilterListLink
|
||||
|
@ -97,7 +109,11 @@ exports[`RuleActionPanel renders panel for rule with a condition and scope, valu
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Edit rule
|
||||
<FormattedMessage
|
||||
defaultMessage="Edit rule"
|
||||
id="xpack.ml.ruleEditor.ruleActionPanel.editRuleLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
"title": "",
|
||||
},
|
||||
|
@ -130,7 +146,11 @@ exports[`RuleActionPanel renders panel for rule with scope, value in filter list
|
|||
Array [
|
||||
Object {
|
||||
"description": "skip model update when airline is not in eu-airlines",
|
||||
"title": "rule",
|
||||
"title": <FormattedMessage
|
||||
defaultMessage="rule"
|
||||
id="xpack.ml.ruleEditor.ruleActionPanel.ruleTitle"
|
||||
values={Object {}}
|
||||
/>,
|
||||
},
|
||||
Object {
|
||||
"description": <EuiLink
|
||||
|
@ -138,7 +158,11 @@ exports[`RuleActionPanel renders panel for rule with scope, value in filter list
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Edit rule
|
||||
<FormattedMessage
|
||||
defaultMessage="Edit rule"
|
||||
id="xpack.ml.ruleEditor.ruleActionPanel.editRuleLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
"title": "actions",
|
||||
},
|
||||
|
|
|
@ -16,6 +16,7 @@ import React from 'react';
|
|||
import {
|
||||
EuiLink,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
export function AddToFilterListLink({
|
||||
fieldValue,
|
||||
|
@ -27,7 +28,11 @@ export function AddToFilterListLink({
|
|||
<EuiLink
|
||||
onClick={() => addItemToFilterList(fieldValue, filterId, true)}
|
||||
>
|
||||
Add {fieldValue} to {filterId}
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.addValueToFilterListLinkText"
|
||||
defaultMessage="Add {fieldValue} to {filterId}"
|
||||
values={{ fieldValue, filterId }}
|
||||
/>
|
||||
</EuiLink>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import React from 'react';
|
||||
|
||||
import { AddToFilterListLink } from './add_to_filter_list_link';
|
||||
|
@ -15,7 +15,7 @@ describe('AddToFilterListLink', () => {
|
|||
test(`renders the add to filter list link for a value`, () => {
|
||||
const addItemToFilterList = jest.fn(() => {});
|
||||
|
||||
const wrapper = shallow(
|
||||
const wrapper = shallowWithIntl(
|
||||
<AddToFilterListLink
|
||||
fieldValue="elastic.co"
|
||||
filterId="safe_domains"
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
EuiOverlayMask,
|
||||
EUI_MODAL_CONFIRM_BUTTON,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
export class DeleteRuleModal extends Component {
|
||||
constructor(props) {
|
||||
|
@ -51,14 +52,28 @@ export class DeleteRuleModal extends Component {
|
|||
modal = (
|
||||
<EuiOverlayMask>
|
||||
<EuiConfirmModal
|
||||
title="Delete rule"
|
||||
title={<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.deleteRuleModal.deleteRuleTitle"
|
||||
defaultMessage="Delete rule"
|
||||
/>}
|
||||
onCancel={this.closeModal}
|
||||
onConfirm={this.deleteRule}
|
||||
cancelButtonText="Cancel"
|
||||
confirmButtonText="Delete"
|
||||
cancelButtonText={<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.deleteRuleModal.cancelButtonLabel"
|
||||
defaultMessage="Cancel"
|
||||
/>}
|
||||
confirmButtonText={<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.deleteRuleModal.deleteButtonLabel"
|
||||
defaultMessage="Delete"
|
||||
/>}
|
||||
defaultFocusedButton={EUI_MODAL_CONFIRM_BUTTON}
|
||||
>
|
||||
<p>Are you sure you want to delete this rule?</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.deleteRuleModal.deleteRuleDescription"
|
||||
defaultMessage="Are you sure you want to delete this rule?"
|
||||
/>
|
||||
</p>
|
||||
</EuiConfirmModal>
|
||||
</EuiOverlayMask>
|
||||
);
|
||||
|
@ -70,7 +85,10 @@ export class DeleteRuleModal extends Component {
|
|||
color="danger"
|
||||
onClick={() => this.showModal()}
|
||||
>
|
||||
Delete rule
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.deleteRuleModal.deleteRuleLinkText"
|
||||
defaultMessage="Delete rule"
|
||||
/>
|
||||
</EuiLink>
|
||||
{modal}
|
||||
</React.Fragment>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import React from 'react';
|
||||
|
||||
import { DeleteRuleModal } from './delete_rule_modal';
|
||||
|
@ -24,7 +24,7 @@ describe('DeleteRuleModal', () => {
|
|||
...requiredProps,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<DeleteRuleModal {...props} />
|
||||
);
|
||||
|
||||
|
@ -37,7 +37,7 @@ describe('DeleteRuleModal', () => {
|
|||
...requiredProps,
|
||||
};
|
||||
|
||||
const wrapper = shallow(<DeleteRuleModal {...props} />);
|
||||
const wrapper = shallowWithIntl(<DeleteRuleModal {...props} />);
|
||||
wrapper.find('EuiLink').simulate('click');
|
||||
wrapper.update();
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
@ -49,7 +49,7 @@ describe('DeleteRuleModal', () => {
|
|||
...requiredProps,
|
||||
};
|
||||
|
||||
const wrapper = shallow(<DeleteRuleModal {...props} />);
|
||||
const wrapper = shallowWithIntl(<DeleteRuleModal {...props} />);
|
||||
wrapper.find('EuiLink').simulate('click');
|
||||
const instance = wrapper.instance();
|
||||
instance.closeModal();
|
||||
|
|
|
@ -28,8 +28,21 @@ import { formatValue } from '../../../formatters/format_value';
|
|||
import {
|
||||
getAppliesToValueFromAnomaly,
|
||||
} from '../utils';
|
||||
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
||||
|
||||
export const EditConditionLink = injectI18n(class EditConditionLink extends Component {
|
||||
static propTypes = {
|
||||
conditionIndex: PropTypes.number.isRequired,
|
||||
conditionValue: PropTypes.number.isRequired,
|
||||
appliesTo: PropTypes.oneOf([
|
||||
APPLIES_TO.ACTUAL,
|
||||
APPLIES_TO.TYPICAL,
|
||||
APPLIES_TO.DIFF_FROM_TYPICAL
|
||||
]),
|
||||
anomaly: PropTypes.object.isRequired,
|
||||
updateConditionValue: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export class EditConditionLink extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
|
@ -62,21 +75,32 @@ export class EditConditionLink extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { intl } = this.props;
|
||||
const value = this.state.value;
|
||||
return (
|
||||
<EuiFlexGroup alignItems="center" gutterSize="s">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText>
|
||||
Update rule condition from {this.props.conditionValue} to
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.editConditionLink.updateRuleConditionFromText"
|
||||
defaultMessage="Update rule condition from {conditionValue} to"
|
||||
values={{ conditionValue: this.props.conditionValue }}
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false} className="condition-edit-value-field">
|
||||
<EuiFieldNumber
|
||||
placeholder="Enter value"
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'xpack.ml.ruleEditor.editConditionLink.enterValuePlaceholder',
|
||||
defaultMessage: 'Enter value'
|
||||
})}
|
||||
compressed={true}
|
||||
value={value}
|
||||
onChange={this.onChangeValue}
|
||||
aria-label="Enter numeric value for condition"
|
||||
aria-label={intl.formatMessage({
|
||||
id: 'xpack.ml.ruleEditor.editConditionLink.enterNumericValueForConditionAriaLabel',
|
||||
defaultMessage: 'Enter numeric value for condition'
|
||||
})}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
{value !== '' &&
|
||||
|
@ -85,22 +109,14 @@ export class EditConditionLink extends Component {
|
|||
size="s"
|
||||
onClick={() => this.onUpdateClick()}
|
||||
>
|
||||
Update
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.editConditionLink.updateLinkText"
|
||||
defaultMessage="Update"
|
||||
/>
|
||||
</EuiLink>
|
||||
</EuiFlexItem>
|
||||
}
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
}
|
||||
}
|
||||
EditConditionLink.propTypes = {
|
||||
conditionIndex: PropTypes.number.isRequired,
|
||||
conditionValue: PropTypes.number.isRequired,
|
||||
appliesTo: PropTypes.oneOf([
|
||||
APPLIES_TO.ACTUAL,
|
||||
APPLIES_TO.TYPICAL,
|
||||
APPLIES_TO.DIFF_FROM_TYPICAL
|
||||
]),
|
||||
anomaly: PropTypes.object.isRequired,
|
||||
updateConditionValue: PropTypes.func.isRequired,
|
||||
};
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
jest.mock('../../../services/job_service.js', () => 'mlJobService');
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import React from 'react';
|
||||
|
||||
import { EditConditionLink } from './edit_condition_link';
|
||||
|
@ -32,8 +32,8 @@ function prepareTest(updateConditionValueFn, appliesTo) {
|
|||
updateConditionValue: updateConditionValueFn,
|
||||
};
|
||||
|
||||
const wrapper = shallow(
|
||||
<EditConditionLink {...props} />
|
||||
const wrapper = shallowWithIntl(
|
||||
<EditConditionLink.WrappedComponent {...props} />
|
||||
);
|
||||
|
||||
return wrapper;
|
||||
|
|
|
@ -27,6 +27,7 @@ import { DeleteRuleModal } from './delete_rule_modal';
|
|||
import { EditConditionLink } from './edit_condition_link';
|
||||
import { buildRuleDescription } from '../utils';
|
||||
import { ml } from '../../../services/ml_api_service';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
|
||||
export class RuleActionPanel extends Component {
|
||||
|
@ -86,7 +87,10 @@ export class RuleActionPanel extends Component {
|
|||
<EuiLink
|
||||
onClick={() => setEditRuleIndex(ruleIndex)}
|
||||
>
|
||||
Edit rule
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.ruleActionPanel.editRuleLinkText"
|
||||
defaultMessage="Edit rule"
|
||||
/>
|
||||
</EuiLink>
|
||||
);
|
||||
}
|
||||
|
@ -168,7 +172,7 @@ export class RuleActionPanel extends Component {
|
|||
// Add items for the standard Edit and Delete links.
|
||||
const descriptionListItems = [
|
||||
{
|
||||
title: 'rule',
|
||||
title: (<FormattedMessage id="xpack.ml.ruleEditor.ruleActionPanel.ruleTitle" defaultMessage="rule" />),
|
||||
description: buildRuleDescription(this.rule, this.props.anomaly),
|
||||
},
|
||||
{
|
||||
|
|
|
@ -28,7 +28,7 @@ jest.mock('../../../services/ml_api_service', () => ({
|
|||
}
|
||||
}));
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import React from 'react';
|
||||
|
||||
import { RuleActionPanel } from './rule_action_panel';
|
||||
|
@ -122,7 +122,7 @@ describe('RuleActionPanel', () => {
|
|||
ruleIndex: 0,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<RuleActionPanel {...props} />
|
||||
);
|
||||
|
||||
|
@ -136,7 +136,7 @@ describe('RuleActionPanel', () => {
|
|||
ruleIndex: 1,
|
||||
};
|
||||
|
||||
const component = shallow(
|
||||
const component = shallowWithIntl(
|
||||
<RuleActionPanel {...props} />
|
||||
);
|
||||
|
||||
|
@ -150,7 +150,7 @@ describe('RuleActionPanel', () => {
|
|||
ruleIndex: 1,
|
||||
};
|
||||
|
||||
const wrapper = shallow(
|
||||
const wrapper = shallowWithIntl(
|
||||
<RuleActionPanel {...props} />
|
||||
);
|
||||
wrapper.setState({ showAddToFilterListLink: true });
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
|
||||
import { DetectorDescriptionList } from '../components/detector_description_list';
|
||||
import { RuleActionPanel } from './rule_action_panel';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
export function SelectRuleAction({
|
||||
job,
|
||||
|
@ -66,14 +66,20 @@ export function SelectRuleAction({
|
|||
{ruleActionPanels}
|
||||
<EuiSpacer size="m" />
|
||||
<EuiText style={{ display: 'inline' }}>
|
||||
or
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.selectRuleAction.orText"
|
||||
defaultMessage="or "
|
||||
/>
|
||||
</EuiText>
|
||||
</React.Fragment>
|
||||
}
|
||||
<EuiLink
|
||||
onClick={() => setEditRuleIndex(rules.length)}
|
||||
>
|
||||
create a rule
|
||||
<FormattedMessage
|
||||
id="xpack.ml.ruleEditor.selectRuleAction.createRuleLinkText"
|
||||
defaultMessage="create a rule"
|
||||
/>
|
||||
</EuiLink>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -14,6 +14,7 @@ import {
|
|||
import { cloneDeep } from 'lodash';
|
||||
import { ml } from '../../services/ml_api_service';
|
||||
import { mlJobService } from '../../services/job_service';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export function getNewConditionDefaults() {
|
||||
return {
|
||||
|
@ -111,7 +112,14 @@ export function deleteJobRule(job, detectorIndex, ruleIndex) {
|
|||
return updateJobRules(job, detectorIndex, customRules);
|
||||
} else {
|
||||
return Promise.reject(new Error(
|
||||
`Rule no longer exists for detector index ${detectorIndex} in job ${job.job_id}`));
|
||||
i18n.translate('xpack.ml.ruleEditor.deleteJobRule.ruleNoLongerExistsErrorMessage', {
|
||||
defaultMessage: 'Rule no longer exists for detector index {detectorIndex} in job {jobId}',
|
||||
values: {
|
||||
detectorIndex,
|
||||
jobId: job.job_id
|
||||
}
|
||||
})
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,57 +187,85 @@ export function addItemToFilter(item, filterId) {
|
|||
|
||||
export function buildRuleDescription(rule) {
|
||||
const { actions, conditions, scope } = rule;
|
||||
let description = 'skip ';
|
||||
let actionsText = '';
|
||||
let conditionsText = '';
|
||||
let filtersText = '';
|
||||
|
||||
actions.forEach((action, i) => {
|
||||
if (i > 0) {
|
||||
description += ' AND ';
|
||||
actionsText += ' AND ';
|
||||
}
|
||||
switch (action) {
|
||||
case ACTION.SKIP_RESULT:
|
||||
description += 'result';
|
||||
actionsText += i18n.translate('xpack.ml.ruleEditor.ruleDescription.resultActionTypeText', {
|
||||
defaultMessage: 'result',
|
||||
description: 'Part of composite text: xpack.ml.ruleEditor.ruleDescription.[actionName]ActionTypeText +' +
|
||||
'xpack.ml.ruleEditor.ruleDescription.conditionsText + xpack.ml.ruleEditor.ruleDescription.filtersText'
|
||||
});
|
||||
break;
|
||||
case ACTION.SKIP_MODEL_UPDATE:
|
||||
description += 'model update';
|
||||
actionsText += i18n.translate('xpack.ml.ruleEditor.ruleDescription.modelUpdateActionTypeText', {
|
||||
defaultMessage: 'model update',
|
||||
description: 'Part of composite text: xpack.ml.ruleEditor.ruleDescription.[actionName]ActionTypeText + ' +
|
||||
'xpack.ml.ruleEditor.ruleDescription.conditionsText + xpack.ml.ruleEditor.ruleDescription.filtersText'
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
description += ' when ';
|
||||
if (conditions !== undefined) {
|
||||
conditions.forEach((condition, i) => {
|
||||
if (i > 0) {
|
||||
description += ' AND ';
|
||||
conditionsText += ' AND ';
|
||||
}
|
||||
|
||||
description += `${appliesToText(condition.applies_to)} is ${operatorToText(condition.operator)} ${condition.value}`;
|
||||
conditionsText += i18n.translate('xpack.ml.ruleEditor.ruleDescription.conditionsText', {
|
||||
defaultMessage: '{appliesTo} is {operator} {value}',
|
||||
values: { appliesTo: appliesToText(condition.applies_to), operator: operatorToText(condition.operator), value: condition.value },
|
||||
description: 'Part of composite text: xpack.ml.ruleEditor.ruleDescription.[actionName]ActionTypeText + ' +
|
||||
'xpack.ml.ruleEditor.ruleDescription.conditionsText + xpack.ml.ruleEditor.ruleDescription.filtersText'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (scope !== undefined) {
|
||||
if (conditions !== undefined && conditions.length > 0) {
|
||||
description += ' AND ';
|
||||
filtersText += ' AND ';
|
||||
}
|
||||
const fieldNames = Object.keys(scope);
|
||||
fieldNames.forEach((fieldName, i) => {
|
||||
if (i > 0) {
|
||||
description += ' AND ';
|
||||
filtersText += ' AND ';
|
||||
}
|
||||
|
||||
const filter = scope[fieldName];
|
||||
description += `${fieldName} is ${filterTypeToText(filter.filter_type)} ${filter.filter_id}`;
|
||||
filtersText += i18n.translate('xpack.ml.ruleEditor.ruleDescription.filtersText', {
|
||||
defaultMessage: '{fieldName} is {filterType} {filterId}',
|
||||
values: { fieldName, filterType: filterTypeToText(filter.filter_type), filterId: filter.filter_id },
|
||||
description: 'Part of composite text: xpack.ml.ruleEditor.ruleDescription.[actionName]ActionTypeText + ' +
|
||||
'xpack.ml.ruleEditor.ruleDescription.conditionsText + xpack.ml.ruleEditor.ruleDescription.filtersText'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return description;
|
||||
return i18n.translate('xpack.ml.ruleEditor.ruleDescription', {
|
||||
defaultMessage: 'skip {actions} when {conditions}{filters}',
|
||||
values: {
|
||||
actions: actionsText,
|
||||
conditions: conditionsText,
|
||||
filters: filtersText
|
||||
},
|
||||
description: 'Composite text: xpack.ml.ruleEditor.ruleDescription.[actionName]ActionTypeText + ' +
|
||||
'xpack.ml.ruleEditor.ruleDescription.conditionsText + xpack.ml.ruleEditor.ruleDescription.filtersText.' +
|
||||
' (Example: skip model update when actual is less than 1 AND ip is in xxx)'
|
||||
});
|
||||
}
|
||||
|
||||
export function filterTypeToText(filterType) {
|
||||
switch (filterType) {
|
||||
case FILTER_TYPE.INCLUDE:
|
||||
return 'in';
|
||||
|
||||
return i18n.translate('xpack.ml.ruleEditor.includeFilterTypeText', { defaultMessage: 'in' });
|
||||
case FILTER_TYPE.EXCLUDE:
|
||||
return 'not in';
|
||||
return i18n.translate('xpack.ml.ruleEditor.excludeFilterTypeText', { defaultMessage: 'not in' });
|
||||
|
||||
default:
|
||||
return (filterType !== undefined) ? filterType : '';
|
||||
|
@ -239,13 +275,12 @@ export function filterTypeToText(filterType) {
|
|||
export function appliesToText(appliesTo) {
|
||||
switch (appliesTo) {
|
||||
case APPLIES_TO.ACTUAL:
|
||||
return 'actual';
|
||||
|
||||
return i18n.translate('xpack.ml.ruleEditor.actualAppliesTypeText', { defaultMessage: 'actual' });
|
||||
case APPLIES_TO.TYPICAL:
|
||||
return 'typical';
|
||||
return i18n.translate('xpack.ml.ruleEditor.typicalAppliesTypeText', { defaultMessage: 'typical' });
|
||||
|
||||
case APPLIES_TO.DIFF_FROM_TYPICAL:
|
||||
return 'diff from typical';
|
||||
return i18n.translate('xpack.ml.ruleEditor.diffFromTypicalAppliesTypeText', { defaultMessage: 'diff from typical' });
|
||||
|
||||
default:
|
||||
return (appliesTo !== undefined) ? appliesTo : '';
|
||||
|
@ -255,16 +290,16 @@ export function appliesToText(appliesTo) {
|
|||
export function operatorToText(operator) {
|
||||
switch (operator) {
|
||||
case OPERATOR.LESS_THAN:
|
||||
return 'less than';
|
||||
return i18n.translate('xpack.ml.ruleEditor.lessThanOperatorTypeText', { defaultMessage: 'less than' });
|
||||
|
||||
case OPERATOR.LESS_THAN_OR_EQUAL:
|
||||
return 'less than or equal to';
|
||||
return i18n.translate('xpack.ml.ruleEditor.lessThanOrEqualToOperatorTypeText', { defaultMessage: 'less than or equal to' });
|
||||
|
||||
case OPERATOR.GREATER_THAN:
|
||||
return 'greater than';
|
||||
return i18n.translate('xpack.ml.ruleEditor.greaterThanOperatorTypeText', { defaultMessage: 'greater than' });
|
||||
|
||||
case OPERATOR.GREATER_THAN_OR_EQUAL:
|
||||
return 'greater than or equal to';
|
||||
return i18n.translate('xpack.ml.ruleEditor.greaterThanOrEqualToOperatorTypeText', { defaultMessage: 'greater than or equal to' });
|
||||
|
||||
default:
|
||||
return (operator !== undefined) ? operator : '';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue