mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Security Solution] Update prebuilt rule customization UI copy (#210817)
**Resolves: https://github.com/elastic/security-docs/issues/6238** **Deployed here: [link](https://nikitaindik-pr-210817-prebuilt-rule-customization-update-ui.kbndev.co/app/security/rules/updates?rulesTable=(field:name,order:asc,searchTerm:'Shared%20Object%20Created%20or%20Changed%20by%20Previously%20Unknown%20Process')&sourcerer=(default:(id:security-solution-default,selectedPatterns:!()))&timerange=(global:(linkTo:!(timeline),timerange:(from:'2025-02-11T23:00:00.000Z',fromStr:now/d,kind:absolute,to:'2025-02-12T22:59:59.999Z',toStr:now/d)),timeline:(linkTo:!(global),timerange:(from:'2025-02-11T23:00:00.000Z',fromStr:now/d,kind:absolute,to:'2025-02-12T22:59:59.999Z',toStr:now/d)))&timeline=(activeTab:query,graphEventId:'',isOpen:!f))** > ⚠️ CI fails are caused by an issue unrelated to this PR ## Summary Changes in this PR: - UI copy is updated in accordance with [recommendations](https://docs.google.com/document/d/1Yl6DyN9pertqgB-iIKIEN3xdvlDM50oscJ00G-WwtyA/edit?tab=t.0) (internal link) from Security Documentation team - Text color for "No update" fields in upgrade flyout changed from green to default. - Fixed a minor bug with placeholder not displaying for "Setup guide" and "Investigation guide" fields on Rule Creation/Editing page <details> <summary><strong>A few screenshots taken in Serverless</strong> (click to expand)</summary> <img width="523" alt="serverless_rep_tooltip" src="https://github.com/user-attachments/assets/825e1514-a191-45c2-90ca-0f15a8c9da7b" /> <img width="836" alt="serverless_bulk_action_error" src="https://github.com/user-attachments/assets/8aa38c77-5aaa-49cf-9b4e-8c992382a1d2" /> <img width="1102" alt="serverless_upgrade_callout" src="https://github.com/user-attachments/assets/cf947c73-d52d-4c85-abd6-369f616b8421" /> <img width="1004" alt="no_update_white" src="https://github.com/user-attachments/assets/f720f24c-0c97-432f-b2d5-7ff7e5919ba0" /> </details> ## Testing You can use [this deployment](https://nikitaindik-pr-210817-prebuilt-rule-customization-update-ui.kbndev.co) (default credentials) test to changes on ESS Enterprise license. Here's a couple rules that has field updates of different kinds: - Unusual User Privilege Enumeration via id - Shared Object Created or Changed by Previously Unknown Process To test on Serverless or with other licenses, you'll need to run it locally. Reach out to me if you need help with this. Work started: 11-Feb-2025
This commit is contained in:
parent
1f35d7ac7f
commit
994201ce87
34 changed files with 225 additions and 153 deletions
|
@ -34935,8 +34935,6 @@
|
|||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.guideLabel": "Guide d'investigation",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.maxAlertsFieldLessThanWarning": "Kibana ne permet qu'un maximum de {maxNumber} {maxNumber, plural, =1 {alerte} other {alertes}} par exécution de règle.",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.nameFieldRequiredError": "Nom obligatoire.",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutrule.noteHelpText": "Ajouter un guide d'investigation sur les règles...",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutrule.setupHelpText": "Ajouter le guide de configuration de règle...",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupHelpText": "Fournissez des instructions sur les conditions préalables à la règle, telles que les intégrations requises, les étapes de configuration et tout ce qui est nécessaire au bon fonctionnement de la règle.",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupLabel": "Guide de configuration",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.tagFieldEmptyError": "Une balise ne doit pas être vide",
|
||||
|
|
|
@ -34796,8 +34796,6 @@
|
|||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.guideLabel": "調査ガイド",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.maxAlertsFieldLessThanWarning": "Kibanaで許可される最大数は、1回の実行につき、{maxNumber} {maxNumber, plural, other {アラート}}です。",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.nameFieldRequiredError": "名前が必要です。",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutrule.noteHelpText": "ルール調査ガイドを追加...",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutrule.setupHelpText": "ルールセットアップガイドを追加...",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupHelpText": "必要な統合、構成ステップ、ルールが正常に動作するために必要な他のすべての項目といった、ルール前提条件に関する指示を入力します。",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupLabel": "セットアップガイド",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.tagFieldEmptyError": "タグを空にすることはできません",
|
||||
|
|
|
@ -34266,8 +34266,6 @@
|
|||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.guideLabel": "调查指南",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.maxAlertsFieldLessThanWarning": "每次规则运行时,Kibana 最多只允许 {maxNumber} 个{maxNumber, plural, other {告警}}。",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.nameFieldRequiredError": "名称必填。",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutrule.noteHelpText": "添加规则调查指南......",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutrule.setupHelpText": "添加规则设置指南......",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupHelpText": "提供有关规则先决条件的说明,如所需集成、配置步骤,以及规则正常运行所需的任何其他内容。",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupLabel": "设置指南",
|
||||
"xpack.securitySolution.detectionEngine.createRule.stepAboutRule.tagFieldEmptyError": "标签不得为空",
|
||||
|
|
|
@ -55,10 +55,27 @@ export const UPGRADE_NOTES_MANAGEMENT_USER_FILTER = (requiredLicense: string) =>
|
|||
},
|
||||
});
|
||||
|
||||
export const UPGRADE_PREBUILT_RULE_CUSTOMIZATION = (requiredLicense: string) =>
|
||||
export const PREBUILT_RULE_CUSTOMIZATION = (requiredLicense: string, licenseKind: string) =>
|
||||
i18n.translate('securitySolutionPackages.ruleManagement.prebuiltRuleCustomization.upsell', {
|
||||
defaultMessage: 'Upgrade to {requiredLicense} to enable prebuilt rule customization',
|
||||
defaultMessage: '{requiredLicense} {licenseKind} is required to customize prebuilt rules',
|
||||
values: {
|
||||
requiredLicense,
|
||||
licenseKind,
|
||||
},
|
||||
});
|
||||
|
||||
export const PREBUILT_RULE_CUSTOMIZATION_DESCRIPTION = (
|
||||
requiredLicense: string,
|
||||
licenseKind: string
|
||||
) =>
|
||||
i18n.translate(
|
||||
'securitySolutionPackages.ruleManagement.prebuiltRuleCustomization.descriptionUpsell',
|
||||
{
|
||||
defaultMessage:
|
||||
"Without the {requiredLicense} {licenseKind}, prebuilt rules can't be customized. To access this feature, upgrade your {licenseKind} or contact your admin for assistance.",
|
||||
values: {
|
||||
requiredLicense,
|
||||
licenseKind,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
|
@ -29,4 +29,5 @@ export type UpsellingMessageId =
|
|||
| 'alert_suppression_rule_form'
|
||||
| 'alert_suppression_rule_details'
|
||||
| 'note_management_user_filter'
|
||||
| 'prebuilt_rule_customization';
|
||||
| 'prebuilt_rule_customization'
|
||||
| 'prebuilt_rule_customization_description';
|
||||
|
|
|
@ -34,6 +34,7 @@ interface MarkdownEditorProps {
|
|||
autoFocusDisabled?: boolean;
|
||||
setIsMarkdownInvalid: (value: boolean) => void;
|
||||
includePlugins?: boolean;
|
||||
placeholder?: string;
|
||||
}
|
||||
|
||||
type EuiMarkdownEditorRef = ElementRef<typeof EuiMarkdownEditor>;
|
||||
|
@ -56,6 +57,7 @@ const MarkdownEditorComponent = forwardRef<MarkdownEditorRef, MarkdownEditorProp
|
|||
autoFocusDisabled,
|
||||
setIsMarkdownInvalid,
|
||||
includePlugins = true,
|
||||
placeholder,
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
|
@ -118,6 +120,7 @@ const MarkdownEditorComponent = forwardRef<MarkdownEditorRef, MarkdownEditorProp
|
|||
errors={markdownErrorMessages}
|
||||
data-test-subj={dataTestSubj}
|
||||
height={height}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ type MarkdownEditorFormProps = EuiMarkdownEditorProps & {
|
|||
|
||||
export const MarkdownEditorForm = React.memo(
|
||||
forwardRef<MarkdownEditorRef, MarkdownEditorFormProps>(
|
||||
({ field, dataTestSubj, idAria, includePlugins }, ref) => {
|
||||
({ field, dataTestSubj, idAria, includePlugins, placeholder }, ref) => {
|
||||
const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field);
|
||||
const [isMarkdownInvalid, setIsMarkdownInvalid] = useState(false);
|
||||
|
||||
|
@ -48,6 +48,7 @@ export const MarkdownEditorForm = React.memo(
|
|||
data-test-subj={`${dataTestSubj}-markdown-editor`}
|
||||
setIsMarkdownInvalid={setIsMarkdownInvalid}
|
||||
includePlugins={includePlugins}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
);
|
||||
|
|
|
@ -196,7 +196,7 @@ export const BUILDING_BLOCK_LABEL = i18n.translate(
|
|||
export const BUILDING_BLOCK_DESCRIPTION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.ruleDescription.buildingBlockDescription',
|
||||
{
|
||||
defaultMessage: 'All generated alerts will be marked as "building block" alerts',
|
||||
defaultMessage: 'All generated alerts will be marked as building block alerts',
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -284,7 +284,7 @@ const StepAboutRuleComponent: FC<StepAboutRuleProps> = ({
|
|||
<EuiToolTip
|
||||
content={
|
||||
ruleSource?.type === 'external'
|
||||
? I18n.AUTHOR_IMMUTABLE_FIELD_TOOLTIP_TEXT
|
||||
? I18n.FIELD_NOT_EDITABLE_TOOLTIP_TEXT(I18n.AUTHOR_FIELD_LABEL)
|
||||
: undefined
|
||||
}
|
||||
display="block"
|
||||
|
@ -307,7 +307,7 @@ const StepAboutRuleComponent: FC<StepAboutRuleProps> = ({
|
|||
<EuiToolTip
|
||||
content={
|
||||
ruleSource?.type === 'external'
|
||||
? I18n.LICENSE_IMMUTABLE_FIELD_TOOLTIP_TEXT
|
||||
? I18n.FIELD_NOT_EDITABLE_TOOLTIP_TEXT(I18n.LICENSE_FIELD_LABEL)
|
||||
: undefined
|
||||
}
|
||||
display="block"
|
||||
|
|
|
@ -29,12 +29,7 @@ const { emptyField } = fieldValidators;
|
|||
export const schema: FormSchema<AboutStepRule> = {
|
||||
author: {
|
||||
type: FIELD_TYPES.COMBO_BOX,
|
||||
label: i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldAuthorLabel',
|
||||
{
|
||||
defaultMessage: 'Author',
|
||||
}
|
||||
),
|
||||
label: I18n.AUTHOR_FIELD_LABEL,
|
||||
helpText: i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldAuthorHelpText',
|
||||
{
|
||||
|
@ -209,12 +204,7 @@ export const schema: FormSchema<AboutStepRule> = {
|
|||
},
|
||||
license: {
|
||||
type: FIELD_TYPES.TEXT,
|
||||
label: i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldLicenseLabel',
|
||||
{
|
||||
defaultMessage: 'License',
|
||||
}
|
||||
),
|
||||
label: I18n.LICENSE_FIELD_LABEL,
|
||||
helpText: i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldLicenseHelpText',
|
||||
{
|
||||
|
|
|
@ -85,29 +85,40 @@ export const URL_FORMAT_INVALID = i18n.translate(
|
|||
);
|
||||
|
||||
export const ADD_RULE_NOTE_HELP_TEXT = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.createRule.stepAboutrule.noteHelpText',
|
||||
'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.noteHelpText',
|
||||
{
|
||||
defaultMessage: 'Add rule investigation guide...',
|
||||
}
|
||||
);
|
||||
|
||||
export const ADD_RULE_SETUP_HELP_TEXT = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.createRule.stepAboutrule.setupHelpText',
|
||||
'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.addRuleSetupHelpText',
|
||||
{
|
||||
defaultMessage: 'Add rule setup guide...',
|
||||
}
|
||||
);
|
||||
|
||||
export const AUTHOR_IMMUTABLE_FIELD_TOOLTIP_TEXT = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.createRule.stepAboutrule.authorImmutableFieldTooltipText',
|
||||
export const AUTHOR_FIELD_LABEL = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldAuthorLabel',
|
||||
{
|
||||
defaultMessage: 'Author is not editable for Elastic rules',
|
||||
defaultMessage: 'Author',
|
||||
}
|
||||
);
|
||||
|
||||
export const LICENSE_IMMUTABLE_FIELD_TOOLTIP_TEXT = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.createRule.stepAboutrule.licenseImmutableFieldTooltipText',
|
||||
export const LICENSE_FIELD_LABEL = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldLicenseLabel',
|
||||
{
|
||||
defaultMessage: 'License is not editable for Elastic rules',
|
||||
defaultMessage: 'License',
|
||||
}
|
||||
);
|
||||
|
||||
export const FIELD_NOT_EDITABLE_TOOLTIP_TEXT = (fieldName: string) =>
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldNotEditableTooltipText',
|
||||
{
|
||||
defaultMessage: "{fieldName} can't be edited for Elastic rules.",
|
||||
values: {
|
||||
fieldName,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
|
@ -95,7 +95,9 @@ const EditRulePageComponent: FC<{ rule: RuleResponse }> = ({ rule }) => {
|
|||
usePrebuiltRulesCustomizationStatus();
|
||||
const canEditRule = isRulesCustomizationEnabled || !rule.immutable;
|
||||
|
||||
const prebuiltCustomizationUpsellingMessage = usePrebuiltRuleCustomizationUpsellingMessage();
|
||||
const prebuiltCustomizationUpsellingMessage = usePrebuiltRuleCustomizationUpsellingMessage(
|
||||
'prebuilt_rule_customization_description'
|
||||
);
|
||||
|
||||
const { detailName: ruleId } = useParams<{ detailName: string }>();
|
||||
|
||||
|
|
|
@ -9,9 +9,8 @@ import React from 'react';
|
|||
import useToggle from 'react-use/lib/useToggle';
|
||||
import { EuiPopover, EuiText, EuiButtonIcon } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { TITLE } from './translations';
|
||||
import * as i18n from './translations';
|
||||
import type { VersionsPickerOptionEnum } from './versions_picker/versions_picker';
|
||||
import { useFieldUpgradeContext } from '../rule_upgrade/field_upgrade_context';
|
||||
import { getOptionDetails } from './utils';
|
||||
|
||||
/**
|
||||
|
@ -30,10 +29,7 @@ interface ComparisonSideHelpInfoProps {
|
|||
export function ComparisonSideHelpInfo({ options }: ComparisonSideHelpInfoProps): JSX.Element {
|
||||
const [isPopoverOpen, togglePopover] = useToggle(false);
|
||||
|
||||
const { hasResolvedValueDifferentFromSuggested } = useFieldUpgradeContext();
|
||||
const optionsWithDescriptions = options.map((option) =>
|
||||
getOptionDetails(option, hasResolvedValueDifferentFromSuggested)
|
||||
);
|
||||
const optionsWithDescriptions = options.map((option) => getOptionDetails(option));
|
||||
|
||||
const button = (
|
||||
<EuiButtonIcon
|
||||
|
@ -48,25 +44,20 @@ export function ComparisonSideHelpInfo({ options }: ComparisonSideHelpInfoProps)
|
|||
<EuiText style={{ width: POPOVER_WIDTH }} size="s">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.detectionEngine.rules.upgradeRules.comparisonSide.upgradeHelpText"
|
||||
defaultMessage="The {title} lets you compare the values of a field across different versions of a rule: {versions} Differences are shown as JSON, with red lines showing what was removed, green lines showing additions, and bold text highlighting changes. Use {title} to review and understand changes across versions."
|
||||
defaultMessage="The {title} lets you compare the values of a field across different versions of a rule:"
|
||||
values={{
|
||||
title: <strong>{TITLE}</strong>,
|
||||
versions: (
|
||||
<>
|
||||
<br />
|
||||
<ul>
|
||||
{optionsWithDescriptions.map(
|
||||
({ title: displayName, description: explanation }) => (
|
||||
<li key={displayName}>
|
||||
<strong>{displayName}</strong> {'-'} {explanation}
|
||||
</li>
|
||||
)
|
||||
)}
|
||||
</ul>
|
||||
</>
|
||||
),
|
||||
title: <strong>{i18n.TITLE}</strong>,
|
||||
}}
|
||||
/>
|
||||
<ul>
|
||||
{optionsWithDescriptions.map(({ title: displayName, description: explanation }) => (
|
||||
<li key={displayName}>
|
||||
<strong>{displayName}</strong>
|
||||
{':'} {explanation}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<p>{i18n.DIFF_FORMAT_AND_COLORS_EXPLANATION}</p>
|
||||
</EuiText>
|
||||
</EuiPopover>
|
||||
);
|
||||
|
|
|
@ -54,7 +54,7 @@ export function FieldComparisonSide(): JSX.Element {
|
|||
) {
|
||||
setSelectedOption(VersionsPickerOptionEnum.MyChanges);
|
||||
}
|
||||
}, [hasResolvedValueDifferentFromSuggested, selectedOption, prevResolvedValue, resolvedValue]);
|
||||
}, [selectedOption, prevResolvedValue, resolvedValue]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -73,7 +73,6 @@ export function FieldComparisonSide(): JSX.Element {
|
|||
options={options}
|
||||
selectedOption={selectedOption}
|
||||
onChange={setSelectedOption}
|
||||
hasResolvedValueDifferentFromSuggested={hasResolvedValueDifferentFromSuggested}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -25,28 +25,30 @@ export const NO_CHANGES = i18n.translate(
|
|||
export const UPDATE_FROM_ELASTIC_TITLE = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.updateFromElasticTitle',
|
||||
{
|
||||
defaultMessage: 'Update from Elastic',
|
||||
defaultMessage: 'Changes from Elastic',
|
||||
}
|
||||
);
|
||||
|
||||
export const UPDATE_FROM_ELASTIC_EXPLANATION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.updateFromElasticExplanation',
|
||||
{
|
||||
defaultMessage: 'view the changes in Elastic’s latest update',
|
||||
defaultMessage:
|
||||
"Compare the field's original value with changes from the Elastic update. Your changes aren't displayed.",
|
||||
}
|
||||
);
|
||||
|
||||
export const MY_CHANGES_TITLE = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myChangesTitle',
|
||||
export const MY_CHANGES_AND_FINAL_UPDATES_TITLE = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myChangesAndFinalUpdatesTitle',
|
||||
{
|
||||
defaultMessage: 'My changes',
|
||||
defaultMessage: 'My changes and final updates',
|
||||
}
|
||||
);
|
||||
|
||||
export const MY_CHANGES_EXPLANATION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myChangesExplanation',
|
||||
export const MY_CHANGES_AND_FINAL_UPDATES_EXPLANATION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myChangesAndFinalUpdatesExplanation',
|
||||
{
|
||||
defaultMessage: `view what you have changed in your installed rule and in the {finalUpdateSectionLabel} section`,
|
||||
defaultMessage:
|
||||
"Compare the field's original value with your changes or changes made in the {finalUpdateSectionLabel} section.",
|
||||
values: {
|
||||
finalUpdateSectionLabel: FINAL_UPDATE,
|
||||
},
|
||||
|
@ -54,9 +56,9 @@ export const MY_CHANGES_EXPLANATION = i18n.translate(
|
|||
);
|
||||
|
||||
export const MY_CHANGES_IN_RULE_UPGRADE_WORKFLOW_EXPLANATION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myChangesFinalUpdateOnlyExplanation',
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myChangesInRuleUpdateWorkflowOnlyExplanation',
|
||||
{
|
||||
defaultMessage: `view the changes you made in the {finalUpdateSectionLabel} section`,
|
||||
defaultMessage: 'View the changes you made in the {finalUpdateSectionLabel} section.',
|
||||
values: {
|
||||
finalUpdateSectionLabel: FINAL_UPDATE,
|
||||
},
|
||||
|
@ -66,30 +68,40 @@ export const MY_CHANGES_IN_RULE_UPGRADE_WORKFLOW_EXPLANATION = i18n.translate(
|
|||
export const MERGED_CHANGES_TITLE = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.mergedChangesTitle',
|
||||
{
|
||||
defaultMessage: 'My changes merged with Elastic’s',
|
||||
defaultMessage: "My changes merged with Elastic's",
|
||||
}
|
||||
);
|
||||
|
||||
export const MERGED_CHANGES_EXPLANATION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.mergedChangesExplanation',
|
||||
{
|
||||
defaultMessage: 'view an update suggestion that combines your changes with Elastic’s',
|
||||
defaultMessage:
|
||||
"Compare the field's original value with a version that combines your changes with those in the Elastic update. This version is only a suggestion.",
|
||||
}
|
||||
);
|
||||
|
||||
export const MY_ORIGINAL_CHANGES_TITLE = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myOriginalChangesTitle',
|
||||
{
|
||||
defaultMessage: 'My original changes',
|
||||
defaultMessage: 'My changes only',
|
||||
}
|
||||
);
|
||||
|
||||
export const MY_ORIGINAL_CHANGES_EXPLANATION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myCustomizationExplanation',
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myOriginalChangesExplanation',
|
||||
{
|
||||
defaultMessage: `view what you have changed in your installed rule. Doesn’t include changes made in the {finalUpdateSectionLabel} section.`,
|
||||
defaultMessage:
|
||||
"Compare the field's original value with your changes. Modifications in the {finalUpdateSectionLabel} section aren't displayed.",
|
||||
values: {
|
||||
finalUpdateSectionLabel: FINAL_UPDATE,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
export const DIFF_FORMAT_AND_COLORS_EXPLANATION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.diffFormatAndColorsExplanation',
|
||||
{
|
||||
defaultMessage:
|
||||
"Differences are shown in JSON and color-coded or bolded. Lines that are highlighted in green were added. Lines that are highlighted in red were removed. Text that's bolded was changed.",
|
||||
}
|
||||
);
|
||||
|
|
|
@ -60,21 +60,13 @@ interface OptionDetails {
|
|||
/**
|
||||
* Returns the title and description for a given versions picker option.
|
||||
*/
|
||||
export function getOptionDetails(
|
||||
option: VersionsPickerOptionEnum,
|
||||
hasResolvedValueDifferentFromSuggested: boolean
|
||||
): OptionDetails {
|
||||
export function getOptionDetails(option: VersionsPickerOptionEnum): OptionDetails {
|
||||
switch (option) {
|
||||
case VersionsPickerOptionEnum.MyChanges:
|
||||
return hasResolvedValueDifferentFromSuggested
|
||||
? {
|
||||
title: i18n.MY_CHANGES_TITLE,
|
||||
description: i18n.MY_CHANGES_IN_RULE_UPGRADE_WORKFLOW_EXPLANATION,
|
||||
}
|
||||
: {
|
||||
title: i18n.MY_CHANGES_TITLE,
|
||||
description: i18n.MY_CHANGES_EXPLANATION,
|
||||
};
|
||||
return {
|
||||
title: i18n.MY_CHANGES_AND_FINAL_UPDATES_TITLE,
|
||||
description: i18n.MY_CHANGES_AND_FINAL_UPDATES_EXPLANATION,
|
||||
};
|
||||
case VersionsPickerOptionEnum.MyOriginalChanges:
|
||||
return {
|
||||
title: i18n.MY_ORIGINAL_CHANGES_TITLE,
|
||||
|
|
|
@ -22,7 +22,6 @@ export const Default = () => {
|
|||
options={options}
|
||||
selectedOption={selectedOption}
|
||||
onChange={setSelectedOption}
|
||||
hasResolvedValueDifferentFromSuggested={false}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -22,20 +22,11 @@ interface VersionsPickerProps {
|
|||
options: VersionsPickerOptionEnum[];
|
||||
selectedOption: VersionsPickerOptionEnum;
|
||||
onChange: (selectedOption: VersionsPickerOptionEnum) => void;
|
||||
hasResolvedValueDifferentFromSuggested: boolean;
|
||||
}
|
||||
|
||||
export function VersionsPicker({
|
||||
options,
|
||||
selectedOption,
|
||||
onChange,
|
||||
hasResolvedValueDifferentFromSuggested,
|
||||
}: VersionsPickerProps) {
|
||||
export function VersionsPicker({ options, selectedOption, onChange }: VersionsPickerProps) {
|
||||
const euiSelectOptions = options.map((option) => {
|
||||
const { title: displayName, description: explanation } = getOptionDetails(
|
||||
option,
|
||||
hasResolvedValueDifferentFromSuggested
|
||||
);
|
||||
const { title: displayName, description: explanation } = getOptionDetails(option);
|
||||
|
||||
return {
|
||||
value: option,
|
||||
|
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
import useToggle from 'react-use/lib/useToggle';
|
||||
import { EuiPopover, EuiText, EuiButtonIcon } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import * as i18n from '../../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/translations';
|
||||
import * as i18n from './translations';
|
||||
|
||||
/**
|
||||
* Theme doesn't expose width variables. Using provided size variables will require
|
||||
|
@ -36,9 +36,9 @@ export function FieldFinalSideHelpInfo(): JSX.Element {
|
|||
<EuiText style={{ width: POPOVER_WIDTH }} size="s">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeHelpText"
|
||||
defaultMessage="The Final Update section lets you preview and edit the final value of a field. This is the value the rule will have after you click {updateButtonLabel}."
|
||||
defaultMessage="The {finalUpdateSectionLabel} section lets you preview and edit the final value of a field. This value is fully applied when you update the rule."
|
||||
values={{
|
||||
updateButtonLabel: <strong>{i18n.UPDATE_BUTTON_LABEL}</strong>,
|
||||
finalUpdateSectionLabel: <strong>{i18n.FINAL_UPDATE}</strong>,
|
||||
}}
|
||||
/>
|
||||
</EuiText>
|
||||
|
|
|
@ -23,7 +23,7 @@ export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JS
|
|||
switch (state) {
|
||||
case FieldUpgradeStateEnum.NoUpdate:
|
||||
return {
|
||||
color: 'success',
|
||||
color: 'default',
|
||||
title: i18n.NO_UPDATE,
|
||||
description: i18n.NO_UPDATE_DESCRIPTION,
|
||||
};
|
||||
|
|
|
@ -17,8 +17,7 @@ export const NO_UPDATE = i18n.translate(
|
|||
export const NO_UPDATE_DESCRIPTION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.noUpdateDescription',
|
||||
{
|
||||
defaultMessage:
|
||||
'The field was modified after rule installation but does not have Elastic update.',
|
||||
defaultMessage: 'This field has no Elastic update but can still be edited if needed.',
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -47,7 +46,8 @@ export const NO_CONFLICT = i18n.translate(
|
|||
export const NO_CONFLICT_DESCRIPTION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.noConflictDescription',
|
||||
{
|
||||
defaultMessage: 'The update has no conflicts and has been applied to the final update.',
|
||||
defaultMessage:
|
||||
"There are no conflicts with the field's current value and incoming Elastic update.",
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -61,7 +61,7 @@ export const REVIEWED_AND_ACCEPTED = i18n.translate(
|
|||
export const SOLVABLE_CONFLICT = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.solvableConflict',
|
||||
{
|
||||
defaultMessage: 'Solved conflict',
|
||||
defaultMessage: 'Auto-resolved conflict',
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -69,14 +69,14 @@ export const SOLVABLE_CONFLICT_DESCRIPTION = i18n.translate(
|
|||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.solvableConflictDescription',
|
||||
{
|
||||
defaultMessage:
|
||||
'We have suggested an update for this modified field, please review before accepting.',
|
||||
"We combined your changes with changes from the Elastic update. Review the suggested changes to ensure they're correct.",
|
||||
}
|
||||
);
|
||||
|
||||
export const NON_SOLVABLE_CONFLICT = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.nonSolvableConflict',
|
||||
{
|
||||
defaultMessage: 'Unsolved conflict',
|
||||
defaultMessage: 'Unresolved conflict',
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -84,7 +84,7 @@ export const NON_SOLVABLE_CONFLICT_DESCRIPTION = i18n.translate(
|
|||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.nonSolvableConflictDescription',
|
||||
{
|
||||
defaultMessage:
|
||||
'Unable to suggest a merged version for the update. Current version is provided for you to edit.',
|
||||
"We couldn't resolve this conflict. Edit the provided current version before saving and accepting the final update.",
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -36,7 +36,12 @@ export function RuleUpgradeCallout({
|
|||
color="danger"
|
||||
size="s"
|
||||
>
|
||||
<p>{i18n.RULE_HAS_HARD_CONFLICTS_DESCRIPTION}</p>
|
||||
<span>{i18n.RULE_HAS_HARD_CONFLICTS_DESCRIPTION}</span>
|
||||
<ul>
|
||||
<li>{i18n.RULE_HAS_HARD_CONFLICTS_KEEP_YOUR_CHANGES}</li>
|
||||
<li>{i18n.RULE_HAS_HARD_CONFLICTS_ACCEPT_ELASTIC_UPDATE}</li>
|
||||
<li>{i18n.RULE_HAS_HARD_CONFLICTS_EDIT_FINAL_VERSION}</li>
|
||||
</ul>
|
||||
</EuiCallOut>
|
||||
);
|
||||
}
|
||||
|
@ -56,7 +61,11 @@ export function RuleUpgradeCallout({
|
|||
color="warning"
|
||||
size="s"
|
||||
>
|
||||
<p>{i18n.RULE_HAS_SOFT_CONFLICTS_DESCRIPTION}</p>
|
||||
<span>{i18n.RULE_HAS_SOFT_CONFLICTS_DESCRIPTION}</span>
|
||||
<ul>
|
||||
<li>{i18n.RULE_HAS_SOFT_CONFLICTS_ACCEPT_SUGGESTED_UPDATE}</li>
|
||||
<li>{i18n.RULE_HAS_SOFT_CONFLICTS_EDIT_FINAL_VERSION}</li>
|
||||
</ul>
|
||||
</EuiCallOut>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import { useKibana } from '../../../../../../common/lib/kibana/kibana_react';
|
|||
export const TOTAL_NUM_OF_FIELDS = (count: number) => (
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.totalNumOfFieldsWithUpdates"
|
||||
defaultMessage="{countValue} {count, plural, one {field} other {fields}} for review"
|
||||
defaultMessage="{countValue} {count, plural, one {field} other {fields}} require review"
|
||||
values={{ countValue: <strong>{count}</strong>, count }}
|
||||
/>
|
||||
);
|
||||
|
@ -26,7 +26,7 @@ export const VERSION_UPDATE_INFO = (
|
|||
) => (
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.versionUpdateInfo"
|
||||
defaultMessage="{numOfFieldsWithUpdatesValue} {numOfFieldsWithUpdates, plural, one {field} other {fields}} changed in Elastic update from version {currentVersionNumber} to {targetVersionNumber}"
|
||||
defaultMessage="{numOfFieldsWithUpdatesValue} {numOfFieldsWithUpdates, plural, one {field} other {fields}} being changed in this Elastic update from version {currentVersionNumber} to {targetVersionNumber}"
|
||||
values={{
|
||||
numOfFieldsWithUpdatesValue: <strong>{numOfFieldsWithUpdates}</strong>,
|
||||
numOfFieldsWithUpdates,
|
||||
|
@ -79,7 +79,7 @@ export function RuleUpgradeHelper(): JSX.Element {
|
|||
export const UPGRADE_STATUS = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.upgradeStatusTitle',
|
||||
{
|
||||
defaultMessage: 'Update status:',
|
||||
defaultMessage: 'Status:',
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -89,7 +89,7 @@ export const RULE_HAS_CONFLICTS = (count: number) =>
|
|||
{
|
||||
values: { count },
|
||||
defaultMessage:
|
||||
'{count} {count, plural, one {field has a conflict} other {fields have conflicts}}. Please review and provide a final update.',
|
||||
'{count} {count, plural, one {field has a conflict} other {fields have conflicts}}. Review and provide a final update.',
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -97,7 +97,21 @@ export const RULE_HAS_SOFT_CONFLICTS_DESCRIPTION = i18n.translate(
|
|||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSoftConflictsDescription',
|
||||
{
|
||||
defaultMessage:
|
||||
'Please review and accept conflicts. You can also keep the current version without the updates, or accept the Elastic update but lose your modifications.',
|
||||
'We auto-resolved the conflicts between your changes and the Elastic update. Review them and do one of the following:',
|
||||
}
|
||||
);
|
||||
|
||||
export const RULE_HAS_SOFT_CONFLICTS_ACCEPT_SUGGESTED_UPDATE = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSoftConflictsAcceptSuggestedUpdate',
|
||||
{
|
||||
defaultMessage: 'Accept the suggested update.',
|
||||
}
|
||||
);
|
||||
|
||||
export const RULE_HAS_SOFT_CONFLICTS_EDIT_FINAL_VERSION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSoftConflictsEditFinalVersion',
|
||||
{
|
||||
defaultMessage: 'Edit the final version and choose a more appropriate field value.',
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -105,14 +119,36 @@ export const RULE_HAS_HARD_CONFLICTS_DESCRIPTION = i18n.translate(
|
|||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasHardConflictsDescription',
|
||||
{
|
||||
defaultMessage:
|
||||
'Please provide an input for the conflicts. You can also keep the current version without the updates, or accept the Elastic update but lose your modifications.',
|
||||
"We couldn't auto-resolve the conflicts between your changes and the Elastic update. To resolve them, do one of the following:",
|
||||
}
|
||||
);
|
||||
|
||||
export const RULE_HAS_HARD_CONFLICTS_KEEP_YOUR_CHANGES = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasHardConflictsKeepYourChanges',
|
||||
{
|
||||
defaultMessage: 'Keep your changes and reject the Elastic update.',
|
||||
}
|
||||
);
|
||||
|
||||
export const RULE_HAS_HARD_CONFLICTS_ACCEPT_ELASTIC_UPDATE = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasHardConflictsAcceptElasticUpdate',
|
||||
{
|
||||
defaultMessage: 'Accept the Elastic update and overwrite your changes.',
|
||||
}
|
||||
);
|
||||
|
||||
export const RULE_HAS_HARD_CONFLICTS_EDIT_FINAL_VERSION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasHardConflictsEditFinalVersion',
|
||||
{
|
||||
defaultMessage:
|
||||
'Edit the final version by combining your changes with the Elastic update or choosing a more appropriate field value.',
|
||||
}
|
||||
);
|
||||
|
||||
export const RULE_IS_READY_FOR_UPGRADE_DESCRIPTION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleIsReadyForUpgradeDescription',
|
||||
{
|
||||
defaultMessage: 'There are no conflicts and the update is ready to be applied.',
|
||||
defaultMessage: 'There are no conflicts. The rule is ready to be updated.',
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -120,6 +156,6 @@ export const FIELD_MODIFIED_BADGE_DESCRIPTION = i18n.translate(
|
|||
'xpack.securitySolution.detectionEngine.upgradeFlyout.fieldModifiedBadgeDescription',
|
||||
{
|
||||
defaultMessage:
|
||||
"The field value was edited after rule's installation and differs from the value upon installation",
|
||||
'This field value differs from the one provided in the original version of the rule.',
|
||||
}
|
||||
);
|
||||
|
|
|
@ -33,7 +33,7 @@ export const INVESTIGATION_GUIDE_TAB_LABEL = i18n.translate(
|
|||
export const UPDATES_TAB_LABEL = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.ruleDetails.updatesTabLabel',
|
||||
{
|
||||
defaultMessage: 'Updates',
|
||||
defaultMessage: 'Elastic update overview',
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -117,14 +117,14 @@ export const BUILDING_BLOCK_FIELD_LABEL = i18n.translate(
|
|||
export const BUILDING_BLOCK_ENABLED_FIELD_DESCRIPTION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.ruleDetails.buildingBlockFieldDescription',
|
||||
{
|
||||
defaultMessage: 'All generated alerts will be marked as "building block" alerts',
|
||||
defaultMessage: 'All generated alerts will be marked as building block alerts',
|
||||
}
|
||||
);
|
||||
|
||||
export const BUILDING_BLOCK_DISABLED_FIELD_DESCRIPTION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.ruleDetails.buildingBlockDisabledFieldDescription',
|
||||
{
|
||||
defaultMessage: 'Will not mark alerts as "building block" alerts',
|
||||
defaultMessage: 'Will not mark alerts as building block alerts',
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { UpsellingMessageId } from '@kbn/security-solution-upselling/service';
|
||||
import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features';
|
||||
import { useUpsellingMessage } from '../../../../common/hooks/use_upselling';
|
||||
|
||||
|
@ -13,10 +14,10 @@ import { useUpsellingMessage } from '../../../../common/hooks/use_upselling';
|
|||
* for prebuilt rule customization. If the license level is sufficient, it
|
||||
* returns `undefined`.
|
||||
*/
|
||||
export const usePrebuiltRuleCustomizationUpsellingMessage = () => {
|
||||
export const usePrebuiltRuleCustomizationUpsellingMessage = (messageId: UpsellingMessageId) => {
|
||||
// Upselling message is returned when the license level is insufficient,
|
||||
// otherwise it's undefined
|
||||
const upsellingMessage = useUpsellingMessage('prebuilt_rule_customization');
|
||||
const upsellingMessage = useUpsellingMessage(messageId);
|
||||
|
||||
// We show the upselling message only if the feature flag is enabled
|
||||
const isFeatureFlagEnabled = useIsExperimentalFeatureEnabled('prebuiltRulesCustomizationEnabled');
|
||||
|
|
|
@ -20,7 +20,9 @@ export const usePrebuiltRulesCustomizationStatus = (): PrebuiltRulesCustomizatio
|
|||
const isFeatureFlagEnabled = useIsExperimentalFeatureEnabled('prebuiltRulesCustomizationEnabled');
|
||||
// Upselling message is returned when the license level is insufficient,
|
||||
// otherwise it's undefined
|
||||
const upsellingMessage = usePrebuiltRuleCustomizationUpsellingMessage();
|
||||
const upsellingMessage = usePrebuiltRuleCustomizationUpsellingMessage(
|
||||
'prebuilt_rule_customization'
|
||||
);
|
||||
|
||||
const isRulesCustomizationEnabled = isFeatureFlagEnabled && !upsellingMessage;
|
||||
let customizationDisabledReason;
|
||||
|
|
|
@ -29,7 +29,9 @@ const BulkEditRuleErrorItem = ({
|
|||
message,
|
||||
rulesCount,
|
||||
}: BulkActionRuleErrorItemProps) => {
|
||||
const upsellingMessage = usePrebuiltRuleCustomizationUpsellingMessage();
|
||||
const upsellingMessage = usePrebuiltRuleCustomizationUpsellingMessage(
|
||||
'prebuilt_rule_customization'
|
||||
);
|
||||
|
||||
switch (errorCode) {
|
||||
case BulkActionsDryRunErrCodeEnum.IMMUTABLE:
|
||||
|
|
|
@ -7,20 +7,24 @@
|
|||
|
||||
import React from 'react';
|
||||
import { EuiCallOut } from '@elastic/eui';
|
||||
import { CUSTOMIZATION_DISABLED_CALLOUT_DESCRIPTION } from './translations';
|
||||
import { usePrebuiltRuleCustomizationUpsellingMessage } from '../../../../rule_management/logic/prebuilt_rules/use_prebuilt_rule_customization_upselling_message';
|
||||
import * as i18n from './translations';
|
||||
|
||||
export function CustomizationDisabledCallout() {
|
||||
const upsellingMessage = usePrebuiltRuleCustomizationUpsellingMessage();
|
||||
const title = usePrebuiltRuleCustomizationUpsellingMessage('prebuilt_rule_customization');
|
||||
const description = usePrebuiltRuleCustomizationUpsellingMessage(
|
||||
'prebuilt_rule_customization_description'
|
||||
);
|
||||
|
||||
// Upselling message is returned only when the license level is insufficient
|
||||
if (!upsellingMessage) {
|
||||
if (!title) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<EuiCallOut title={upsellingMessage} size="s" color="primary">
|
||||
<p>{CUSTOMIZATION_DISABLED_CALLOUT_DESCRIPTION}</p>
|
||||
<EuiCallOut title={title} size="s" color="primary">
|
||||
<p>{i18n.MODIFIED_RULE_UPGRADE_LICENSE_INSUFFICIENT_CALLOUT_DESCRIPTION}</p>
|
||||
<p>{description}</p>
|
||||
</EuiCallOut>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ export const BULK_UPDATE_ALL_RULES_BUTTON_TOOLTIP_CONFLICTS = i18n.translate(
|
|||
export const BULK_UPDATE_SELECTED_RULES_BUTTON_TOOLTIP_CONFLICTS = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.bulkButtons.selectedRules.conflicts',
|
||||
{
|
||||
defaultMessage: 'All selected rules have conflicts. Update them individually.',
|
||||
defaultMessage: 'The selected rules have conflicts that must be manually resolved.',
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -58,7 +58,7 @@ export const SEARCH_PLACEHOLDER = i18n.translate(
|
|||
export const UPDATE_BUTTON_LABEL = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.ruleDetails.updateButtonLabel',
|
||||
{
|
||||
defaultMessage: 'Update',
|
||||
defaultMessage: 'Update rule',
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -86,7 +86,14 @@ export const RULE_TYPE_CHANGE_CALLOUT_TITLE = i18n.translate(
|
|||
export const RULE_TYPE_CHANGE_CALLOUT_DESCRIPTION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.upgradeRules.ruleTypeChangeCalloutDescription',
|
||||
{
|
||||
defaultMessage: 'Elastic update has rule type changed.',
|
||||
defaultMessage: 'The rule type will change if you update this rule.',
|
||||
}
|
||||
);
|
||||
|
||||
export const MODIFIED_RULE_UPGRADE_LICENSE_INSUFFICIENT_CALLOUT_DESCRIPTION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.upgradeRules.ruleUpgradeLicenseInsufficientCalloutDescription',
|
||||
{
|
||||
defaultMessage: 'Updating the rule will erase your changes.',
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -94,14 +101,14 @@ export const RULE_TYPE_CHANGE_WITH_CUSTOMIZATIONS_CALLOUT_DESCRIPTION = i18n.tra
|
|||
'xpack.securitySolution.detectionEngine.upgradeRules.ruleTypeChangeWithCustomizationCalloutDescription',
|
||||
{
|
||||
defaultMessage:
|
||||
'Your customization will be lost at update. Please take note of your customization or clone this rule before updating.',
|
||||
'Updating the rule will erase your changes. To save them, first duplicate the rule, then update it.',
|
||||
}
|
||||
);
|
||||
|
||||
export const LAST_UPDATE = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.upgradeFlyout.header.lastUpdate',
|
||||
{
|
||||
defaultMessage: 'Last update',
|
||||
defaultMessage: 'Last updated',
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -168,11 +175,3 @@ export const RULE_NEW_VERSION_DETECTED_WARNING_DESCRIPTION = (ruleName: string)
|
|||
values: { ruleName },
|
||||
}
|
||||
);
|
||||
|
||||
export const CUSTOMIZATION_DISABLED_CALLOUT_DESCRIPTION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.upgradeRules.customizationDisabledCalloutDescription',
|
||||
{
|
||||
defaultMessage:
|
||||
'Prebuilt rule customization is disabled. Only updates to Elastic version are available.',
|
||||
}
|
||||
);
|
||||
|
|
|
@ -831,7 +831,7 @@ export const NO_TAGS_AVAILABLE = i18n.translate(
|
|||
export const RULE_SOURCE = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.allRules.filters.ruleSourceLabel',
|
||||
{
|
||||
defaultMessage: 'Modifications',
|
||||
defaultMessage: 'Modified/Unmodified',
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -1436,7 +1436,7 @@ export const UPDATE_RULE_BUTTON = i18n.translate(
|
|||
export const UPDATE_RULE_BUTTON_TOOLTIP_CONFLICTS = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.rules.upgradeRules.button.conflicts',
|
||||
{
|
||||
defaultMessage: 'Rule has conflicts. Resolve them manually.',
|
||||
defaultMessage: 'This rule has conflicts that must be manually resolved.',
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -10,10 +10,11 @@ import { SecurityPageName } from '@kbn/security-solution-plugin/common';
|
|||
import {
|
||||
ALERT_SUPPRESSION_RULE_DETAILS,
|
||||
ALERT_SUPPRESSION_RULE_FORM,
|
||||
PREBUILT_RULE_CUSTOMIZATION_DESCRIPTION,
|
||||
UPGRADE_ALERT_ASSIGNMENTS,
|
||||
UPGRADE_INVESTIGATION_GUIDE,
|
||||
UPGRADE_NOTES_MANAGEMENT_USER_FILTER,
|
||||
UPGRADE_PREBUILT_RULE_CUSTOMIZATION,
|
||||
PREBUILT_RULE_CUSTOMIZATION,
|
||||
} from '@kbn/security-solution-upselling/messages';
|
||||
import type {
|
||||
MessageUpsellings,
|
||||
|
@ -142,6 +143,11 @@ export const upsellingMessages: UpsellingMessages = [
|
|||
{
|
||||
id: 'prebuilt_rule_customization',
|
||||
minimumLicenseRequired: 'enterprise',
|
||||
message: UPGRADE_PREBUILT_RULE_CUSTOMIZATION('Enterprise'),
|
||||
message: PREBUILT_RULE_CUSTOMIZATION('Enterprise', 'subscription'),
|
||||
},
|
||||
{
|
||||
id: 'prebuilt_rule_customization_description',
|
||||
minimumLicenseRequired: 'enterprise',
|
||||
message: PREBUILT_RULE_CUSTOMIZATION_DESCRIPTION('Enterprise', 'subscription'),
|
||||
},
|
||||
];
|
||||
|
|
|
@ -10,7 +10,8 @@ import { SecurityPageName } from '@kbn/security-solution-plugin/common';
|
|||
import {
|
||||
UPGRADE_INVESTIGATION_GUIDE,
|
||||
UPGRADE_INVESTIGATION_GUIDE_INTERACTIONS,
|
||||
UPGRADE_PREBUILT_RULE_CUSTOMIZATION,
|
||||
PREBUILT_RULE_CUSTOMIZATION,
|
||||
PREBUILT_RULE_CUSTOMIZATION_DESCRIPTION,
|
||||
} from '@kbn/security-solution-upselling/messages';
|
||||
import type {
|
||||
UpsellingMessageId,
|
||||
|
@ -166,8 +167,17 @@ export const upsellingMessages: UpsellingMessages = [
|
|||
{
|
||||
id: 'prebuilt_rule_customization',
|
||||
pli: ProductFeatureKey.prebuiltRuleCustomization,
|
||||
message: UPGRADE_PREBUILT_RULE_CUSTOMIZATION(
|
||||
getProductTypeByPLI(ProductFeatureKey.prebuiltRuleCustomization) ?? ''
|
||||
message: PREBUILT_RULE_CUSTOMIZATION(
|
||||
getProductTypeByPLI(ProductFeatureKey.prebuiltRuleCustomization) ?? '',
|
||||
'feature tier'
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'prebuilt_rule_customization_description',
|
||||
pli: ProductFeatureKey.prebuiltRuleCustomization,
|
||||
message: PREBUILT_RULE_CUSTOMIZATION_DESCRIPTION(
|
||||
getProductTypeByPLI(ProductFeatureKey.prebuiltRuleCustomization) ?? '',
|
||||
'feature tier'
|
||||
),
|
||||
},
|
||||
];
|
||||
|
|
|
@ -73,7 +73,7 @@ import { enableRules, waitForRulesToFinishExecution } from '../../../../tasks/ap
|
|||
const PREVIEW_TABS = {
|
||||
OVERVIEW: 'Overview',
|
||||
JSON_VIEW: 'JSON view',
|
||||
UPDATES: 'Updates', // Currently open by default on upgrade
|
||||
UPDATES: 'Elastic update overview', // Currently open by default on upgrade
|
||||
};
|
||||
|
||||
describe(
|
||||
|
|
|
@ -142,7 +142,7 @@ export const assertCommonPropertiesShown = (properties: Partial<PrebuiltRuleAsse
|
|||
cy.get(BUILDING_BLOCK_TITLE).should('have.text', 'Building block');
|
||||
cy.get(BUILDING_BLOCK_VALUE).should(
|
||||
'have.text',
|
||||
'All generated alerts will be marked as "building block" alerts'
|
||||
'All generated alerts will be marked as building block alerts'
|
||||
);
|
||||
|
||||
cy.get(SEVERITY_TITLE).should('have.text', 'Severity');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue