diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade.tsx index d7e3e33fcb5f8..4f87cf0ff202a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade.tsx @@ -16,12 +16,18 @@ import { useFieldUpgradeContext } from './field_upgrade_context'; export function FieldUpgrade(): JSX.Element { const { euiTheme } = useEuiTheme(); - const { fieldName, fieldUpgradeState, hasConflict } = useFieldUpgradeContext(); + const { fieldName, fieldUpgradeState, hasConflict, isCustomized } = useFieldUpgradeContext(); return ( <> } + header={ + + } initialIsOpen={hasConflict} data-test-subj="ruleUpgradePerFieldDiff" > diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_context.tsx index f88c9fb3e0760..6f8a6033de406 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_context.tsx @@ -7,10 +7,12 @@ import React, { createContext, useContext, useMemo } from 'react'; import { useBoolean } from '@kbn/react-hooks'; -import type { - DiffableRule, - FieldsDiff, - ThreeWayDiff, +import { assertUnreachable } from '../../../../../../../common/utility_types'; +import { + ThreeWayDiffOutcome, + type DiffableRule, + type FieldsDiff, + type ThreeWayDiff, } from '../../../../../../../common/api/detection_engine'; import { invariant } from '../../../../../../../common/utils/invariant'; import { convertRuleToDiffable } from '../../../../../../../common/detection_engine/prebuilt_rules/diff/convert_rule_to_diffable'; @@ -34,9 +36,13 @@ interface FieldUpgradeContextType { */ fieldUpgradeState: FieldUpgradeStateEnum; /** - * Whether rule has an unresolved conflict. This state is derived from `fieldUpgradeState`. + * Whether the field has an unresolved conflict. This state is derived from `fieldUpgradeState`. */ hasConflict: boolean; + /** + * Whether the field was changed after prebuilt rule installation, i.e. customized + */ + isCustomized: boolean; /** * Field's three way diff */ @@ -98,6 +104,7 @@ export function FieldUpgradeContextProvider({ hasConflict: fieldUpgradeState === FieldUpgradeStateEnum.SolvableConflict || fieldUpgradeState === FieldUpgradeStateEnum.NonSolvableConflict, + isCustomized: calcIsCustomized(fieldDiff), fieldDiff, finalDiffableRule: calcFinalDiffableRule(ruleUpgradeState), rightSideMode: editing ? FieldFinalSideMode.Edit : FieldFinalSideMode.Readonly, @@ -133,6 +140,24 @@ export function useFieldUpgradeContext() { return context; } +function calcIsCustomized(fieldDiff: ThreeWayDiff): boolean { + switch (fieldDiff.diff_outcome) { + case ThreeWayDiffOutcome.StockValueNoUpdate: + case ThreeWayDiffOutcome.StockValueCanUpdate: + case ThreeWayDiffOutcome.MissingBaseCanUpdate: + case ThreeWayDiffOutcome.MissingBaseNoUpdate: + return false; + + case ThreeWayDiffOutcome.CustomizedValueCanUpdate: + case ThreeWayDiffOutcome.CustomizedValueSameUpdate: + case ThreeWayDiffOutcome.CustomizedValueNoUpdate: + return true; + + default: + return assertUnreachable(fieldDiff.diff_outcome); + } +} + function calcFinalDiffableRule(ruleUpgradeState: RuleUpgradeState): DiffableRule { const fieldsResolvedValues = Object.entries(ruleUpgradeState.fieldsUpgradeState).reduce< Record diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_header.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_header.tsx index b401f702bd036..91339e25d5907 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_header.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_header.tsx @@ -11,25 +11,29 @@ import { EuiFlexGroup, EuiTitle } from '@elastic/eui'; import { fieldToDisplayNameMap } from '../../diff_components/translations'; import type { FieldUpgradeStateEnum } from '../../../../model/prebuilt_rule_upgrade'; import { FieldUpgradeStateInfo } from './field_upgrade_state_info'; +import { ModifiedBadge } from '../badges/modified_badge'; +import { FIELD_MODIFIED_BADGE_DESCRIPTION } from './translations'; interface FieldUpgradeHeaderProps { fieldName: string; fieldUpgradeState: FieldUpgradeStateEnum; + isCustomized: boolean; } export function FieldUpgradeHeader({ fieldName, fieldUpgradeState, + isCustomized, }: FieldUpgradeHeaderProps): JSX.Element { return ( - +
{fieldToDisplayNameMap[fieldName] ?? startCase(camelCase(fieldName))}
- - - + {isCustomized && } + +
); } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/translations.tsx index 4a73f096a271c..a54ced917de54 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/translations.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/translations.tsx @@ -110,6 +110,7 @@ export const RULE_IS_READY_FOR_UPGRADE_DESCRIPTION = i18n.translate( export const FIELD_MODIFIED_BADGE_DESCRIPTION = i18n.translate( 'xpack.securitySolution.detectionEngine.upgradeFlyout.fieldModifiedBadgeDescription', { - defaultMessage: 'The field value was edited and differs from the stock value', + defaultMessage: + "The field value was edited after rule's installation and differs from the value upon installation", } ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/translations.tsx index 4b9f79e061ce9..4bcf0bd0a3b68 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/translations.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/translations.tsx @@ -136,6 +136,7 @@ export const FIELD_UPDATES = i18n.translate( export const RULE_MODIFIED_BADGE_DESCRIPTION = i18n.translate( 'xpack.securitySolution.detectionEngine.upgradeFlyout.ruleModifiedBadgeDescription', { - defaultMessage: 'The rule was edited and field values differs from the stock values', + defaultMessage: + 'The rule was edited after installation and field values differs from the values upon installation', } );