From 51464ba8a4ebd47b2bc74d982dd88bb5f7cb6615 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 22 Nov 2024 11:56:39 +0100 Subject: [PATCH 01/77] rename components for better readability --- .../field_upgrade_conflicts_resolver.tsx | 4 ++-- .../constants.ts | 0 .../field_final_side.tsx} | 16 ++++++++-------- .../final_side_context.tsx | 0 .../final_side_help_info.tsx | 0 .../translations.ts | 0 .../{final_edit.tsx => field_final_edit.tsx} | 4 ++-- .../fields/rule_field_edit_form_wrapper.tsx | 2 +- ...nal_readonly.tsx => field_final_readonly.tsx} | 4 ++-- 9 files changed, 15 insertions(+), 15 deletions(-) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{final_side => field_final_side}/constants.ts (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{final_side/final_side.tsx => field_final_side/field_final_side.tsx} (76%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{final_side => field_final_side}/final_side_context.tsx (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{final_side => field_final_side}/final_side_help_info.tsx (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{final_side => field_final_side}/translations.ts (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/{final_edit.tsx => field_final_edit.tsx} (95%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/{final_readonly.tsx => field_final_readonly.tsx} (83%) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx index 6a2ad17f45f26..0739e7eb049d7 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx @@ -17,7 +17,7 @@ import type { import { ThreeWayDiffConflict } from '../../../../../../../common/api/detection_engine'; import type { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { ComparisonSide } from '../comparison_side/comparison_side'; -import { FinalSide } from '../final_side/final_side'; +import { FieldFinalSide } from '../field_final_side/field_final_side'; import { FieldUpgradeConflictsResolverHeader } from './field_upgrade_conflicts_resolver_header'; import { useDiffableRuleContext } from '../diffable_rule_context'; import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; @@ -66,7 +66,7 @@ export function FieldUpgradeConflictsResolver - + diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/constants.ts similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/constants.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/constants.ts diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side.tsx similarity index 76% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side.tsx index 30e3f4461195a..7b06ba4b87861 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side.tsx @@ -10,18 +10,18 @@ import { EuiTitle } from '@elastic/eui'; import { SideHeader } from '../components/side_header'; import { FinalSideHelpInfo } from './final_side_help_info'; import * as i18n from './translations'; -import { FinalReadOnly } from '../final_readonly/final_readonly'; -import { FinalEdit } from '../final_edit/final_edit'; +import { FieldFinalReadOnly } from '../final_readonly/field_final_readonly'; +import { FieldFinalEdit } from '../final_edit/field_final_edit'; import { FinalSideMode } from './constants'; import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; import { assertUnreachable } from '../../../../../../../common/utility_types'; import { FinalSideContextProvider, useFinalSideContext } from './final_side_context'; -interface FinalSideProps { +interface FieldFinalSideProps { fieldName: UpgradeableDiffableFields; } -export function FinalSide({ fieldName }: FinalSideProps): JSX.Element { +export function FieldFinalSide({ fieldName }: FieldFinalSideProps): JSX.Element { return ( <> @@ -33,20 +33,20 @@ export function FinalSide({ fieldName }: FinalSideProps): JSX.Element { - + ); } -function FinalSideContent(): JSX.Element { +function FieldFinalSideContent(): JSX.Element { const { mode } = useFinalSideContext(); switch (mode) { case FinalSideMode.READONLY: - return ; + return ; case FinalSideMode.EDIT: - return ; + return ; default: return assertUnreachable(mode); } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_context.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side_context.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_context.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side_help_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_help_info.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side_help_info.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_help_info.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/translations.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/translations.ts diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx similarity index 95% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx index 13bc3daa56037..8335ee777d70f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx @@ -25,12 +25,12 @@ import type { UpgradeableMachineLearningFields, } from '../../../../model/prebuilt_rule_upgrade/fields'; import { isCommonFieldName } from '../../../../model/prebuilt_rule_upgrade/fields'; -import { useFinalSideContext } from '../final_side/final_side_context'; +import { useFinalSideContext } from '../field_final_side/final_side_context'; import { EqlRuleFieldEdit } from './eql_rule_field_edit'; import { EsqlRuleFieldEdit } from './esql_rule_field_edit'; import { MachineLearningRuleFieldEdit } from './machine_learning_rule_field_edit'; -export function FinalEdit() { +export function FieldFinalEdit(): JSX.Element { const { finalDiffableRule } = useDiffableRuleContext(); const { type } = finalDiffableRule; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx index a5f7eedc6114c..554a22c73b03a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx @@ -16,7 +16,7 @@ import type { DiffableAllFields, DiffableRule, } from '../../../../../../../../common/api/detection_engine'; -import { useFinalSideContext } from '../../final_side/final_side_context'; +import { useFinalSideContext } from '../../field_final_side/final_side_context'; import { useDiffableRuleContext } from '../../diffable_rule_context'; import * as i18n from '../../translations'; import type { RuleFieldEditComponentProps } from './rule_field_edit_component_props'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/final_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx similarity index 83% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/final_readonly.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx index 21b8475fe3002..890f112b177f3 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/final_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx @@ -9,9 +9,9 @@ import { EuiButtonEmpty } from '@elastic/eui'; import React from 'react'; import { FieldReadOnly } from './field_readonly'; import * as i18n from '../translations'; -import { useFinalSideContext } from '../final_side/final_side_context'; +import { useFinalSideContext } from '../field_final_side/final_side_context'; -export function FinalReadOnly() { +export function FieldFinalReadOnly(): JSX.Element { const { setEditMode, fieldName } = useFinalSideContext(); return ( From 963c64d0df612597ba5b5049b5e862d9752d339f Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 22 Nov 2024 12:15:08 +0100 Subject: [PATCH 02/77] fix wrong texts --- .../components/field_upgrade_state_info/translations.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/translations.tsx index 36349b5029a87..0857013e2c715 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/translations.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/translations.tsx @@ -40,7 +40,7 @@ export const SOLVABLE_CONFLICT_DESCRIPTION = i18n.translate( export const NON_SOLVABLE_CONFLICT = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.nonSolvableConflict', { - defaultMessage: 'Solved conflict', + defaultMessage: 'Unsolved conflict', } ); @@ -48,7 +48,7 @@ export const NON_SOLVABLE_CONFLICT_DESCRIPTION = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.nonSolvableConflictDescription', { defaultMessage: - 'We have suggested an update for this modified field, please review before accepting.', + 'Unable to suggest a merged version for the update. Current version is provided for you to edit.', } ); From 40b406c38ecd4c6be1e0b2d0b072029d2a320211 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 22 Nov 2024 12:15:48 +0100 Subject: [PATCH 03/77] display initially edit mode for NON_SOLVABLE conflicts --- .../components/field_upgrade_conflicts_resolver.tsx | 8 ++++++-- .../field_final_side/field_final_side.tsx | 11 ++++++----- .../field_final_side/final_side_context.tsx | 10 ++++++---- .../{constants.ts => final_side_mode.ts} | 4 ++-- .../three_way_diff/field_final_side/index.ts | 10 ++++++++++ .../three_way_diff/final_edit/field_final_edit.tsx | 2 +- .../fields/rule_field_edit_form_wrapper.tsx | 2 +- .../final_readonly/field_final_readonly.tsx | 4 ++-- 8 files changed, 34 insertions(+), 17 deletions(-) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/{constants.ts => final_side_mode.ts} (87%) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/index.ts diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx index 0739e7eb049d7..743b1e16d15fd 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx @@ -17,7 +17,7 @@ import type { import { ThreeWayDiffConflict } from '../../../../../../../common/api/detection_engine'; import type { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { ComparisonSide } from '../comparison_side/comparison_side'; -import { FieldFinalSide } from '../field_final_side/field_final_side'; +import { FieldFinalSide, FinalSideMode } from '../field_final_side'; import { FieldUpgradeConflictsResolverHeader } from './field_upgrade_conflicts_resolver_header'; import { useDiffableRuleContext } from '../diffable_rule_context'; import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; @@ -35,6 +35,10 @@ export function FieldUpgradeConflictsResolver): JSX.Element { const { euiTheme } = useEuiTheme(); const hasConflict = fieldThreeWayDiff.conflict !== ThreeWayDiffConflict.NONE; + const initialFieldFinalSideMode = + fieldThreeWayDiff.conflict === ThreeWayDiffConflict.NON_SOLVABLE + ? FinalSideMode.Edit + : FinalSideMode.Readonly; const { finalDiffableRule } = useDiffableRuleContext(); @@ -66,7 +70,7 @@ export function FieldUpgradeConflictsResolver - + diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side.tsx index 7b06ba4b87861..e39ffbc7da52c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side.tsx @@ -12,16 +12,17 @@ import { FinalSideHelpInfo } from './final_side_help_info'; import * as i18n from './translations'; import { FieldFinalReadOnly } from '../final_readonly/field_final_readonly'; import { FieldFinalEdit } from '../final_edit/field_final_edit'; -import { FinalSideMode } from './constants'; +import { FinalSideMode } from './final_side_mode'; import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; import { assertUnreachable } from '../../../../../../../common/utility_types'; import { FinalSideContextProvider, useFinalSideContext } from './final_side_context'; interface FieldFinalSideProps { fieldName: UpgradeableDiffableFields; + initialMode: FinalSideMode; } -export function FieldFinalSide({ fieldName }: FieldFinalSideProps): JSX.Element { +export function FieldFinalSide({ fieldName, initialMode }: FieldFinalSideProps): JSX.Element { return ( <> @@ -32,7 +33,7 @@ export function FieldFinalSide({ fieldName }: FieldFinalSideProps): JSX.Element - + @@ -43,9 +44,9 @@ function FieldFinalSideContent(): JSX.Element { const { mode } = useFinalSideContext(); switch (mode) { - case FinalSideMode.READONLY: + case FinalSideMode.Readonly: return ; - case FinalSideMode.EDIT: + case FinalSideMode.Edit: return ; default: return assertUnreachable(mode); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_context.tsx index 6beb0535e5e27..e27e1f78e320d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_context.tsx @@ -7,7 +7,7 @@ import React, { createContext, useContext, type PropsWithChildren, useCallback } from 'react'; import { invariant } from '../../../../../../../common/utils/invariant'; -import { FinalSideMode } from './constants'; +import { FinalSideMode } from './final_side_mode'; import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; interface FinalSideContextType { @@ -21,15 +21,17 @@ const FinalSideContext = createContext(null); interface FinalSideContextProviderProps { fieldName: UpgradeableDiffableFields; + initialMode: FinalSideMode; } export function FinalSideContextProvider({ children, fieldName, + initialMode, }: PropsWithChildren) { - const [mode, setMode] = React.useState(FinalSideMode.READONLY); - const setReadOnlyMode = useCallback(() => setMode(FinalSideMode.READONLY), []); - const setEditMode = useCallback(() => setMode(FinalSideMode.EDIT), []); + const [mode, setMode] = React.useState(initialMode); + const setReadOnlyMode = useCallback(() => setMode(FinalSideMode.Readonly), []); + const setEditMode = useCallback(() => setMode(FinalSideMode.Edit), []); const contextValue = { fieldName, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_mode.ts similarity index 87% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/constants.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_mode.ts index 6316abcae48a3..cf8d681580e11 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/constants.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_mode.ts @@ -6,6 +6,6 @@ */ export enum FinalSideMode { - READONLY = 'readonly', - EDIT = 'edit', + Readonly = 'readonly', + Edit = 'edit', } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/index.ts new file mode 100644 index 0000000000000..aeadd58708780 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './final_side_mode'; +export * from './field_final_side'; +export { useFinalSideContext } from './final_side_context'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx index 8335ee777d70f..a97412d39afc7 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx @@ -25,7 +25,7 @@ import type { UpgradeableMachineLearningFields, } from '../../../../model/prebuilt_rule_upgrade/fields'; import { isCommonFieldName } from '../../../../model/prebuilt_rule_upgrade/fields'; -import { useFinalSideContext } from '../field_final_side/final_side_context'; +import { useFinalSideContext } from '../field_final_side'; import { EqlRuleFieldEdit } from './eql_rule_field_edit'; import { EsqlRuleFieldEdit } from './esql_rule_field_edit'; import { MachineLearningRuleFieldEdit } from './machine_learning_rule_field_edit'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx index 554a22c73b03a..ff4bf019fd46e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx @@ -16,7 +16,7 @@ import type { DiffableAllFields, DiffableRule, } from '../../../../../../../../common/api/detection_engine'; -import { useFinalSideContext } from '../../field_final_side/final_side_context'; +import { useFinalSideContext } from '../../field_final_side'; import { useDiffableRuleContext } from '../../diffable_rule_context'; import * as i18n from '../../translations'; import type { RuleFieldEditComponentProps } from './rule_field_edit_component_props'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx index 890f112b177f3..68a7db7dcc346 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx @@ -7,9 +7,9 @@ import { EuiButtonEmpty } from '@elastic/eui'; import React from 'react'; -import { FieldReadOnly } from './field_readonly'; +import { useFinalSideContext } from '../field_final_side'; import * as i18n from '../translations'; -import { useFinalSideContext } from '../field_final_side/final_side_context'; +import { FieldReadOnly } from './field_readonly'; export function FieldFinalReadOnly(): JSX.Element { const { setEditMode, fieldName } = useFinalSideContext(); From db048596ec57e1b23e0ab09daa6e012ee39c83c1 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 22 Nov 2024 13:04:22 +0100 Subject: [PATCH 04/77] add save button --- .../field_final_side/field_final_side.tsx | 27 +++++++++++++------ .../field_final_side/translations.ts | 21 +++++++++++++++ .../final_readonly/field_final_readonly.tsx | 10 ++++--- 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side.tsx index e39ffbc7da52c..e0a97c1efb3a7 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side.tsx @@ -6,16 +6,16 @@ */ import React from 'react'; -import { EuiTitle } from '@elastic/eui'; +import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; import { SideHeader } from '../components/side_header'; import { FinalSideHelpInfo } from './final_side_help_info'; -import * as i18n from './translations'; import { FieldFinalReadOnly } from '../final_readonly/field_final_readonly'; import { FieldFinalEdit } from '../final_edit/field_final_edit'; import { FinalSideMode } from './final_side_mode'; import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; import { assertUnreachable } from '../../../../../../../common/utility_types'; import { FinalSideContextProvider, useFinalSideContext } from './final_side_context'; +import * as i18n from './translations'; interface FieldFinalSideProps { fieldName: UpgradeableDiffableFields; @@ -26,12 +26,23 @@ export function FieldFinalSide({ fieldName, initialMode }: FieldFinalSideProps): return ( <> - -

- {i18n.FINAL_UPDATE} - -

-
+ + + + +

+ {i18n.FINAL_UPDATE} + +

+
+
+
+ + {}}> + {i18n.SAVE} + + +
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/translations.ts index 8f6a10b5681be..223bb16498ecc 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/translations.ts @@ -13,3 +13,24 @@ export const FINAL_UPDATE = i18n.translate( defaultMessage: 'Final update', } ); + +export const SAVE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.field.save', + { + defaultMessage: 'Save', + } +); + +export const ACCEPT = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.field.accept', + { + defaultMessage: 'Accept', + } +); + +export const SAVE_AND_ACCEPT = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.field.saveAndAccept', + { + defaultMessage: 'Save and accept', + } +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx index 68a7db7dcc346..43c03a0da7cb9 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx @@ -5,8 +5,8 @@ * 2.0. */ -import { EuiButtonEmpty } from '@elastic/eui'; import React from 'react'; +import { EuiButtonEmpty, EuiFlexGroup } from '@elastic/eui'; import { useFinalSideContext } from '../field_final_side'; import * as i18n from '../translations'; import { FieldReadOnly } from './field_readonly'; @@ -16,9 +16,11 @@ export function FieldFinalReadOnly(): JSX.Element { return ( <> - - {i18n.EDIT_BUTTON_LABEL} - + + + {i18n.EDIT_BUTTON_LABEL} + + ); From 04b918d0dfd3c078c021a559a35c52a050c8a854 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Sat, 23 Nov 2024 14:03:32 +0100 Subject: [PATCH 05/77] display save button at the final side header --- .../field_upgrade_conflicts_resolver.tsx | 6 +- .../field_final_side/field_final_side.tsx | 37 ++++--- .../field_final_side_context.tsx | 101 ++++++++++++++++++ ...nfo.tsx => field_final_side_help_info.tsx} | 2 +- ..._side_mode.ts => field_final_side_mode.ts} | 2 +- .../field_final_side/final_side_context.tsx | 52 --------- .../three_way_diff/field_final_side/index.ts | 4 +- .../final_edit/field_final_edit.tsx | 6 +- .../fields/rule_field_edit_form_wrapper.tsx | 22 +++- .../final_readonly/field_final_readonly.tsx | 7 +- .../three_way_diff/translations.ts | 7 -- .../translation_tab/rule_query.tsx | 45 ++++++++ 12 files changed, 204 insertions(+), 87 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_context.tsx rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/{final_side_help_info.tsx => field_final_side_help_info.tsx} (96%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/{final_side_mode.ts => field_final_side_mode.ts} (90%) delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_context.tsx create mode 100644 x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/rule_query.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx index 743b1e16d15fd..24e1c7f2ce59d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx @@ -17,7 +17,7 @@ import type { import { ThreeWayDiffConflict } from '../../../../../../../common/api/detection_engine'; import type { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { ComparisonSide } from '../comparison_side/comparison_side'; -import { FieldFinalSide, FinalSideMode } from '../field_final_side'; +import { FieldFinalSide, FieldFinalSideMode } from '../field_final_side'; import { FieldUpgradeConflictsResolverHeader } from './field_upgrade_conflicts_resolver_header'; import { useDiffableRuleContext } from '../diffable_rule_context'; import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; @@ -37,8 +37,8 @@ export function FieldUpgradeConflictsResolver new Subject(), []); + const handleSaveButtonClick = useCallback(() => submitSubject.next(), [submitSubject]); + return ( <> @@ -32,32 +39,38 @@ export function FieldFinalSide({ fieldName, initialMode }: FieldFinalSideProps):

{i18n.FINAL_UPDATE} - +

- {}}> + {i18n.SAVE}
- + - + ); } function FieldFinalSideContent(): JSX.Element { - const { mode } = useFinalSideContext(); + const { + state: { mode }, + } = useFieldFinalSideContext(); switch (mode) { - case FinalSideMode.Readonly: + case FieldFinalSideMode.Readonly: return ; - case FinalSideMode.Edit: + case FieldFinalSideMode.Edit: return ; default: return assertUnreachable(mode); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_context.tsx new file mode 100644 index 0000000000000..2333644798d68 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_context.tsx @@ -0,0 +1,101 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { createContext, useContext, type PropsWithChildren, useState, useMemo } from 'react'; +import type { Subject } from 'rxjs'; +import { useBoolean } from '@kbn/react-hooks'; +import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; +import { invariant } from '../../../../../../../common/utils/invariant'; +import { FieldFinalSideMode } from './field_final_side_mode'; + +interface FieldFinalSideState { + /** + * Field name of an upgradable field from DiffableRule + */ + fieldName: UpgradeableDiffableFields; + /** + * Field final side view mode `Readonly` or `Editing` + */ + mode: FieldFinalSideMode; + /** + * Whether the field value is valid. It might be not valid in editing after form validation. + */ + valid: boolean; + /** + * Triggers field form submission + */ + triggerSubmitSubject: Subject; +} + +interface FieldFinalSideActions { + /** + * Sets Readonly field final side view mode + */ + setReadOnlyMode: () => void; + /** + * Sets Editing field final side view mode + */ + setEditMode: () => void; + /** + * Sets field's value validity + */ + setValid: (value: boolean) => void; +} + +interface FieldFinalSideContextType { + state: FieldFinalSideState; + actions: FieldFinalSideActions; +} + +const FieldFinalSideContext = createContext(null); + +interface FieldFinalSideContextProviderProps { + fieldName: UpgradeableDiffableFields; + initialMode: FieldFinalSideMode; + submitSubject: Subject; +} + +export function FieldFinalSideContextProvider({ + children, + fieldName, + initialMode, + submitSubject, +}: PropsWithChildren) { + const [valid, setValid] = useState(true); + const [editing, { on: setEditMode, off: setReadOnlyMode }] = useBoolean( + initialMode === FieldFinalSideMode.Edit + ); + + const contextValue: FieldFinalSideContextType = useMemo( + () => ({ + state: { + fieldName, + mode: editing ? FieldFinalSideMode.Edit : FieldFinalSideMode.Readonly, + valid: editing === false || valid, + triggerSubmitSubject: submitSubject, + }, + actions: { + setReadOnlyMode, + setEditMode, + setValid, + }, + }), + [fieldName, editing, valid, submitSubject, setReadOnlyMode, setEditMode, setValid] + ); + + return ( + {children} + ); +} + +export function useFieldFinalSideContext() { + const context = useContext(FieldFinalSideContext); + + invariant(context !== null, 'useFinalSideContext must be used inside a FinalSideContextProvider'); + + return context; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_help_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_help_info.tsx similarity index 96% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_help_info.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_help_info.tsx index 51e0c5097b97d..32a55401dbf3c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_help_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_help_info.tsx @@ -19,7 +19,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; */ const POPOVER_WIDTH = 320; -export function FinalSideHelpInfo(): JSX.Element { +export function FieldFinalSideHelpInfo(): JSX.Element { const [isPopoverOpen, togglePopover] = useToggle(false); const button = ( diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_mode.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_mode.ts similarity index 90% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_mode.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_mode.ts index cf8d681580e11..8c0dc3db3d261 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_mode.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_mode.ts @@ -5,7 +5,7 @@ * 2.0. */ -export enum FinalSideMode { +export enum FieldFinalSideMode { Readonly = 'readonly', Edit = 'edit', } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_context.tsx deleted file mode 100644 index e27e1f78e320d..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/final_side_context.tsx +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { createContext, useContext, type PropsWithChildren, useCallback } from 'react'; -import { invariant } from '../../../../../../../common/utils/invariant'; -import { FinalSideMode } from './final_side_mode'; -import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; - -interface FinalSideContextType { - fieldName: UpgradeableDiffableFields; - mode: FinalSideMode; - setReadOnlyMode: () => void; - setEditMode: () => void; -} - -const FinalSideContext = createContext(null); - -interface FinalSideContextProviderProps { - fieldName: UpgradeableDiffableFields; - initialMode: FinalSideMode; -} - -export function FinalSideContextProvider({ - children, - fieldName, - initialMode, -}: PropsWithChildren) { - const [mode, setMode] = React.useState(initialMode); - const setReadOnlyMode = useCallback(() => setMode(FinalSideMode.Readonly), []); - const setEditMode = useCallback(() => setMode(FinalSideMode.Edit), []); - - const contextValue = { - fieldName, - setReadOnlyMode, - setEditMode, - mode, - }; - - return {children}; -} - -export function useFinalSideContext() { - const context = useContext(FinalSideContext); - - invariant(context !== null, 'useFinalSideContext must be used inside a FinalSideContextProvider'); - - return context; -} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/index.ts index aeadd58708780..1298a5de75739 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/index.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/index.ts @@ -5,6 +5,6 @@ * 2.0. */ -export * from './final_side_mode'; +export * from './field_final_side_mode'; export * from './field_final_side'; -export { useFinalSideContext } from './final_side_context'; +export { useFieldFinalSideContext } from './field_final_side_context'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx index a97412d39afc7..c6a57972c3b8b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx @@ -25,7 +25,7 @@ import type { UpgradeableMachineLearningFields, } from '../../../../model/prebuilt_rule_upgrade/fields'; import { isCommonFieldName } from '../../../../model/prebuilt_rule_upgrade/fields'; -import { useFinalSideContext } from '../field_final_side'; +import { useFieldFinalSideContext } from '../field_final_side'; import { EqlRuleFieldEdit } from './eql_rule_field_edit'; import { EsqlRuleFieldEdit } from './esql_rule_field_edit'; import { MachineLearningRuleFieldEdit } from './machine_learning_rule_field_edit'; @@ -34,7 +34,9 @@ export function FieldFinalEdit(): JSX.Element { const { finalDiffableRule } = useDiffableRuleContext(); const { type } = finalDiffableRule; - const { fieldName } = useFinalSideContext(); + const { + state: { fieldName }, + } = useFieldFinalSideContext(); if (isCommonFieldName(fieldName)) { return ; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx index ff4bf019fd46e..7d835a1d38aa5 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx @@ -16,7 +16,7 @@ import type { DiffableAllFields, DiffableRule, } from '../../../../../../../../common/api/detection_engine'; -import { useFinalSideContext } from '../../field_final_side'; +import { useFieldFinalSideContext } from '../../field_final_side'; import { useDiffableRuleContext } from '../../diffable_rule_context'; import * as i18n from '../../translations'; import type { RuleFieldEditComponentProps } from './rule_field_edit_component_props'; @@ -55,7 +55,10 @@ export function RuleFieldEditFormWrapper({ deserializer, serializer, }: RuleFieldEditFormWrapperProps) { - const { fieldName, setReadOnlyMode } = useFinalSideContext(); + const { + state: { fieldName, triggerSubmitSubject }, + actions: { setReadOnlyMode, setValid }, + } = useFieldFinalSideContext(); const { finalDiffableRule, setRuleFieldResolvedValue } = useDiffableRuleContext(); const deserialize = useCallback( @@ -110,15 +113,24 @@ export function RuleFieldEditFormWrapper({ form.validate(); }, [form]); + // Sets global field value validity state + useEffect(() => { + setValid(form.isValid ?? false); + }, [form.isValid, setValid]); + + // Submits form upon submission events arrival + useEffect(() => { + const subscription = triggerSubmitSubject.subscribe(() => form.submit()); + + return () => subscription.unsubscribe(); + }, [triggerSubmitSubject, form]); + return ( <> {i18n.CANCEL_BUTTON_LABEL} - - {i18n.SAVE_BUTTON_LABEL} - {modal}
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx index 43c03a0da7cb9..bc3d2de8dc9f2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx @@ -7,12 +7,15 @@ import React from 'react'; import { EuiButtonEmpty, EuiFlexGroup } from '@elastic/eui'; -import { useFinalSideContext } from '../field_final_side'; +import { useFieldFinalSideContext } from '../field_final_side'; import * as i18n from '../translations'; import { FieldReadOnly } from './field_readonly'; export function FieldFinalReadOnly(): JSX.Element { - const { setEditMode, fieldName } = useFinalSideContext(); + const { + state: { fieldName }, + actions: { setEditMode }, + } = useFieldFinalSideContext(); return ( <> diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.ts index ced733d87ff6e..b03f8442b0c75 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.ts @@ -14,13 +14,6 @@ export const CANCEL_BUTTON_LABEL = i18n.translate( } ); -export const SAVE_BUTTON_LABEL = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.saveButtonLabel', - { - defaultMessage: 'Save', - } -); - export const EDIT_BUTTON_LABEL = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.editButtonLabel', { diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/rule_query.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/rule_query.tsx new file mode 100644 index 0000000000000..3cfd9f3b10f52 --- /dev/null +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/rule_query.tsx @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useMemo } from 'react'; +import { EuiMarkdownEditor, EuiMarkdownFormat, EuiTitle } from '@elastic/eui'; +import { SideHeader } from '../../../../../detection_engine/rule_management/components/rule_details/three_way_diff/components/side_header'; +import * as i18n from './translations'; + +interface RuleQueryProps { + title: string; + query: string; + canEdit?: boolean; +} + +export const RuleQueryComponent = ({ title, query, canEdit }: RuleQueryProps) => { + const queryTextComponent = useMemo(() => { + if (canEdit) { + return ( + {}} + height={400} + initialViewMode={'viewing'} + /> + ); + } else { + return {query}; + } + }, [canEdit, query]); + return ( + <> + + +

{title}

+
+
+ {queryTextComponent} + + ); +}; From b5baa0f097ee35620fa201b194e066cf00a8363e Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Sat, 23 Nov 2024 14:21:45 +0100 Subject: [PATCH 06/77] implement rule field resolver scenarios --- ....tsx => field_comparison_side.stories.tsx} | 6 +- ...son_side.tsx => field_comparison_side.tsx} | 6 +- .../field_upgrade_conflicts_resolver.tsx | 13 +-- .../components/field_final_side.tsx | 36 ++++++ .../components/field_final_side_content.tsx | 49 ++++++++ .../components/field_final_side_header.tsx | 94 +++++++++++++++ .../field_final_side_help_info.tsx | 0 .../rule_field_edit_component_props.ts | 0 .../rule_field_edit_form_wrapper.tsx | 45 +++---- .../{ => components}/translations.ts | 14 +++ .../context/field_edit_form_context.tsx | 62 ++++++++++ .../field_final_side_context.tsx | 36 ++---- .../field_final_side/field_final_side.tsx | 78 ------------- .../three_way_diff/field_final_side/index.ts | 6 +- .../final_edit/common_rule_field_edit.tsx | 2 +- .../suppression_edit_adapter.tsx | 2 +- .../suppression_edit_form.tsx | 2 +- .../fields/data_source/data_source_edit.tsx | 2 +- .../data_source/data_source_edit_form.tsx | 2 +- .../data_source_type_selector_field.tsx | 2 +- .../eql_query/eql_query_edit_adapter.tsx | 2 +- .../fields/eql_query/eql_query_edit_form.tsx | 2 +- .../fields/kql_query/kql_query_edit.tsx | 2 +- .../fields/kql_query/kql_query_edit_form.tsx | 2 +- .../suppression_edit_form.tsx | 4 +- .../three_way_diff/final_edit/index.ts | 8 ++ .../final_readonly/field_final_readonly.tsx | 108 ++++++++++++++--- .../final_readonly/field_readonly.tsx | 110 ------------------ .../alert_suppression.stories.tsx | 9 +- .../anomaly_threshold.stories.tsx | 9 +- .../building_block/building_block.stories.tsx | 9 +- .../data_source/data_source.stories.tsx | 7 +- .../description/description.stories.tsx | 9 +- .../fields/eql_query/eql_query.stories.tsx | 5 +- .../fields/esql_query/esql_query.stories.tsx | 11 +- .../false_positives.stories.tsx | 9 +- .../history_window_start.stories.tsx | 9 +- .../investigation_fields.stories.tsx | 9 +- .../fields/kql_query/kql_query.stories.tsx | 7 +- .../machine_learning_job_id.stories.tsx | 9 +- .../max_signals/max_signals.stories.tsx | 9 +- .../fields/name/name.stories.tsx | 6 +- .../new_terms_fields.stories.tsx | 9 +- .../fields/note/note.stories.tsx | 6 +- .../fields/references/references.stories.tsx | 9 +- .../related_integrations.stories.tsx | 9 +- .../required_fields.stories.tsx | 9 +- .../fields/risk_score/risk_score.stories.tsx | 9 +- .../risk_score_mapping.stories.tsx | 9 +- .../rule_name_override.stories.tsx | 9 +- .../rule_schedule/rule_schedule.stories.tsx | 9 +- .../fields/setup/setup.stories.tsx | 6 +- .../fields/severity/severity.stories.tsx | 6 +- .../severity_mapping.stories.tsx | 9 +- .../fields/tags/tags.stories.tsx | 6 +- .../fields/threat/threat.stories.tsx | 6 +- .../threat_index/threat_index.stories.tsx | 9 +- .../threat_indicator_path.stories.tsx | 9 +- .../threat_mapping/threat_mapping.stories.tsx | 9 +- .../threat_query/threat_query.stories.tsx | 5 +- .../fields/threshold/threshold.stories.tsx | 9 +- .../timeline_template.stories.tsx | 9 +- .../timestamp_override.stories.tsx | 9 +- .../fields/type/type.stories.tsx | 6 +- .../three_way_diff/final_readonly/index.ts | 8 ++ .../three_way_diff_storybook_providers.tsx | 12 +- .../three_way_diff/translations.ts | 22 ---- 67 files changed, 613 insertions(+), 417 deletions(-) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/{comparison_side.stories.tsx => field_comparison_side.stories.tsx} (99%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/{comparison_side.tsx => field_comparison_side.tsx} (91%) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_content.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/{ => components}/field_final_side_help_info.tsx (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{final_edit/fields => field_final_side/components}/rule_field_edit_component_props.ts (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{final_edit/fields => field_final_side/components}/rule_field_edit_form_wrapper.tsx (81%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/{ => components}/translations.ts (74%) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/context/field_edit_form_context.tsx rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/{ => context}/field_final_side_context.tsx (64%) delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/index.ts delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_readonly.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/index.ts delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.ts diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.stories.tsx similarity index 99% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side.stories.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.stories.tsx index 37ddb71dce9f7..d9079a0669d20 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.stories.tsx @@ -7,7 +7,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; -import { ComparisonSide } from './comparison_side'; +import { FieldComparisonSide } from './field_comparison_side'; import type { ThreeWayDiff, DiffableAllFields, @@ -20,7 +20,7 @@ import { KqlQueryType, } from '../../../../../../../common/api/detection_engine'; export default { - component: ComparisonSide, + component: FieldComparisonSide, title: 'Rule Management/Prebuilt Rules/Upgrade Flyout/ThreeWayDiff/ComparisonSide', argTypes: { fieldName: { @@ -46,7 +46,7 @@ interface TemplateProps { const Template: Story> = (args) => { return ( - { +interface FieldComparisonSideProps { fieldName: FieldName; fieldThreeWayDiff: ThreeWayDiff; resolvedValue: DiffableAllFields[FieldName]; } -export function ComparisonSide({ +export function FieldComparisonSide({ fieldName, fieldThreeWayDiff, resolvedValue, -}: ComparisonSideProps) { +}: FieldComparisonSideProps) { const [selectedVersions, setSelectedVersions] = useState( SelectedVersions.CurrentFinal ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx index 24e1c7f2ce59d..29951d7f593b1 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx @@ -16,8 +16,8 @@ import type { } from '../../../../../../../common/api/detection_engine'; import { ThreeWayDiffConflict } from '../../../../../../../common/api/detection_engine'; import type { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; -import { ComparisonSide } from '../comparison_side/comparison_side'; -import { FieldFinalSide, FieldFinalSideMode } from '../field_final_side'; +import { FieldComparisonSide } from '../comparison_side/field_comparison_side'; +import { FieldFinalSide } from '../field_final_side'; import { FieldUpgradeConflictsResolverHeader } from './field_upgrade_conflicts_resolver_header'; import { useDiffableRuleContext } from '../diffable_rule_context'; import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; @@ -35,11 +35,6 @@ export function FieldUpgradeConflictsResolver): JSX.Element { const { euiTheme } = useEuiTheme(); const hasConflict = fieldThreeWayDiff.conflict !== ThreeWayDiffConflict.NONE; - const initialFieldFinalSideMode = - fieldThreeWayDiff.conflict === ThreeWayDiffConflict.NON_SOLVABLE - ? FieldFinalSideMode.Edit - : FieldFinalSideMode.Readonly; - const { finalDiffableRule } = useDiffableRuleContext(); return ( @@ -56,7 +51,7 @@ export function FieldUpgradeConflictsResolver - } resolvedValue={finalDiffableRule[fieldName] as DiffableAllFields[FieldName]} @@ -70,7 +65,7 @@ export function FieldUpgradeConflictsResolver - + diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side.tsx new file mode 100644 index 0000000000000..7d630e47f416f --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side.tsx @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { FieldFinalSideMode } from '../field_final_side_mode'; +import { FieldUpgradeState } from '../../../../../model/prebuilt_rule_upgrade'; +import type { UpgradeableDiffableFields } from '../../../../../model/prebuilt_rule_upgrade/fields'; +import { FieldFinalSideContextProvider } from '../context/field_final_side_context'; +import { FieldEditFormContextProvider } from '../context/field_edit_form_context'; +import { FieldFinalSideContent } from './field_final_side_content'; +import { FieldFinalSideHeader } from './field_final_side_header'; + +interface FieldFinalSideProps { + fieldName: UpgradeableDiffableFields; + fieldUpgradeState: FieldUpgradeState; +} + +export function FieldFinalSide({ fieldName, fieldUpgradeState }: FieldFinalSideProps): JSX.Element { + const initialMode = + fieldUpgradeState === FieldUpgradeState.NonSolvableConflict + ? FieldFinalSideMode.Edit + : FieldFinalSideMode.Readonly; + + return ( + + + + + + + ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_content.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_content.tsx new file mode 100644 index 0000000000000..64f943a3372e6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_content.tsx @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiButtonEmpty, EuiFlexGroup } from '@elastic/eui'; +import { FieldFinalReadOnly } from '../../final_readonly'; +import { FieldFinalEdit } from '../../final_edit'; +import { FieldFinalSideMode } from '../field_final_side_mode'; +import { assertUnreachable } from '../../../../../../../../common/utility_types'; +import { useFieldFinalSideContext } from '../context/field_final_side_context'; +import * as i18n from './translations'; + +export function FieldFinalSideContent(): JSX.Element { + const { + state: { mode }, + actions: { setEditMode, setReadOnlyMode }, + } = useFieldFinalSideContext(); + + switch (mode) { + case FieldFinalSideMode.Readonly: + return ( + <> + + + {i18n.EDIT} + + + + + ); + case FieldFinalSideMode.Edit: + return ( + <> + + + {i18n.CANCEL} + + + + + ); + default: + return assertUnreachable(mode); + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx new file mode 100644 index 0000000000000..03ea8c1f630d4 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx @@ -0,0 +1,94 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { PropsWithChildren } from 'react'; +import React, { useCallback } from 'react'; +import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; +import type { DiffableAllFields } from '../../../../../../../../common/api/detection_engine'; +import { FieldUpgradeState } from '../../../../../model/prebuilt_rule_upgrade'; +import { SideHeader } from '../../components/side_header'; +import { useFieldFinalSideContext } from '../context/field_final_side_context'; +import { FieldFinalSideMode } from '../field_final_side_mode'; +import { assertUnreachable } from '../../../../../../../../common/utility_types'; +import { useFieldEditFormContext } from '../context/field_edit_form_context'; +import { FieldFinalSideHelpInfo } from './field_final_side_help_info'; +import { useDiffableRuleContext } from '../../diffable_rule_context'; +import * as i18n from './translations'; + +interface FieldFinalSideHeaderProps { + fieldUpgradeState: FieldUpgradeState; +} + +export function FieldFinalSideHeader({ + fieldUpgradeState, +}: FieldFinalSideHeaderProps): JSX.Element { + const { + state: { fieldName, mode }, + } = useFieldFinalSideContext(); + const { form } = useFieldEditFormContext(); + const { finalDiffableRule, setRuleFieldResolvedValue } = useDiffableRuleContext(); + const handleAccept = useCallback( + () => + setRuleFieldResolvedValue({ + ruleId: finalDiffableRule.rule_id, + fieldName: fieldName as keyof DiffableAllFields, + resolvedValue: finalDiffableRule[fieldName] as DiffableAllFields[typeof fieldName], + }), + [finalDiffableRule, fieldName, setRuleFieldResolvedValue] + ); + const handleSave = useCallback(() => form?.submit(), [form]); + + switch (mode) { + case FieldFinalSideMode.Readonly: + return ( + + + {fieldUpgradeState !== FieldUpgradeState.Accepted && ( + + {i18n.ACCEPT} + + )} + + + ); + case FieldFinalSideMode.Edit: + return ( + + + + {fieldUpgradeState !== FieldUpgradeState.Accepted ? i18n.SAVE_AND_ACCEPT : i18n.SAVE} + + + + ); + default: + return assertUnreachable(mode); + } +} + +function StaticHeaderContent({ children }: PropsWithChildren<{}>): JSX.Element { + return ( + + + + +

+ {i18n.FINAL_UPDATE} + +

+
+
+
+ {children} +
+ ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_help_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_help_info.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_help_info.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_help_info.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_component_props.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_component_props.ts similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_component_props.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_component_props.ts diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_form_wrapper.tsx similarity index 81% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_form_wrapper.tsx index 7d835a1d38aa5..85f5930096437 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_form_wrapper.tsx @@ -11,14 +11,15 @@ import { extractValidationMessages } from '../../../../../../rule_creation/logic import type { FormWithWarningsSubmitHandler } from '../../../../../../../common/hooks/use_form_with_warnings'; import { useFormWithWarnings } from '../../../../../../../common/hooks/use_form_with_warnings'; import { Form } from '../../../../../../../shared_imports'; +import { useForm, Form } from '../../../../../../../shared_imports'; import type { FormSchema, FormData } from '../../../../../../../shared_imports'; import type { DiffableAllFields, DiffableRule, } from '../../../../../../../../common/api/detection_engine'; -import { useFieldFinalSideContext } from '../../field_final_side'; +import { useFieldFinalSideContext } from '../context/field_final_side_context'; import { useDiffableRuleContext } from '../../diffable_rule_context'; -import * as i18n from '../../translations'; +import { useFieldEditFormContext } from '../context/field_edit_form_context'; import type { RuleFieldEditComponentProps } from './rule_field_edit_component_props'; import { useConfirmValidationErrorsModal } from '../../../../../../../common/hooks/use_confirm_validation_errors_modal'; import { @@ -55,9 +56,10 @@ export function RuleFieldEditFormWrapper({ deserializer, serializer, }: RuleFieldEditFormWrapperProps) { + const { registerForm } = useFieldEditFormContext(); const { - state: { fieldName, triggerSubmitSubject }, - actions: { setReadOnlyMode, setValid }, + state: { fieldName }, + actions: { setReadOnlyMode }, } = useFieldFinalSideContext(); const { finalDiffableRule, setRuleFieldResolvedValue } = useDiffableRuleContext(); @@ -107,40 +109,23 @@ export function RuleFieldEditFormWrapper({ }, }); + useEffect(() => registerForm(form), [registerForm, form]); + // form.isValid has `undefined` value until all fields are dirty. // Run the validation upfront to visualize form validity state. useEffect(() => { form.validate(); }, [form]); - // Sets global field value validity state - useEffect(() => { - setValid(form.isValid ?? false); - }, [form.isValid, setValid]); - - // Submits form upon submission events arrival - useEffect(() => { - const subscription = triggerSubmitSubject.subscribe(() => form.submit()); - - return () => subscription.unsubscribe(); - }, [triggerSubmitSubject, form]); - return ( - <> - - - {i18n.CANCEL_BUTTON_LABEL} - - + {modal} - - - - + + ); } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/translations.ts similarity index 74% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/translations.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/translations.ts index 223bb16498ecc..4c44629bf4268 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/translations.ts @@ -34,3 +34,17 @@ export const SAVE_AND_ACCEPT = i18n.translate( defaultMessage: 'Save and accept', } ); + +export const CANCEL = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.cancelButtonLabel', + { + defaultMessage: 'Cancel', + } +); + +export const EDIT = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.editButtonLabel', + { + defaultMessage: 'Edit', + } +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/context/field_edit_form_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/context/field_edit_form_context.tsx new file mode 100644 index 0000000000000..ff67656d3e6ac --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/context/field_edit_form_context.tsx @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { + createContext, + useContext, + type PropsWithChildren, + useState, + useCallback, +} from 'react'; +import type { FormHook } from '../../../../../../../shared_imports'; +import { invariant } from '../../../../../../../../common/utils/invariant'; + +type FieldEditFormCleanUp = () => void; + +interface FieldEditFormContextType { + form: FormHook | undefined; + registerForm: (form: FormHook) => FieldEditFormCleanUp; +} + +const FieldEditFormContext = createContext(null); + +export function FieldEditFormContextProvider({ children }: PropsWithChildren<{}>) { + const [form, setForm] = useState(); + const registerForm = useCallback( + (formToRegister: FormHook) => { + setForm((prevForm) => { + if (prevForm) { + throw new Error( + 'Unexpected new form registration while the old one was not cleaned. Do you properly cleanup form by returning registerForm result from useEffect.' + ); + } + + return formToRegister; + }); + + return () => setForm(undefined); + }, + [setForm] + ); + + return ( + + {children} + + ); +} + +export function useFieldEditFormContext() { + const context = useContext(FieldEditFormContext); + + invariant( + context !== null, + 'useFieldEditFormContext must be used inside a FieldEditFormProvider' + ); + + return context; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/context/field_final_side_context.tsx similarity index 64% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_context.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/context/field_final_side_context.tsx index 2333644798d68..295bb31fc3f5c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/context/field_final_side_context.tsx @@ -5,12 +5,11 @@ * 2.0. */ -import React, { createContext, useContext, type PropsWithChildren, useState, useMemo } from 'react'; -import type { Subject } from 'rxjs'; +import React, { createContext, useContext, type PropsWithChildren, useMemo } from 'react'; import { useBoolean } from '@kbn/react-hooks'; -import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; -import { invariant } from '../../../../../../../common/utils/invariant'; -import { FieldFinalSideMode } from './field_final_side_mode'; +import type { UpgradeableDiffableFields } from '../../../../../model/prebuilt_rule_upgrade/fields'; +import { invariant } from '../../../../../../../../common/utils/invariant'; +import { FieldFinalSideMode } from '../field_final_side_mode'; interface FieldFinalSideState { /** @@ -21,14 +20,6 @@ interface FieldFinalSideState { * Field final side view mode `Readonly` or `Editing` */ mode: FieldFinalSideMode; - /** - * Whether the field value is valid. It might be not valid in editing after form validation. - */ - valid: boolean; - /** - * Triggers field form submission - */ - triggerSubmitSubject: Subject; } interface FieldFinalSideActions { @@ -40,10 +31,6 @@ interface FieldFinalSideActions { * Sets Editing field final side view mode */ setEditMode: () => void; - /** - * Sets field's value validity - */ - setValid: (value: boolean) => void; } interface FieldFinalSideContextType { @@ -56,16 +43,13 @@ const FieldFinalSideContext = createContext(nu interface FieldFinalSideContextProviderProps { fieldName: UpgradeableDiffableFields; initialMode: FieldFinalSideMode; - submitSubject: Subject; } export function FieldFinalSideContextProvider({ children, fieldName, initialMode, - submitSubject, }: PropsWithChildren) { - const [valid, setValid] = useState(true); const [editing, { on: setEditMode, off: setReadOnlyMode }] = useBoolean( initialMode === FieldFinalSideMode.Edit ); @@ -75,16 +59,13 @@ export function FieldFinalSideContextProvider({ state: { fieldName, mode: editing ? FieldFinalSideMode.Edit : FieldFinalSideMode.Readonly, - valid: editing === false || valid, - triggerSubmitSubject: submitSubject, }, actions: { setReadOnlyMode, setEditMode, - setValid, }, }), - [fieldName, editing, valid, submitSubject, setReadOnlyMode, setEditMode, setValid] + [fieldName, editing, setReadOnlyMode, setEditMode] ); return ( @@ -92,10 +73,13 @@ export function FieldFinalSideContextProvider({ ); } -export function useFieldFinalSideContext() { +export function useFieldFinalSideContext(): FieldFinalSideContextType { const context = useContext(FieldFinalSideContext); - invariant(context !== null, 'useFinalSideContext must be used inside a FinalSideContextProvider'); + invariant( + context !== null, + 'useFieldFinalSideContext must be used inside a FieldFinalSideContextProvider' + ); return context; } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side.tsx deleted file mode 100644 index 764b090728ef1..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side.tsx +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useCallback, useMemo } from 'react'; -import { Subject } from 'rxjs'; -import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; -import { SideHeader } from '../components/side_header'; -import { FieldFinalSideHelpInfo } from './field_final_side_help_info'; -import { FieldFinalReadOnly } from '../final_readonly/field_final_readonly'; -import { FieldFinalEdit } from '../final_edit/field_final_edit'; -import { FieldFinalSideMode } from './field_final_side_mode'; -import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; -import { assertUnreachable } from '../../../../../../../common/utility_types'; -import { - FieldFinalSideContextProvider, - useFieldFinalSideContext, -} from './field_final_side_context'; -import * as i18n from './translations'; - -interface FieldFinalSideProps { - fieldName: UpgradeableDiffableFields; - initialMode: FieldFinalSideMode; -} - -export function FieldFinalSide({ fieldName, initialMode }: FieldFinalSideProps): JSX.Element { - const submitSubject = useMemo(() => new Subject(), []); - const handleSaveButtonClick = useCallback(() => submitSubject.next(), [submitSubject]); - - return ( - <> - - - - - -

- {i18n.FINAL_UPDATE} - -

-
-
-
- - - {i18n.SAVE} - - -
-
- - - - - ); -} - -function FieldFinalSideContent(): JSX.Element { - const { - state: { mode }, - } = useFieldFinalSideContext(); - - switch (mode) { - case FieldFinalSideMode.Readonly: - return ; - case FieldFinalSideMode.Edit: - return ; - default: - return assertUnreachable(mode); - } -} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/index.ts index 1298a5de75739..a0d86970f9956 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/index.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/index.ts @@ -6,5 +6,7 @@ */ export * from './field_final_side_mode'; -export * from './field_final_side'; -export { useFieldFinalSideContext } from './field_final_side_context'; +export * from './components/field_final_side'; +export type * from './components/rule_field_edit_component_props'; +export * from './components/rule_field_edit_form_wrapper'; +export { useFieldFinalSideContext } from './context/field_final_side_context'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/common_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/common_rule_field_edit.tsx index 3f10ce014d82e..0b8668e90a903 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/common_rule_field_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/common_rule_field_edit.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { RuleFieldEditFormWrapper } from './fields/rule_field_edit_form_wrapper'; +import { RuleFieldEditFormWrapper } from '../field_final_side'; import type { UpgradeableCommonFields } from '../../../../model/prebuilt_rule_upgrade/fields'; import { BuildingBlockEdit, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/alert_suppression/suppression_edit_adapter.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/alert_suppression/suppression_edit_adapter.tsx index 6dfd38d5676d3..3100e5c21f8bb 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/alert_suppression/suppression_edit_adapter.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/alert_suppression/suppression_edit_adapter.tsx @@ -11,7 +11,7 @@ import { getTermsAggregationFields } from '../../../../../../../rule_creation_ui import { isEsqlRule, isMlRule } from '../../../../../../../../../common/detection_engine/utils'; import { useAllEsqlRuleFields } from '../../../../../../../rule_creation_ui/hooks'; import { useMLRuleConfig } from '../../../../../../../../common/components/ml/hooks/use_ml_rule_config'; -import type { RuleFieldEditComponentProps } from '../rule_field_edit_component_props'; +import type { RuleFieldEditComponentProps } from '../../../field_final_side'; import { useDiffableRuleDataView } from '../hooks/use_diffable_rule_data_view'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/alert_suppression/suppression_edit_form.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/alert_suppression/suppression_edit_form.tsx index f6ed2e5c657c7..e01db6f428887 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/alert_suppression/suppression_edit_form.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/alert_suppression/suppression_edit_form.tsx @@ -17,7 +17,7 @@ import { AlertSuppressionDurationType } from '../../../../../../../../detections import { type FormData } from '../../../../../../../../shared_imports'; import { DEFAULT_SUPPRESSION_MISSING_FIELDS_STRATEGY } from '../../../../../../../../../common/detection_engine/constants'; import { type AlertSuppression } from '../../../../../../../../../common/api/detection_engine'; -import { RuleFieldEditFormWrapper } from '../rule_field_edit_form_wrapper'; +import { RuleFieldEditFormWrapper } from '../../../field_final_side'; import { AlertSuppressionEditAdapter } from './suppression_edit_adapter'; import { alertSuppressionFormSchema, type AlertSuppressionFormData } from './form_schema'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/data_source/data_source_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/data_source/data_source_edit.tsx index 2f697288221cf..7ff2b7fdbd6fd 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/data_source/data_source_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/data_source/data_source_edit.tsx @@ -11,7 +11,7 @@ import { css } from '@emotion/css'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { DataSourceType } from '../../../../../../../../../common/api/detection_engine/prebuilt_rules'; import { UseMultiFields } from '../../../../../../../../shared_imports'; -import type { RuleFieldEditComponentProps } from '../rule_field_edit_component_props'; +import type { RuleFieldEditComponentProps } from '../../../field_final_side'; import { IndexPatternField } from './index_pattern_edit'; import { DataSourceInfoText } from './data_source_info_text'; import { DataViewField } from './data_view_field'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/data_source/data_source_edit_form.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/data_source/data_source_edit_form.tsx index e30b713908a02..ec9e49bb7ab17 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/data_source/data_source_edit_form.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/data_source/data_source_edit_form.tsx @@ -16,7 +16,7 @@ import { FIELD_TYPES, } from '../../../../../../../../shared_imports'; import { DataSourceType } from '../../../../../../../../../common/api/detection_engine/prebuilt_rules'; -import { RuleFieldEditFormWrapper } from '../rule_field_edit_form_wrapper'; +import { RuleFieldEditFormWrapper } from '../../../field_final_side'; import { DataSourceEdit } from './data_source_edit'; import { INDEX_HELPER_TEXT } from '../../../../../../../rule_creation_ui/components/step_define_rule/translations'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/data_source/data_source_type_selector_field.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/data_source/data_source_type_selector_field.tsx index 9e24fd6c56c77..3562e7de82d66 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/data_source/data_source_type_selector_field.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/data_source/data_source_type_selector_field.tsx @@ -10,7 +10,7 @@ import type { EuiButtonGroupOptionProps } from '@elastic/eui'; import { EuiButtonGroup } from '@elastic/eui'; import { DataSourceType } from '../../../../../../../../../common/api/detection_engine/prebuilt_rules'; import type { FieldHook } from '../../../../../../../../shared_imports'; -import type { ResetFormFn } from '../rule_field_edit_component_props'; +import type { ResetFormFn } from '../../../field_final_side'; import * as i18n from './translations'; interface DataSourceTypeSelectorFieldProps { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/eql_query/eql_query_edit_adapter.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/eql_query/eql_query_edit_adapter.tsx index cea9b9308c0df..73e7c553c9127 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/eql_query/eql_query_edit_adapter.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/eql_query/eql_query_edit_adapter.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { DataViewBase } from '@kbn/es-query'; import { EqlQueryEdit } from '../../../../../../../rule_creation/components/eql_query_edit'; -import type { RuleFieldEditComponentProps } from '../rule_field_edit_component_props'; +import type { RuleFieldEditComponentProps } from '../../../field_final_side'; import { useDiffableRuleDataView } from '../hooks/use_diffable_rule_data_view'; export function EqlQueryEditAdapter({ diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/eql_query/eql_query_edit_form.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/eql_query/eql_query_edit_form.tsx index 4dd953006d39c..f357504af76f0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/eql_query/eql_query_edit_form.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/eql_query/eql_query_edit_form.tsx @@ -10,7 +10,7 @@ import type { Filter } from '@kbn/es-query'; import type { EqlOptions } from '@kbn/timelines-plugin/common'; import type { FieldValueQueryBar } from '../../../../../../../rule_creation_ui/components/query_bar_field'; import type { FormData, FormSchema } from '../../../../../../../../shared_imports'; -import { RuleFieldEditFormWrapper } from '../rule_field_edit_form_wrapper'; +import { RuleFieldEditFormWrapper } from '../../../field_final_side'; import { type DiffableRule, RuleEqlQuery, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query/kql_query_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query/kql_query_edit.tsx index 27415855adfbe..f377e17d8e23b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query/kql_query_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query/kql_query_edit.tsx @@ -18,7 +18,7 @@ import type { DiffableRule } from '../../../../../../../../../common/api/detecti import type { SetRuleQuery } from '../../../../../../../../detections/containers/detection_engine/rules/use_rule_from_timeline'; import { useRuleFromTimeline } from '../../../../../../../../detections/containers/detection_engine/rules/use_rule_from_timeline'; import { useGetSavedQuery } from '../../../../../../../../detections/pages/detection_engine/rules/use_get_saved_query'; -import type { RuleFieldEditComponentProps } from '../rule_field_edit_component_props'; +import type { RuleFieldEditComponentProps } from '../../../field_final_side'; import { useDiffableRuleDataView } from '../hooks/use_diffable_rule_data_view'; export function KqlQueryEdit({ diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query/kql_query_edit_form.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query/kql_query_edit_form.tsx index 98ffc4b6bfdf0..a02fa9b9fd9d4 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query/kql_query_edit_form.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query/kql_query_edit_form.tsx @@ -9,8 +9,8 @@ import React from 'react'; import type { Type } from '@kbn/securitysolution-io-ts-alerting-types'; import type { FormData, FormSchema } from '../../../../../../../../shared_imports'; import { schema } from '../../../../../../../rule_creation_ui/components/step_define_rule/schema'; -import { RuleFieldEditFormWrapper } from '../rule_field_edit_form_wrapper'; import type { FieldValueQueryBar } from '../../../../../../../rule_creation_ui/components/query_bar_field'; +import { RuleFieldEditFormWrapper } from '../../../field_final_side'; import { KqlQueryLanguage, KqlQueryType, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/threshold_alert_suppression/suppression_edit_form.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/threshold_alert_suppression/suppression_edit_form.tsx index af9f9db00cff2..0d4be2e421a5c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/threshold_alert_suppression/suppression_edit_form.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/threshold_alert_suppression/suppression_edit_form.tsx @@ -13,12 +13,12 @@ import { import { ALERT_SUPPRESSION_DURATION_FIELD_NAME } from '../../../../../../../rule_creation/components/alert_suppression_edit'; import { type FormData } from '../../../../../../../../shared_imports'; import type { ThresholdAlertSuppression } from '../../../../../../../../../common/api/detection_engine'; -import { RuleFieldEditFormWrapper } from '../rule_field_edit_form_wrapper'; +import { RuleFieldEditFormWrapper } from '../../../field_final_side'; import { thresholdAlertSuppressionFormSchema, type ThresholdAlertSuppressionFormData, } from './form_schema'; -import type { RuleFieldEditComponentProps } from '../rule_field_edit_component_props'; +import type { RuleFieldEditComponentProps } from '../../../field_final_side'; export function ThresholdAlertSuppressionEditForm(): JSX.Element { return ( diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/index.ts new file mode 100644 index 0000000000000..cc252595beee6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './field_final_edit'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx index bc3d2de8dc9f2..87abf720faeda 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx @@ -5,26 +5,106 @@ * 2.0. */ -import React from 'react'; -import { EuiButtonEmpty, EuiFlexGroup } from '@elastic/eui'; +import React, { useMemo } from 'react'; +import { DiffableCommonFields } from '../../../../../../../common/api/detection_engine'; +import type { + DiffableCustomQueryFields, + DiffableSavedQueryFields, + DiffableEqlFields, + DiffableThreatMatchFields, + DiffableThresholdFields, + DiffableNewTermsFields, + DiffableEsqlFields, + DiffableMachineLearningFields, +} from '../../../../../../../common/api/detection_engine'; +import { assertUnreachable } from '../../../../../../../common/utility_types'; +import { useDiffableRuleContext } from '../diffable_rule_context'; import { useFieldFinalSideContext } from '../field_final_side'; -import * as i18n from '../translations'; -import { FieldReadOnly } from './field_readonly'; +import { CustomQueryRuleFieldReadOnly } from './custom_query_rule_field_readonly'; +import { SavedQueryRuleFieldReadOnly } from './saved_query_rule_field_readonly'; +import { EqlRuleFieldReadOnly } from './eql_rule_field_readonly'; +import { EsqlRuleFieldReadOnly } from './esql_rule_field_readonly'; +import { ThreatMatchRuleFieldReadOnly } from './threat_match_rule_field_readonly'; +import { ThresholdRuleFieldReadOnly } from './threshold_rule_field_readonly'; +import { MachineLearningRuleFieldReadOnly } from './machine_learning_rule_field_readonly'; +import { NewTermsRuleFieldReadOnly } from './new_terms_rule_field_readonly'; +import { CommonRuleFieldReadOnly } from './common_rule_field_readonly'; export function FieldFinalReadOnly(): JSX.Element { + const { finalDiffableRule } = useDiffableRuleContext(); const { state: { fieldName }, - actions: { setEditMode }, } = useFieldFinalSideContext(); - return ( - <> - - - {i18n.EDIT_BUTTON_LABEL} - - - - + const { data: commonField } = useMemo( + () => DiffableCommonFields.keyof().safeParse(fieldName), + [fieldName] ); + + if (commonField) { + return ( + + ); + } + + switch (finalDiffableRule.type) { + case 'query': + return ( + + ); + case 'saved_query': + return ( + + ); + case 'eql': + return ( + + ); + case 'esql': + return ( + + ); + case 'threat_match': + return ( + + ); + case 'threshold': + return ( + + ); + case 'machine_learning': + return ( + + ); + case 'new_terms': + return ( + + ); + default: + return assertUnreachable(finalDiffableRule); + } } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_readonly.tsx deleted file mode 100644 index ecaec5af0f54a..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_readonly.tsx +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useMemo } from 'react'; -import { DiffableCommonFields } from '../../../../../../../common/api/detection_engine'; -import type { - DiffableCustomQueryFields, - DiffableSavedQueryFields, - DiffableEqlFields, - DiffableThreatMatchFields, - DiffableThresholdFields, - DiffableNewTermsFields, - DiffableEsqlFields, - DiffableMachineLearningFields, -} from '../../../../../../../common/api/detection_engine'; -import { assertUnreachable } from '../../../../../../../common/utility_types'; -import { CustomQueryRuleFieldReadOnly } from './custom_query_rule_field_readonly'; -import { SavedQueryRuleFieldReadOnly } from './saved_query_rule_field_readonly'; -import { EqlRuleFieldReadOnly } from './eql_rule_field_readonly'; -import { EsqlRuleFieldReadOnly } from './esql_rule_field_readonly'; -import { ThreatMatchRuleFieldReadOnly } from './threat_match_rule_field_readonly'; -import { ThresholdRuleFieldReadOnly } from './threshold_rule_field_readonly'; -import { MachineLearningRuleFieldReadOnly } from './machine_learning_rule_field_readonly'; -import { NewTermsRuleFieldReadOnly } from './new_terms_rule_field_readonly'; -import { CommonRuleFieldReadOnly } from './common_rule_field_readonly'; -import { useDiffableRuleContext } from '../diffable_rule_context'; - -interface FieldReadOnlyProps { - fieldName: string; -} - -export function FieldReadOnly({ fieldName }: FieldReadOnlyProps) { - const { finalDiffableRule } = useDiffableRuleContext(); - - const { data: commonField } = useMemo( - () => DiffableCommonFields.keyof().safeParse(fieldName), - [fieldName] - ); - - if (commonField) { - return ( - - ); - } - - switch (finalDiffableRule.type) { - case 'query': - return ( - - ); - case 'saved_query': - return ( - - ); - case 'eql': - return ( - - ); - case 'esql': - return ( - - ); - case 'threat_match': - return ( - - ); - case 'threshold': - return ( - - ); - case 'machine_learning': - return ( - - ); - case 'new_terms': - return ( - - ); - default: - return assertUnreachable(finalDiffableRule); - } -} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/alert_suppression/alert_suppression.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/alert_suppression/alert_suppression.stories.tsx index 9aeeee25983d3..9cebd044dad63 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/alert_suppression/alert_suppression.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/alert_suppression/alert_suppression.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { AlertSuppressionReadOnly } from './alert_suppression'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -25,8 +25,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/anomaly_threshold/anomaly_threshold.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/anomaly_threshold/anomaly_threshold.stories.tsx index 392187941046c..0f7ce369a117d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/anomaly_threshold/anomaly_threshold.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/anomaly_threshold/anomaly_threshold.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { AnomalyThresholdReadOnly } from './anomaly_threshold'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockMachineLearningRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -25,8 +25,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/building_block/building_block.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/building_block/building_block.stories.tsx index 6bace209f283b..7112e63a313d8 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/building_block/building_block.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/building_block/building_block.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { BuildingBlockReadOnly } from './building_block'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -24,8 +24,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/data_source/data_source.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/data_source/data_source.stories.tsx index d7bf26bc7d9ba..93f71afefb902 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/data_source/data_source.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/data_source/data_source.stories.tsx @@ -7,7 +7,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; import { @@ -18,7 +18,7 @@ import { } from '../../storybook/mocks'; export default { - component: FieldReadOnly, + component: FieldFinalReadOnly, title: 'Rule Management/Prebuilt Rules/Upgrade Flyout/ThreeWayDiff/FieldReadOnly/data_source', }; @@ -32,8 +32,9 @@ const Template: Story = (args) => { - + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.stories.tsx index 079c327fb29ef..de7df1f7fbfbf 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { DescriptionReadOnly } from './description'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -24,8 +24,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/eql_query/eql_query.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/eql_query/eql_query.stories.tsx index 8ee0ac1511784..bad23cba21e2e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/eql_query/eql_query.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/eql_query/eql_query.stories.tsx @@ -7,7 +7,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; import { EqlQueryReadOnly } from './eql_query'; @@ -34,8 +34,9 @@ const Template: Story = (args) => { - + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/esql_query/esql_query.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/esql_query/esql_query.stories.tsx index 70f37106842e1..81b692bfc4e9b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/esql_query/esql_query.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/esql_query/esql_query.stories.tsx @@ -7,13 +7,13 @@ import React from 'react'; import type { Story } from '@storybook/react'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockEsqlRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { - component: FieldReadOnly, + component: FieldFinalReadOnly, title: 'Rule Management/Prebuilt Rules/Upgrade Flyout/ThreeWayDiff/FieldReadOnly/esql_query', }; @@ -23,8 +23,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/false_positives/false_positives.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/false_positives/false_positives.stories.tsx index a5884b340e32b..a3f2defba2ec9 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/false_positives/false_positives.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/false_positives/false_positives.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { FalsePositivesReadOnly } from './false_positives'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -24,8 +24,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/history_window_start/history_window_start.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/history_window_start/history_window_start.stories.tsx index 12e0f086ecec9..da87cf2c04eb0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/history_window_start/history_window_start.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/history_window_start/history_window_start.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { HistoryWindowStartReadOnly } from './history_window_start'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockNewTermsRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -25,8 +25,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/investigation_fields/investigation_fields.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/investigation_fields/investigation_fields.stories.tsx index a32c79076a03d..400e7fd5ccba9 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/investigation_fields/investigation_fields.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/investigation_fields/investigation_fields.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { InvestigationFieldsReadOnly } from './investigation_fields'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -25,8 +25,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/kql_query.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/kql_query.stories.tsx index 16731ec498162..500999fea6c4f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/kql_query.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/kql_query.stories.tsx @@ -7,7 +7,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; import { @@ -22,7 +22,7 @@ import { } from '../../storybook/mocks'; export default { - component: FieldReadOnly, + component: FieldFinalReadOnly, title: 'Rule Management/Prebuilt Rules/Upgrade Flyout/ThreeWayDiff/FieldReadOnly/kql_query', }; @@ -36,8 +36,9 @@ const Template: Story = (args) => { - + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/machine_learning_job_id/machine_learning_job_id.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/machine_learning_job_id/machine_learning_job_id.stories.tsx index ea23aa5984106..35d90a26fdfde 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/machine_learning_job_id/machine_learning_job_id.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/machine_learning_job_id/machine_learning_job_id.stories.tsx @@ -10,7 +10,7 @@ import { useQueryClient } from '@tanstack/react-query'; import type { Story } from '@storybook/react'; import { MachineLearningJobIdReadOnly } from './machine_learning_job_id'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; import { GET_MODULES_QUERY_KEY } from '../../../../../../../../common/components/ml_popover/hooks/use_fetch_modules_query'; import { GET_RECOGNIZER_QUERY_KEY } from '../../../../../../../../common/components/ml_popover/hooks/use_fetch_recognizer_query'; @@ -64,9 +64,12 @@ interface TemplateProps { const Template: Story = (args) => { return ( - + - + ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/max_signals/max_signals.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/max_signals/max_signals.stories.tsx index 3c7945366a174..6959a5c391649 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/max_signals/max_signals.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/max_signals/max_signals.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { MaxSignalsReadOnly } from './max_signals'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -24,8 +24,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.stories.tsx index d97f71b4df0ac..137b34f851a27 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { NameReadOnly } from './name'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -24,8 +24,8 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/new_terms_fields/new_terms_fields.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/new_terms_fields/new_terms_fields.stories.tsx index f3dc5a1e3da9b..0f870562f2a8b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/new_terms_fields/new_terms_fields.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/new_terms_fields/new_terms_fields.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { NewTermsFieldsReadOnly } from './new_terms_fields'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockNewTermsRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -25,8 +25,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/note/note.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/note/note.stories.tsx index 4a62c5e58dc28..9492b797689c7 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/note/note.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/note/note.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { NoteReadOnly } from './note'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -24,8 +24,8 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/references/references.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/references/references.stories.tsx index ea8ee856099dd..d4d0d3241a6bf 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/references/references.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/references/references.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { ReferencesReadOnly } from './references'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -24,8 +24,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/related_integrations/related_integrations.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/related_integrations/related_integrations.stories.tsx index b810eaa1fbb8f..65f4f50dbfb87 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/related_integrations/related_integrations.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/related_integrations/related_integrations.stories.tsx @@ -10,7 +10,7 @@ import { useQueryClient } from '@tanstack/react-query'; import type { Story } from '@storybook/react'; import { RelatedIntegrationsReadOnly } from './related_integrations'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; @@ -45,9 +45,12 @@ interface TemplateProps { const Template: Story = (args) => { return ( - + - + ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/required_fields/required_fields.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/required_fields/required_fields.stories.tsx index ee926fc7ed561..b3839c9535612 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/required_fields/required_fields.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/required_fields/required_fields.stories.tsx @@ -7,7 +7,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { RequiredFieldsReadOnly } from './required_fields'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -23,8 +23,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/risk_score/risk_score.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/risk_score/risk_score.stories.tsx index cb640e31090cc..c045000018d07 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/risk_score/risk_score.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/risk_score/risk_score.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { RiskScoreReadOnly } from './risk_score'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -24,8 +24,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/risk_score_mapping/risk_score_mapping.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/risk_score_mapping/risk_score_mapping.stories.tsx index 90dbe7f981f64..4c7bd4cbba9ef 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/risk_score_mapping/risk_score_mapping.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/risk_score_mapping/risk_score_mapping.stories.tsx @@ -7,7 +7,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { RiskScoreMappingReadOnly } from './risk_score_mapping'; import { mockCustomQueryRule } from '../../storybook/mocks'; @@ -25,8 +25,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/rule_name_override/rule_name_override.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/rule_name_override/rule_name_override.stories.tsx index d0d596f15af42..0552b9e4f6b4f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/rule_name_override/rule_name_override.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/rule_name_override/rule_name_override.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { RuleNameOverrideReadOnly } from './rule_name_override'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -25,8 +25,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/rule_schedule/rule_schedule.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/rule_schedule/rule_schedule.stories.tsx index 30f2170a30f31..cca1dcb9bc21f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/rule_schedule/rule_schedule.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/rule_schedule/rule_schedule.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { RuleScheduleReadOnly } from './rule_schedule'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -24,8 +24,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/setup/setup.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/setup/setup.stories.tsx index 34410c7c6f638..14ba62913053e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/setup/setup.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/setup/setup.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { SetupReadOnly } from './setup'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -24,8 +24,8 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/severity/severity.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/severity/severity.stories.tsx index b51547d1655e0..3d6836295aa94 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/severity/severity.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/severity/severity.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { SeverityReadOnly } from './severity'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -24,8 +24,8 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/severity_mapping/severity_mapping.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/severity_mapping/severity_mapping.stories.tsx index b4ecb70ce66cd..4d3825cc7e4dc 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/severity_mapping/severity_mapping.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/severity_mapping/severity_mapping.stories.tsx @@ -7,7 +7,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { SeverityMappingReadOnly } from './severity_mapping'; import { mockCustomQueryRule } from '../../storybook/mocks'; @@ -25,8 +25,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.stories.tsx index c8129dd989d24..f93f5ffd2dad0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { TagsReadOnly } from './tags'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -24,8 +24,8 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat/threat.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat/threat.stories.tsx index de8c15f29e0cc..671dc68e1054f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat/threat.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat/threat.stories.tsx @@ -7,7 +7,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreatReadOnly } from './threat'; import { mockCustomQueryRule } from '../../storybook/mocks'; @@ -24,8 +24,8 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_index/threat_index.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_index/threat_index.stories.tsx index aeb1b6491bba6..6ab55ca01e335 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_index/threat_index.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_index/threat_index.stories.tsx @@ -7,7 +7,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreatIndexReadOnly } from './threat_index'; import { mockThreatMatchRule } from '../../storybook/mocks'; @@ -24,8 +24,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_indicator_path/threat_indicator_path.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_indicator_path/threat_indicator_path.stories.tsx index bb91b29fffe11..15c547001a27d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_indicator_path/threat_indicator_path.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_indicator_path/threat_indicator_path.stories.tsx @@ -7,7 +7,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreatIndicatorPathReadOnly } from './threat_indicator_path'; import { mockThreatMatchRule } from '../../storybook/mocks'; @@ -25,8 +25,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_mapping/threat_mapping.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_mapping/threat_mapping.stories.tsx index 35c4bba4544a7..587be1b02cba0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_mapping/threat_mapping.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_mapping/threat_mapping.stories.tsx @@ -7,7 +7,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreatMappingReadOnly } from './threat_mapping'; import { mockThreatMatchRule } from '../../storybook/mocks'; @@ -24,8 +24,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_query/threat_query.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_query/threat_query.stories.tsx index 625226ab4f9f5..46e98bbaa798d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_query/threat_query.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_query/threat_query.stories.tsx @@ -7,7 +7,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreatQueryReadOnly } from './threat_query'; import { @@ -34,8 +34,9 @@ const Template: Story = (args) => { - + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threshold/threshold.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threshold/threshold.stories.tsx index 0541d5f9a9b47..5270a2af8a635 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threshold/threshold.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threshold/threshold.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { ThresholdReadOnly } from './threshold'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockThresholdRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -24,8 +24,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/timeline_template/timeline_template.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/timeline_template/timeline_template.stories.tsx index e4c3a2043ff24..582affc9d192e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/timeline_template/timeline_template.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/timeline_template/timeline_template.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { TimelineTemplateReadOnly } from './timeline_template'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -25,8 +25,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/timestamp_override/timestamp_override.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/timestamp_override/timestamp_override.stories.tsx index 5828ba156d9d2..3d4c5b00005ad 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/timestamp_override/timestamp_override.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/timestamp_override/timestamp_override.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { TimestampOverrideReadOnly } from './timestamp_override'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -25,8 +25,11 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/type/type.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/type/type.stories.tsx index ba252a8a80b88..c57bdf36ce3a0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/type/type.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/type/type.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { TypeReadOnly } from './type'; -import { FieldReadOnly } from '../../field_readonly'; +import { FieldFinalReadOnly } from '../../field_final_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -24,8 +24,8 @@ interface TemplateProps { const Template: Story = (args) => { return ( - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/index.ts new file mode 100644 index 0000000000000..4abd3b839ae2f --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './field_final_readonly'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/three_way_diff_storybook_providers.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/three_way_diff_storybook_providers.tsx index 722f5ac9f6ada..2831d680750f4 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/three_way_diff_storybook_providers.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/three_way_diff_storybook_providers.tsx @@ -13,11 +13,14 @@ import { Provider as ReduxStoreProvider } from 'react-redux'; import type { CoreStart } from '@kbn/core/public'; import type { UpsellingService } from '@kbn/security-solution-upselling/service'; import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; +import type { UpgradeableDiffableFields } from '../../../../../model/prebuilt_rule_upgrade/fields'; import { ReactQueryClientProvider } from '../../../../../../../common/containers/query_client/query_client_provider'; import { UpsellingProvider } from '../../../../../../../common/components/upselling_provider'; import { DiffableRuleContextProvider } from '../../diffable_rule_context'; import type { DiffableRule } from '../../../../../../../../common/api/detection_engine'; +import { FieldFinalSideContextProvider } from '../../field_final_side/context/field_final_side_context'; import { mockCustomQueryRule } from './mocks'; +import { FieldFinalSideMode } from '../../field_final_side'; function createKibanaServicesMock(overrides?: Partial) { const baseMock = { @@ -78,12 +81,14 @@ interface StorybookProvidersProps { children: React.ReactNode; kibanaServicesOverrides?: Record; finalDiffableRule?: DiffableRule; + fieldName: string; } export function ThreeWayDiffStorybookProviders({ children, kibanaServicesOverrides, finalDiffableRule = mockCustomQueryRule(), + fieldName, }: StorybookProvidersProps) { const kibanaServicesMock = createKibanaServicesMock(kibanaServicesOverrides); const KibanaReactContext = createKibanaReactContext(kibanaServicesMock); @@ -99,7 +104,12 @@ export function ThreeWayDiffStorybookProviders({ finalDiffableRule={finalDiffableRule} setRuleFieldResolvedValue={setRuleFieldResolvedValueMock} > - {children} + + {children} + diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.ts deleted file mode 100644 index b03f8442b0c75..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const CANCEL_BUTTON_LABEL = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.cancelButtonLabel', - { - defaultMessage: 'Cancel', - } -); - -export const EDIT_BUTTON_LABEL = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.editButtonLabel', - { - defaultMessage: 'Edit', - } -); From 92a5615f9e9926894305dbc21c84336854f16bf1 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Sun, 24 Nov 2024 23:25:27 +0100 Subject: [PATCH 07/77] add no_conflict state --- .../field_upgrade_state_info.tsx | 32 +++++++++++---- .../field_upgrade_state_info/translations.tsx | 41 +++++++++++++++---- .../field_upgrade_state.ts | 1 + .../use_prebuilt_rules_upgrade_state.ts | 2 +- 4 files changed, 59 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/field_upgrade_state_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/field_upgrade_state_info.tsx index c49fc18e2c6ba..596a6d860eb9e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/field_upgrade_state_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/field_upgrade_state_info.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { EuiIcon, EuiText } from '@elastic/eui'; +import { EuiBadge, EuiText } from '@elastic/eui'; import { FieldUpgradeState } from '../../../../../model/prebuilt_rule_upgrade'; import * as i18n from './translations'; @@ -16,14 +16,26 @@ interface FieldUpgradeStateInfoProps { export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JSX.Element { switch (state) { - case FieldUpgradeState.Accepted: + case FieldUpgradeState.NoConflict: return ( <> - -  {i18n.UPDATE_ACCEPTED} + {i18n.READY_FOR_UPDATE} +    + {i18n.NO_CONFLICT} {i18n.SEPARATOR} - {i18n.UPDATE_ACCEPTED_DESCRIPTION} + {i18n.NO_CONFLICT_DESCRIPTION} + + + ); + + case FieldUpgradeState.Accepted: + return ( + <> + + {i18n.READY_FOR_UPDATE} +    + {i18n.REVIEWED_AND_ACCEPTED} ); @@ -32,8 +44,9 @@ export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JS return ( <> - -  {i18n.SOLVABLE_CONFLICT} + {i18n.REVIEW_REQUIRED} +    + {i18n.SOLVABLE_CONFLICT} {i18n.SEPARATOR} {i18n.SOLVABLE_CONFLICT_DESCRIPTION} @@ -44,8 +57,9 @@ export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JS return ( <> - -  {i18n.NON_SOLVABLE_CONFLICT} + {i18n.ACTION_REQUIRED} +    + {i18n.NON_SOLVABLE_CONFLICT} {i18n.SEPARATOR} {i18n.NON_SOLVABLE_CONFLICT_DESCRIPTION} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/translations.tsx index 0857013e2c715..2056f89e7332d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/translations.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/translations.tsx @@ -7,18 +7,45 @@ import { i18n } from '@kbn/i18n'; -export const UPDATE_ACCEPTED = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.updateAccepted', +export const READY_FOR_UPDATE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.badge.readyForUpdate', { - defaultMessage: 'Update accepted', + defaultMessage: 'Ready for update', } ); -export const UPDATE_ACCEPTED_DESCRIPTION = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.updateAcceptedDescription', +export const REVIEW_REQUIRED = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.badge.reviewRequired', { - defaultMessage: - 'You can still make changes, please review/accept all other conflicts before updating the rule.', + defaultMessage: 'Review required', + } +); + +export const ACTION_REQUIRED = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.badge.actionRequired', + { + defaultMessage: 'Action required', + } +); + +export const NO_CONFLICT = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.noConflict', + { + defaultMessage: 'No conflicts', + } +); + +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.', + } +); + +export const REVIEWED_AND_ACCEPTED = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.reviewedAndAccepted', + { + defaultMessage: 'Reviewed and accepted', } ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state.ts index ae2d8799c0bd4..dc92bbb8a6600 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state.ts @@ -7,6 +7,7 @@ export enum FieldUpgradeState { Accepted = 'ACCEPTED', + NoConflict = 'NO_CONFLICT', SolvableConflict = 'SOLVABLE_CONFLICT', NonSolvableConflict = 'NON_SOLVABLE_CONFLICT', } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts index b50ca7da1849d..dfed81605bb27 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts @@ -117,7 +117,7 @@ function calcFieldsState( for (const fieldName of Object.keys(ruleFieldsDiff)) { switch (ruleFieldsDiff[fieldName].conflict) { case ThreeWayDiffConflict.NONE: - fieldsState[fieldName] = FieldUpgradeState.Accepted; + fieldsState[fieldName] = FieldUpgradeState.NoConflict; break; case ThreeWayDiffConflict.SOLVABLE: From e63bc6560fd9499fad603a910b4d58ddb0ad4436 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 25 Nov 2024 09:51:21 +0100 Subject: [PATCH 08/77] add FieldEditFormContext explanation --- .../context/field_edit_form_context.tsx | 37 +++++++++++++------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/context/field_edit_form_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/context/field_edit_form_context.tsx index ff67656d3e6ac..ba722107e8b9e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/context/field_edit_form_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/context/field_edit_form_context.tsx @@ -11,6 +11,7 @@ import React, { type PropsWithChildren, useState, useCallback, + useRef, } from 'react'; import type { FormHook } from '../../../../../../../shared_imports'; import { invariant } from '../../../../../../../../common/utils/invariant'; @@ -24,27 +25,39 @@ interface FieldEditFormContextType { const FieldEditFormContext = createContext(null); +/** + * FieldEditFormContext helps to encapsulate form related logic in `field_final_side` folder. + * + * The only purpose is to obtain the recent form handler and provide it for consumers in + * in the `field_final_side` folder. + */ export function FieldEditFormContextProvider({ children }: PropsWithChildren<{}>) { - const [form, setForm] = useState(); + // Using reference reduces unnecessary re-renders though we need to re-render children + // whenever something in the form changes like validity state to be able to reflect that changes. + const formRef = useRef(); + // Setting the state re-renders the component and its children. The state value is ignored since + // we use a ref here. In that case it doesn't re-render components upon form cleanup. In that case + // the edit component disappears and we aren't interested in the form's state anymore. + const [, setForm] = useState(); const registerForm = useCallback( (formToRegister: FormHook) => { - setForm((prevForm) => { - if (prevForm) { - throw new Error( - 'Unexpected new form registration while the old one was not cleaned. Do you properly cleanup form by returning registerForm result from useEffect.' - ); - } + // Guard against subtle bugs. In attempt of using two forms throw an exception. + if (formRef.current) { + throw new Error( + 'Unexpected new form registration while the old one was not cleaned. Do you properly cleanup form by returning registerForm result from useEffect.' + ); + } - return formToRegister; - }); + formRef.current = formToRegister; + setForm(formToRegister); - return () => setForm(undefined); + return () => (formRef.current = undefined); }, - [setForm] + [formRef, setForm] ); return ( - + {children} ); From e4b9150f968ff2e2f006f5b0ba9020abd64ef0b3 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 25 Nov 2024 10:42:53 +0100 Subject: [PATCH 09/77] change rule upgrade callout according to the design --- .../components/badges/action_required.tsx | 14 ++++++++ .../badges/ready_for_upgrade_badge.tsx | 14 ++++++++ .../badges/review_required_badge.tsx | 14 ++++++++ .../components/badges/translations.ts | 29 ++++++++++++++++ .../field_upgrade_state_info.tsx | 13 ++++--- .../field_upgrade_state_info/translations.tsx | 21 ------------ .../rule_upgrade_callout.tsx | 34 +++++++++++++++---- .../rule_upgrade_callout/translations.tsx | 22 ++++++------ 8 files changed, 118 insertions(+), 43 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/action_required.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/ready_for_upgrade_badge.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/review_required_badge.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/translations.ts diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/action_required.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/action_required.tsx new file mode 100644 index 0000000000000..d21136531fd07 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/action_required.tsx @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiBadge } from '@elastic/eui'; +import * as i18n from './translations'; + +export function ActionRequiredBadge(): JSX.Element { + return {i18n.ACTION_REQUIRED}; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/ready_for_upgrade_badge.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/ready_for_upgrade_badge.tsx new file mode 100644 index 0000000000000..b6c5138cf0efe --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/ready_for_upgrade_badge.tsx @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiBadge } from '@elastic/eui'; +import * as i18n from './translations'; + +export function ReadyForUpgradeBadge(): JSX.Element { + return {i18n.READY_FOR_UPDATE}; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/review_required_badge.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/review_required_badge.tsx new file mode 100644 index 0000000000000..db02ce9a3615e --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/review_required_badge.tsx @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiBadge } from '@elastic/eui'; +import * as i18n from './translations'; + +export function ReviewRequiredBadge(): JSX.Element { + return {i18n.REVIEW_REQUIRED}; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/translations.ts new file mode 100644 index 0000000000000..d2445442bccd0 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/translations.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const READY_FOR_UPDATE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.badge.readyForUpdate', + { + defaultMessage: 'Ready for update', + } +); + +export const REVIEW_REQUIRED = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.badge.reviewRequired', + { + defaultMessage: 'Review required', + } +); + +export const ACTION_REQUIRED = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.badge.actionRequired', + { + defaultMessage: 'Action required', + } +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/field_upgrade_state_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/field_upgrade_state_info.tsx index 596a6d860eb9e..0ee573d05985c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/field_upgrade_state_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/field_upgrade_state_info.tsx @@ -6,8 +6,11 @@ */ import React from 'react'; -import { EuiBadge, EuiText } from '@elastic/eui'; +import { EuiText } from '@elastic/eui'; import { FieldUpgradeState } from '../../../../../model/prebuilt_rule_upgrade'; +import { ReadyForUpgradeBadge } from '../badges/ready_for_upgrade_badge'; +import { ReviewRequiredBadge } from '../badges/review_required_badge'; +import { ActionRequiredBadge } from '../badges/action_required'; import * as i18n from './translations'; interface FieldUpgradeStateInfoProps { @@ -20,7 +23,7 @@ export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JS return ( <> - {i18n.READY_FOR_UPDATE} +    {i18n.NO_CONFLICT} {i18n.SEPARATOR} @@ -33,7 +36,7 @@ export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JS return ( <> - {i18n.READY_FOR_UPDATE} +    {i18n.REVIEWED_AND_ACCEPTED} @@ -44,7 +47,7 @@ export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JS return ( <> - {i18n.REVIEW_REQUIRED} +    {i18n.SOLVABLE_CONFLICT} {i18n.SEPARATOR} @@ -57,7 +60,7 @@ export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JS return ( <> - {i18n.ACTION_REQUIRED} +    {i18n.NON_SOLVABLE_CONFLICT} {i18n.SEPARATOR} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/translations.tsx index 2056f89e7332d..fbd96c9fbd01f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/translations.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/translations.tsx @@ -7,27 +7,6 @@ import { i18n } from '@kbn/i18n'; -export const READY_FOR_UPDATE = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.badge.readyForUpdate', - { - defaultMessage: 'Ready for update', - } -); - -export const REVIEW_REQUIRED = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.badge.reviewRequired', - { - defaultMessage: 'Review required', - } -); - -export const ACTION_REQUIRED = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.badge.actionRequired', - { - defaultMessage: 'Action required', - } -); - export const NO_CONFLICT = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.noConflict', { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/rule_upgrade_callout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/rule_upgrade_callout.tsx index 8ab2674524952..a9c1582aa0909 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/rule_upgrade_callout.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/rule_upgrade_callout.tsx @@ -9,6 +9,9 @@ import React, { useMemo } from 'react'; import { EuiCallOut } from '@elastic/eui'; import type { RuleUpgradeState } from '../../../../../model/prebuilt_rule_upgrade'; import { FieldUpgradeState } from '../../../../../model/prebuilt_rule_upgrade'; +import { ActionRequiredBadge } from '../badges/action_required'; +import { ReviewRequiredBadge } from '../badges/review_required_badge'; +import { ReadyForUpgradeBadge } from '../badges/ready_for_upgrade_badge'; import * as i18n from './translations'; interface RuleUpgradeCalloutProps { @@ -40,8 +43,15 @@ export function RuleUpgradeCallout({ ruleUpgradeState }: RuleUpgradeCalloutProps if (numOfNonSolvableConflicts > 0) { return ( + {i18n.UPGRADE_STATUS} +   + +   + {i18n.RULE_HAS_NON_SOLVABLE_CONFLICTS(numOfNonSolvableConflicts)} + + } color="danger" size="s" > @@ -53,8 +63,15 @@ export function RuleUpgradeCallout({ ruleUpgradeState }: RuleUpgradeCalloutProps if (numOfSolvableConflicts > 0) { return ( + {i18n.UPGRADE_STATUS} +   + +   + {i18n.RULE_HAS_SOLVABLE_CONFLICTS(numOfSolvableConflicts)} + + } color="warning" size="s" > @@ -65,8 +82,13 @@ export function RuleUpgradeCallout({ ruleUpgradeState }: RuleUpgradeCalloutProps return ( + {i18n.UPGRADE_STATUS} +   + + + } color="success" size="s" > diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/translations.tsx index 319884746dbc2..16f5520d98055 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/translations.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/translations.tsx @@ -7,13 +7,20 @@ import { i18n } from '@kbn/i18n'; +export const UPGRADE_STATUS = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.upgradeStatusTitle', + { + defaultMessage: 'Update status:', + } +); + export const RULE_HAS_NON_SOLVABLE_CONFLICTS = (count: number) => i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasNonSolvableConflicts', { values: { count }, defaultMessage: - '{count} of the fields {count, plural, one {has} other {have}} an unsolved conflict. Please review and modify accordingly.', + '{count} {count, plural, one {field has a unsolved conflict} other {fields have unsolved conflicts}}. Please review and provide a final update.', } ); @@ -31,7 +38,7 @@ export const RULE_HAS_SOLVABLE_CONFLICTS = (count: number) => { values: { count }, defaultMessage: - '{count} of the fields {count, plural, one {has} other {have}} an update conflict, please review the suggested update being updating.', + '{count} {count, plural, one {field has a solved conflict} other {fields have solved conflicts}}. Please review the final update.', } ); @@ -39,20 +46,13 @@ export const RULE_HAS_SOLVABLE_CONFLICTS_DESCRIPTION = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflictsDescription', { defaultMessage: - 'Please review the suggested updated version before accepting the update. You can edit and then save the field if you wish to change it.', - } -); - -export const RULE_IS_READY_FOR_UPGRADE = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleIsReadyForUpgrade', - { - defaultMessage: 'The update is ready to be applied.', + 'Please review and accept solved conflicts. You can also keep the current without the updates, or accept the Elastic update but lose your modifications.', } ); export const RULE_IS_READY_FOR_UPGRADE_DESCRIPTION = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleIsReadyForUpgradeDescription', { - defaultMessage: 'All conflicts have now been reviewed and solved please update the rule.', + defaultMessage: 'There are no conflicts and the update is ready to be applied.', } ); From 7dc16f70a04ba8c215f77202eabc3fcdea09f038 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 25 Nov 2024 15:35:19 +0100 Subject: [PATCH 10/77] display modified badge for customized fields --- .../components/badges/modified_badge.tsx | 18 ++++ .../components/badges/translations.ts | 7 ++ .../field_upgrade_conflicts_resolver.tsx | 11 ++- ...ield_upgrade_conflicts_resolver_header.tsx | 16 +++- .../field_upgrade_state_info.tsx | 94 +++++++++---------- 5 files changed, 95 insertions(+), 51 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/modified_badge.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/modified_badge.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/modified_badge.tsx new file mode 100644 index 0000000000000..1c05e3f690a18 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/modified_badge.tsx @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiBadge } from '@elastic/eui'; +import * as i18n from './translations'; + +export function ModifiedBadge(): JSX.Element { + return ( + + {i18n.MODIFIED} + + ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/translations.ts index d2445442bccd0..f55b9ad2eef73 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/translations.ts @@ -27,3 +27,10 @@ export const ACTION_REQUIRED = i18n.translate( defaultMessage: 'Action required', } ); + +export const MODIFIED = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.badge.modified', + { + defaultMessage: 'Modified', + } +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx index 29951d7f593b1..1790ebf51f124 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx @@ -5,9 +5,10 @@ * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer, useEuiTheme } from '@elastic/eui'; import { css } from '@emotion/css'; +import { isEqual } from 'lodash'; import { SplitAccordion } from '../../../../../../common/components/split_accordion'; import type { DiffableAllFields, @@ -36,6 +37,13 @@ export function FieldUpgradeConflictsResolver + fieldThreeWayDiff.has_base_version + ? !isEqual(fieldThreeWayDiff.base_version, fieldThreeWayDiff.current_version) + : false, + [fieldThreeWayDiff] + ); return ( <> @@ -44,6 +52,7 @@ export function FieldUpgradeConflictsResolver } initialIsOpen={hasConflict} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver_header.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver_header.tsx index a096f025873a5..8b96f1456973c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver_header.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver_header.tsx @@ -10,16 +10,22 @@ import { camelCase, startCase } from 'lodash'; import { EuiFlexGroup, EuiTitle } from '@elastic/eui'; import { fieldToDisplayNameMap } from '../../diff_components/translations'; import type { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; +import { ModifiedBadge } from './badges/modified_badge'; import { FieldUpgradeStateInfo } from './field_upgrade_state_info'; interface FieldUpgradeConflictsResolverHeaderProps { fieldName: string; fieldUpgradeState: FieldUpgradeState; + /** + * Whether the field was customized by users (current and base versions differ) + */ + isCustomized: boolean; } export function FieldUpgradeConflictsResolverHeader({ fieldName, fieldUpgradeState, + isCustomized, }: FieldUpgradeConflictsResolverHeaderProps): JSX.Element { return ( @@ -27,7 +33,15 @@ export function FieldUpgradeConflictsResolverHeader({
{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/components/field_upgrade_state_info/field_upgrade_state_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/field_upgrade_state_info.tsx index 0ee573d05985c..68308b48d3531 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/field_upgrade_state_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/field_upgrade_state_info.tsx @@ -5,8 +5,9 @@ * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; import { EuiText } from '@elastic/eui'; +import { assertUnreachable } from '../../../../../../../../common/utility_types'; import { FieldUpgradeState } from '../../../../../model/prebuilt_rule_upgrade'; import { ReadyForUpgradeBadge } from '../badges/ready_for_upgrade_badge'; import { ReviewRequiredBadge } from '../badges/review_required_badge'; @@ -18,55 +19,50 @@ interface FieldUpgradeStateInfoProps { } export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JSX.Element { - switch (state) { - case FieldUpgradeState.NoConflict: - return ( - <> - - -    - {i18n.NO_CONFLICT} - {i18n.SEPARATOR} - {i18n.NO_CONFLICT_DESCRIPTION} - - - ); + const { color, badge, title, description } = useMemo(() => { + switch (state) { + case FieldUpgradeState.NoConflict: + return { + color: 'success', + badge: , + title: i18n.NO_CONFLICT, + description: i18n.NO_CONFLICT_DESCRIPTION, + }; - case FieldUpgradeState.Accepted: - return ( - <> - - -    - {i18n.REVIEWED_AND_ACCEPTED} - - - ); + case FieldUpgradeState.Accepted: + return { + color: 'success', + badge: , + title: i18n.REVIEWED_AND_ACCEPTED, + }; - case FieldUpgradeState.SolvableConflict: - return ( - <> - - -    - {i18n.SOLVABLE_CONFLICT} - {i18n.SEPARATOR} - {i18n.SOLVABLE_CONFLICT_DESCRIPTION} - - - ); + case FieldUpgradeState.SolvableConflict: + return { + color: 'warning', + badge: , + title: i18n.SOLVABLE_CONFLICT, + description: i18n.SOLVABLE_CONFLICT_DESCRIPTION, + }; - case FieldUpgradeState.NonSolvableConflict: - return ( - <> - - -    - {i18n.NON_SOLVABLE_CONFLICT} - {i18n.SEPARATOR} - {i18n.NON_SOLVABLE_CONFLICT_DESCRIPTION} - - - ); - } + case FieldUpgradeState.NonSolvableConflict: + return { + color: 'danger', + badge: , + title: i18n.NON_SOLVABLE_CONFLICT, + description: i18n.NON_SOLVABLE_CONFLICT_DESCRIPTION, + }; + + default: + return assertUnreachable(state); + } + }, [state]); + + return ( + <> + + {badge}  {title} + {description ? `${i18n.SEPARATOR} ${i18n.NO_CONFLICT_DESCRIPTION}` : null} + + + ); } From dbea30e8cb9040d0b9d705600022e12fd509aa93 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 25 Nov 2024 15:44:00 +0100 Subject: [PATCH 11/77] remove excess padding --- .../upgrade_prebuilt_rules_table_context.tsx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx index 6aad29f8b5792..ec3ae054b4519 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx @@ -21,12 +21,12 @@ import { invariant } from '../../../../../../common/utils/invariant'; import { useAppToasts } from '../../../../../common/hooks/use_app_toasts'; import { PerFieldRuleDiffTab } from '../../../../rule_management/components/rule_details/per_field_rule_diff_tab'; import { TabContentPadding } from '../../../../rule_management/components/rule_details/rule_details_flyout'; +import { usePerformUpgradeSpecificRules } from '../../../../rule_management/logic/prebuilt_rules/use_perform_rule_upgrade'; +import { usePrebuiltRulesUpgradeReview } from '../../../../rule_management/logic/prebuilt_rules/use_prebuilt_rules_upgrade_review'; import { RuleDiffTab } from '../../../../rule_management/components/rule_details/rule_diff_tab'; import { RuleUpgradeConflictsResolverTab } from '../../../../rule_management/components/rule_details/three_way_diff/rule_upgrade_conflicts_resolver_tab'; import * as ruleDetailsI18n from '../../../../rule_management/components/rule_details/translations'; import { useIsPrebuiltRulesCustomizationEnabled } from '../../../../rule_management/hooks/use_is_prebuilt_rules_customization_enabled'; -import { usePerformUpgradeSpecificRules } from '../../../../rule_management/logic/prebuilt_rules/use_perform_rule_upgrade'; -import { usePrebuiltRulesUpgradeReview } from '../../../../rule_management/logic/prebuilt_rules/use_prebuilt_rules_upgrade_review'; import { useIsUpgradingSecurityPackages } from '../../../../rule_management/logic/use_upgrade_security_packages'; import type { RuleUpgradeState, @@ -352,12 +352,10 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ ), content: ( - - - + ), }; From 7b86e682ce0dc2351f2201c5a60910cdda86d1fe Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 25 Nov 2024 20:17:11 +0100 Subject: [PATCH 12/77] add upgrade rule header details --- ...tch_prebuilt_rules_upgrade_review_query.ts | 38 ++++++++- .../rule_details/rule_details_flyout.tsx | 18 +++-- .../{translations.ts => translations.tsx} | 32 ++++++++ .../upgrade_flyout_subheader.tsx | 78 +++++++++++++++++++ .../upgrade_prebuilt_rules_table_context.tsx | 13 +++- .../rules_table/use_rule_preview_flyout.tsx | 7 ++ 6 files changed, 178 insertions(+), 8 deletions(-) rename x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/{translations.ts => translations.tsx} (77%) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_upgrade_review_query.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_upgrade_review_query.ts index 78e5cc26d6a8c..2b3cdff535aaf 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_upgrade_review_query.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_upgrade_review_query.ts @@ -9,7 +9,12 @@ import type { UseQueryOptions } from '@tanstack/react-query'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import { reviewRuleUpgrade } from '../../api'; import { REVIEW_RULE_UPGRADE_URL } from '../../../../../../common/api/detection_engine/prebuilt_rules/urls'; -import type { ReviewRuleUpgradeResponseBody } from '../../../../../../common/api/detection_engine/prebuilt_rules'; +import type { RuleUpgradeInfoForReview } from '../../../../../../common/api/detection_engine/prebuilt_rules'; +import { + NON_UPGRADEABLE_DIFFABLE_FIELDS, + ThreeWayDiffConflict, + type ReviewRuleUpgradeResponseBody, +} from '../../../../../../common/api/detection_engine/prebuilt_rules'; import { DEFAULT_QUERY_OPTIONS } from '../constants'; export const REVIEW_RULE_UPGRADE_QUERY_KEY = ['POST', REVIEW_RULE_UPGRADE_URL]; @@ -21,6 +26,9 @@ export const useFetchPrebuiltRulesUpgradeReviewQuery = ( REVIEW_RULE_UPGRADE_QUERY_KEY, async ({ signal }) => { const response = await reviewRuleUpgrade({ signal }); + + cleanupNonCustomizableFieldDiffs(response.rules); + return response; }, { @@ -46,3 +54,31 @@ export const useInvalidateFetchPrebuiltRulesUpgradeReviewQuery = () => { }); }, [queryClient]); }; + +/** + * Cleans up non customizable field diffs to avoid leaking in UI + * + * It modifies data in place due to performance considerations. + */ +function cleanupNonCustomizableFieldDiffs(rules: RuleUpgradeInfoForReview[]): void { + for (const rule of rules) { + for (const nonCustomizableFieldName of NON_UPGRADEABLE_DIFFABLE_FIELDS) { + const nonCustomizableFieldDiff = rule.diff.fields[nonCustomizableFieldName]; + + if (nonCustomizableFieldDiff?.conflict === ThreeWayDiffConflict.NONE) { + rule.diff.num_fields_with_updates--; + } + + if (nonCustomizableFieldDiff?.conflict === ThreeWayDiffConflict.SOLVABLE) { + rule.diff.num_fields_with_conflicts--; + } + + if (nonCustomizableFieldDiff?.conflict === ThreeWayDiffConflict.NON_SOLVABLE) { + rule.diff.num_fields_with_non_solvable_conflicts--; + rule.diff.num_fields_with_conflicts--; + } + + delete rule.diff.fields[nonCustomizableFieldName]; + } + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_details_flyout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_details_flyout.tsx index 7c7125a36dc5d..3425779926f7d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_details_flyout.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_details_flyout.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC, PropsWithChildren } from 'react'; +import type { FC, PropsWithChildren, ReactNode } from 'react'; import React, { useMemo, useState, useEffect } from 'react'; import styled from 'styled-components'; import { css } from '@emotion/css'; @@ -107,6 +107,7 @@ export const TabContentPadding: FC> = ({ children }) interface RuleDetailsFlyoutProps { rule: RuleResponse; + subHeader?: ReactNode; ruleActions?: React.ReactNode; size?: EuiFlyoutProps['size']; extraTabs?: EuiTabbedContentTab[]; @@ -115,15 +116,16 @@ interface RuleDetailsFlyoutProps { closeFlyout: () => void; } -export const RuleDetailsFlyout = ({ +export function RuleDetailsFlyout({ rule, ruleActions, + subHeader, size = 'm', extraTabs = [], dataTestSubj, id, closeFlyout, -}: RuleDetailsFlyoutProps) => { +}: RuleDetailsFlyoutProps): JSX.Element { const { expandedOverviewSections, toggleOverviewSection } = useOverviewTabSections(); const overviewTab: EuiTabbedContentTab = useMemo( @@ -202,7 +204,13 @@ export const RuleDetailsFlyout = ({

{rule.name}

- + + {subHeader && ( + <> + {subHeader} + + + )} ); -}; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/translations.tsx similarity index 77% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/translations.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/translations.tsx index 9a07c1bb6908a..743367a021a0b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/translations.tsx @@ -5,7 +5,10 @@ * 2.0. */ +import React from 'react'; import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import type { ReactNode } from 'react'; export const UPDATE_ALL = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeAll', @@ -93,3 +96,32 @@ export const RULE_TYPE_CHANGE_CALLOUT_DESCRIPTION = i18n.translate( 'Your customization will be lost at update. Please take note of your customization or clone this rule before updating.', } ); + +export const LAST_UPDATE = i18n.translate( + 'xpack.securitySolution.detectionEngine.upgradeFlyout.header.lastUpdate', + { + defaultMessage: 'Last update', + } +); + +export const UPDATED_BY_AND_WHEN = (updatedBy: ReactNode, updatedAt: ReactNode) => ( + +); + +export const SEVERITY = i18n.translate( + 'xpack.securitySolution.detectionEngine.upgradeFlyout.header.severity', + { + defaultMessage: 'Severity', + } +); + +export const FIELD_UPDATES = i18n.translate( + 'xpack.securitySolution.detectionEngine.upgradeFlyout.header.fieldUpdates', + { + defaultMessage: 'Field updates', + } +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx new file mode 100644 index 0000000000000..75c8852e275f3 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo } from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui'; +import { camelCase, startCase } from 'lodash'; +import { FormattedDate } from '../../../../../common/components/formatted_date'; +import { SeverityBadge } from '../../../../../common/components/severity_badge'; +import { ModifiedBadge } from '../../../../rule_management/components/rule_details/three_way_diff/components/badges/modified_badge'; +import type { RuleUpgradeState } from '../../../../rule_management/model/prebuilt_rule_upgrade'; +import { fieldToDisplayNameMap } from '../../../../rule_management/components/rule_details/diff_components/translations'; +import * as i18n from './translations'; + +interface UpgradeFlyoutSubHeaderProps { + ruleUpgradeState: RuleUpgradeState; +} + +export const UpgradeFlyoutSubHeader = memo(function UpgradeFlyoutSubHeader({ + ruleUpgradeState, +}: UpgradeFlyoutSubHeaderProps): JSX.Element { + const lastUpdate = ( + + + {i18n.LAST_UPDATE} + {':'} + {' '} + {i18n.UPDATED_BY_AND_WHEN( + ruleUpgradeState.target_rule.created_by, + + )} + + ); + + const severity = ( + + + + {i18n.SEVERITY} + {':'} + + + + + ); + + const customized = ruleUpgradeState.current_rule.rule_source.type === 'external' && + ruleUpgradeState.current_rule.rule_source.is_customized && ; + + const fieldUpdates = ( + + + {i18n.FIELD_UPDATES} + {':'}{' '} + {Object.keys(ruleUpgradeState.diff.fields) + .map((fieldName) => fieldToDisplayNameMap[fieldName] ?? startCase(camelCase(fieldName))) + .join(', ')} + + + ); + + return ( + <> + + {lastUpdate} + {severity} + + + + {customized && {customized}} + {fieldUpdates} + + + ); +}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx index ec3ae054b4519..4657730b36b09 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx @@ -25,7 +25,6 @@ import { usePerformUpgradeSpecificRules } from '../../../../rule_management/logi import { usePrebuiltRulesUpgradeReview } from '../../../../rule_management/logic/prebuilt_rules/use_prebuilt_rules_upgrade_review'; import { RuleDiffTab } from '../../../../rule_management/components/rule_details/rule_diff_tab'; import { RuleUpgradeConflictsResolverTab } from '../../../../rule_management/components/rule_details/three_way_diff/rule_upgrade_conflicts_resolver_tab'; -import * as ruleDetailsI18n from '../../../../rule_management/components/rule_details/translations'; import { useIsPrebuiltRulesCustomizationEnabled } from '../../../../rule_management/hooks/use_is_prebuilt_rules_customization_enabled'; import { useIsUpgradingSecurityPackages } from '../../../../rule_management/logic/use_upgrade_security_packages'; import type { @@ -37,12 +36,14 @@ import { isNonUpgradeableFieldName } from '../../../../rule_management/model/pre import { useRulePreviewFlyout } from '../use_rule_preview_flyout'; import { MlJobUpgradeModal } from './modals/ml_job_upgrade_modal'; import { UpgradeConflictsModal } from './modals/upgrade_conflicts_modal'; -import * as i18n from './translations'; import type { UpgradePrebuiltRulesTableFilterOptions } from './use_filter_prebuilt_rules_to_upgrade'; import { useFilterPrebuiltRulesToUpgrade } from './use_filter_prebuilt_rules_to_upgrade'; import { usePrebuiltRulesUpgradeState } from './use_prebuilt_rules_upgrade_state'; import { useMlJobUpgradeModal, useUpgradeConflictsModal } from './use_upgrade_modals'; import { RuleTypeChangeCallout } from './rule_type_change_callout'; +import { UpgradeFlyoutSubHeader } from './upgrade_flyout_subheader'; +import * as ruleDetailsI18n from '../../../../rule_management/components/rule_details/translations'; +import * as i18n from './translations'; export interface UpgradePrebuiltRulesTableState { /** @@ -263,6 +264,13 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ [isPrebuiltRulesCustomizationEnabled, upgradeRulesToResolved, upgradeRulesToTarget] ); + const subHeaderFactory = useCallback( + (rule: RuleResponse) => + rulesUpgradeState[rule.rule_id] ? ( + + ) : null, + [rulesUpgradeState] + ); const ruleActionsFactory = useCallback( (rule: RuleResponse, closeRulePreview: () => void) => { const ruleUpgradeState = rulesUpgradeState[rule.rule_id]; @@ -369,6 +377,7 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ ); const { rulePreviewFlyout, openRulePreview } = useRulePreviewFlyout({ rules: filteredRules, + subHeaderFactory, ruleActionsFactory, extraTabsFactory, flyoutProps: { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rule_preview_flyout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rule_preview_flyout.tsx index d6dcdd0592b85..1ab0105e19271 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rule_preview_flyout.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rule_preview_flyout.tsx @@ -17,6 +17,7 @@ interface UseRulePreviewFlyoutParams { rules: RuleResponse[]; ruleActionsFactory: (rule: RuleResponse, closeRulePreview: () => void) => ReactNode; extraTabsFactory?: (rule: RuleResponse) => EuiTabbedContentTab[]; + subHeaderFactory?: (rule: RuleResponse) => ReactNode; flyoutProps: RulePreviewFlyoutProps; } @@ -38,10 +39,15 @@ export function useRulePreviewFlyout({ rules, extraTabsFactory, ruleActionsFactory, + subHeaderFactory, flyoutProps, }: UseRulePreviewFlyoutParams): UseRulePreviewFlyoutResult { const [rule, setRuleForPreview] = useState(); const closeRulePreview = useCallback(() => setRuleForPreview(undefined), []); + const subHeader = useMemo( + () => (rule ? subHeaderFactory?.(rule) : null), + [subHeaderFactory, rule] + ); const ruleActions = useMemo( () => rule && ruleActionsFactory(rule, closeRulePreview), [rule, ruleActionsFactory, closeRulePreview] @@ -61,6 +67,7 @@ export function useRulePreviewFlyout({ closeFlyout={closeRulePreview} ruleActions={ruleActions} extraTabs={extraTabs} + subHeader={subHeader} /> ), openRulePreview: useCallback( From cfdb2c0fed40759c5f5cb9971f19d7ac61e1f289 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 25 Nov 2024 20:29:58 +0100 Subject: [PATCH 13/77] fix non scrollable tab content --- .../upgrade_prebuilt_rules_table_context.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx index 4657730b36b09..21206c20df864 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx @@ -360,10 +360,12 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ ), content: ( - +
+ +
), }; From f5289366df0441567f28080f17b47f3e44b9b3a5 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 26 Nov 2024 11:32:59 +0100 Subject: [PATCH 14/77] toss files and folders for better readability --- .../badges/action_required.tsx | 0 .../badges/modified_badge.tsx | 0 .../badges/ready_for_upgrade_badge.tsx | 0 .../badges/review_required_badge.tsx | 0 .../{components => }/badges/translations.ts | 0 .../comparison_side/field_comparison_side.tsx | 6 +- .../components/translations.tsx | 60 ------------------- .../components/field_final_side_header.tsx | 14 ++--- .../rule_field_edit_form_wrapper.tsx | 4 +- ...ader.tsx => field_upgrade_side_header.tsx} | 2 +- .../field_upgrade_state_info.tsx | 4 +- .../field_upgrade_state_info/index.ts | 0 .../field_upgrade_state_info/translations.tsx | 0 .../final_edit/field_final_edit.tsx | 16 ++--- .../final_readonly/field_final_readonly.tsx | 4 +- .../three_way_diff_storybook_providers.tsx | 6 +- ...ule_context.tsx => final_rule_context.tsx} | 23 +++---- .../field_upgrade.tsx} | 14 ++--- .../field_upgrade_header.tsx} | 10 ++-- .../index.ts | 2 +- .../rule_upgrade.tsx} | 36 +++++++---- .../rule_upgrade_callout.tsx | 4 +- .../rule_upgrade_info_bar.tsx | 0 .../translations.tsx | 52 ++++++++++++++++ .../rule_upgrade_conflicts_resolver_tab.tsx | 41 ------------- .../three_way_diff/rule_upgrade_tab.tsx | 33 ++++++++++ .../upgrade_flyout_subheader.tsx | 2 +- .../upgrade_prebuilt_rules_table_context.tsx | 20 +++---- .../translation_tab/rule_query.tsx | 9 +-- 29 files changed, 174 insertions(+), 188 deletions(-) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{components => }/badges/action_required.tsx (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{components => }/badges/modified_badge.tsx (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{components => }/badges/ready_for_upgrade_badge.tsx (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{components => }/badges/review_required_badge.tsx (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{components => }/badges/translations.ts (100%) delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/translations.tsx rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{components/side_header.tsx => field_upgrade_side_header.tsx} (90%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{components => }/field_upgrade_state_info/field_upgrade_state_info.tsx (92%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{components => }/field_upgrade_state_info/index.ts (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{components => }/field_upgrade_state_info/translations.tsx (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{diffable_rule_context.tsx => final_rule_context.tsx} (63%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{components/field_upgrade_conflicts_resolver.tsx => rule_upgrade/field_upgrade.tsx} (83%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{components/field_upgrade_conflicts_resolver_header.tsx => rule_upgrade/field_upgrade_header.tsx} (81%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{components/rule_upgrade_callout => rule_upgrade}/index.ts (86%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{components/rule_upgrade_conflicts_resolver.tsx => rule_upgrade/rule_upgrade.tsx} (58%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{components/rule_upgrade_callout => rule_upgrade}/rule_upgrade_callout.tsx (94%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{components => rule_upgrade}/rule_upgrade_info_bar.tsx (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{components/rule_upgrade_callout => rule_upgrade}/translations.tsx (58%) delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade_conflicts_resolver_tab.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade_tab.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/action_required.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/action_required.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/action_required.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/action_required.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/modified_badge.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/modified_badge.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/modified_badge.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/modified_badge.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/ready_for_upgrade_badge.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/ready_for_upgrade_badge.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/ready_for_upgrade_badge.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/ready_for_upgrade_badge.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/review_required_badge.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/review_required_badge.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/review_required_badge.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/review_required_badge.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/badges/translations.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/translations.ts diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx index 8aec819f7ba6c..86b9725c52d5a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx @@ -17,7 +17,7 @@ import type { } from '../../../../../../../common/api/detection_engine'; import { getSubfieldChanges } from './get_subfield_changes'; import { SubfieldChanges } from './subfield_changes'; -import { SideHeader } from '../components/side_header'; +import { FieldUpgradeSideHeader } from '../field_upgrade_side_header'; import { ComparisonSideHelpInfo } from './comparison_side_help_info'; import * as i18n from './translations'; @@ -46,7 +46,7 @@ export function FieldComparisonSide({ return ( <> - +

@@ -60,7 +60,7 @@ export function FieldComparisonSide({ onChange={setSelectedVersions} /> - + ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/translations.tsx deleted file mode 100644 index 27172cb98755c..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/translations.tsx +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { EuiLink } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { useKibana } from '../../../../../../common/lib/kibana/kibana_react'; - -export const NUM_OF_FIELDS_WITH_UPDATES = (count: number) => ( - {count} }} - /> -); - -export const NUM_OF_CONFLICTS = (count: number) => ( - {count} }} - /> -); - -const UPGRADE_RULES_DOCS_LINK = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.updateYourRulesDocsLink', - { - defaultMessage: 'update your rules', - } -); - -export function RuleUpgradeHelper(): JSX.Element { - const { - docLinks: { - links: { - securitySolution: { manageDetectionRules }, - }, - }, - } = useKibana().services; - const manageDetectionRulesSnoozeSection = `${manageDetectionRules}#edit-rules-settings`; - - return ( - - {UPGRADE_RULES_DOCS_LINK} - - ), - }} - /> - ); -} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx index 03ea8c1f630d4..f9a6362f30c35 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx @@ -10,13 +10,13 @@ import React, { useCallback } from 'react'; import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; import type { DiffableAllFields } from '../../../../../../../../common/api/detection_engine'; import { FieldUpgradeState } from '../../../../../model/prebuilt_rule_upgrade'; -import { SideHeader } from '../../components/side_header'; +import { FieldUpgradeSideHeader } from '../../field_upgrade_side_header'; import { useFieldFinalSideContext } from '../context/field_final_side_context'; import { FieldFinalSideMode } from '../field_final_side_mode'; import { assertUnreachable } from '../../../../../../../../common/utility_types'; import { useFieldEditFormContext } from '../context/field_edit_form_context'; +import { useFinalRuleContext } from '../../final_rule_context'; import { FieldFinalSideHelpInfo } from './field_final_side_help_info'; -import { useDiffableRuleContext } from '../../diffable_rule_context'; import * as i18n from './translations'; interface FieldFinalSideHeaderProps { @@ -30,7 +30,7 @@ export function FieldFinalSideHeader({ state: { fieldName, mode }, } = useFieldFinalSideContext(); const { form } = useFieldEditFormContext(); - const { finalDiffableRule, setRuleFieldResolvedValue } = useDiffableRuleContext(); + const { finalDiffableRule, setRuleFieldResolvedValue } = useFinalRuleContext(); const handleAccept = useCallback( () => setRuleFieldResolvedValue({ @@ -45,7 +45,7 @@ export function FieldFinalSideHeader({ switch (mode) { case FieldFinalSideMode.Readonly: return ( - + {fieldUpgradeState !== FieldUpgradeState.Accepted && ( @@ -53,11 +53,11 @@ export function FieldFinalSideHeader({ )} - + ); case FieldFinalSideMode.Edit: return ( - + - + ); default: return assertUnreachable(mode); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_form_wrapper.tsx index 85f5930096437..443b6243d2eb8 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_form_wrapper.tsx @@ -18,7 +18,7 @@ import type { DiffableRule, } from '../../../../../../../../common/api/detection_engine'; import { useFieldFinalSideContext } from '../context/field_final_side_context'; -import { useDiffableRuleContext } from '../../diffable_rule_context'; +import { useFinalRuleContext } from '../../final_rule_context'; import { useFieldEditFormContext } from '../context/field_edit_form_context'; import type { RuleFieldEditComponentProps } from './rule_field_edit_component_props'; import { useConfirmValidationErrorsModal } from '../../../../../../../common/hooks/use_confirm_validation_errors_modal'; @@ -61,7 +61,7 @@ export function RuleFieldEditFormWrapper({ state: { fieldName }, actions: { setReadOnlyMode }, } = useFieldFinalSideContext(); - const { finalDiffableRule, setRuleFieldResolvedValue } = useDiffableRuleContext(); + const { finalDiffableRule, setRuleFieldResolvedValue } = useFinalRuleContext(); const deserialize = useCallback( (defaultValue: FormData): FormData => diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/side_header.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_side_header.tsx similarity index 90% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/side_header.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_side_header.tsx index 574e3f526f856..3e0e60d3c4edf 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/side_header.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_side_header.tsx @@ -10,7 +10,7 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, useEuiTheme } from '@elastic/eui'; import { css } from '@emotion/css'; -export function SideHeader({ children }: PropsWithChildren<{}>) { +export function FieldUpgradeSideHeader({ children }: PropsWithChildren<{}>) { const { euiTheme } = useEuiTheme(); return ( diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/field_upgrade_state_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/field_upgrade_state_info.tsx similarity index 92% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/field_upgrade_state_info.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/field_upgrade_state_info.tsx index 68308b48d3531..3ce3427dff829 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/field_upgrade_state_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/field_upgrade_state_info.tsx @@ -7,8 +7,8 @@ import React, { useMemo } from 'react'; import { EuiText } from '@elastic/eui'; -import { assertUnreachable } from '../../../../../../../../common/utility_types'; -import { FieldUpgradeState } from '../../../../../model/prebuilt_rule_upgrade'; +import { assertUnreachable } from '../../../../../../../common/utility_types'; +import { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { ReadyForUpgradeBadge } from '../badges/ready_for_upgrade_badge'; import { ReviewRequiredBadge } from '../badges/review_required_badge'; import { ActionRequiredBadge } from '../badges/action_required'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/index.ts similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/index.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/index.ts diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/translations.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_state_info/translations.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/translations.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx index c6a57972c3b8b..be8950a1534c3 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx @@ -7,13 +7,6 @@ import React from 'react'; import { assertUnreachable } from '../../../../../../../common/utility_types'; -import { useDiffableRuleContext } from '../diffable_rule_context'; -import { CommonRuleFieldEdit } from './common_rule_field_edit'; -import { CustomQueryRuleFieldEdit } from './custom_query_rule_field_edit'; -import { SavedQueryRuleFieldEdit } from './saved_query_rule_field_edit'; -import { ThreatMatchRuleFieldEdit } from './threat_match_rule_field_edit'; -import { ThresholdRuleFieldEdit } from './threshold_rule_field_edit'; -import { NewTermsRuleFieldEdit } from './new_terms_rule_field_edit'; import type { UpgradeableCustomQueryFields, UpgradeableSavedQueryFields, @@ -26,12 +19,19 @@ import type { } from '../../../../model/prebuilt_rule_upgrade/fields'; import { isCommonFieldName } from '../../../../model/prebuilt_rule_upgrade/fields'; import { useFieldFinalSideContext } from '../field_final_side'; +import { useFinalRuleContext } from '../final_rule_context'; +import { CommonRuleFieldEdit } from './common_rule_field_edit'; +import { CustomQueryRuleFieldEdit } from './custom_query_rule_field_edit'; +import { SavedQueryRuleFieldEdit } from './saved_query_rule_field_edit'; +import { ThreatMatchRuleFieldEdit } from './threat_match_rule_field_edit'; +import { ThresholdRuleFieldEdit } from './threshold_rule_field_edit'; +import { NewTermsRuleFieldEdit } from './new_terms_rule_field_edit'; import { EqlRuleFieldEdit } from './eql_rule_field_edit'; import { EsqlRuleFieldEdit } from './esql_rule_field_edit'; import { MachineLearningRuleFieldEdit } from './machine_learning_rule_field_edit'; export function FieldFinalEdit(): JSX.Element { - const { finalDiffableRule } = useDiffableRuleContext(); + const { finalDiffableRule } = useFinalRuleContext(); const { type } = finalDiffableRule; const { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx index 87abf720faeda..404509f2bf64d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx @@ -18,7 +18,7 @@ import type { DiffableMachineLearningFields, } from '../../../../../../../common/api/detection_engine'; import { assertUnreachable } from '../../../../../../../common/utility_types'; -import { useDiffableRuleContext } from '../diffable_rule_context'; +import { useFinalRuleContext } from '../final_rule_context'; import { useFieldFinalSideContext } from '../field_final_side'; import { CustomQueryRuleFieldReadOnly } from './custom_query_rule_field_readonly'; import { SavedQueryRuleFieldReadOnly } from './saved_query_rule_field_readonly'; @@ -31,7 +31,7 @@ import { NewTermsRuleFieldReadOnly } from './new_terms_rule_field_readonly'; import { CommonRuleFieldReadOnly } from './common_rule_field_readonly'; export function FieldFinalReadOnly(): JSX.Element { - const { finalDiffableRule } = useDiffableRuleContext(); + const { finalDiffableRule } = useFinalRuleContext(); const { state: { fieldName }, } = useFieldFinalSideContext(); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/three_way_diff_storybook_providers.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/three_way_diff_storybook_providers.tsx index 2831d680750f4..89327dd0f6c07 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/three_way_diff_storybook_providers.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/three_way_diff_storybook_providers.tsx @@ -16,7 +16,7 @@ import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; import type { UpgradeableDiffableFields } from '../../../../../model/prebuilt_rule_upgrade/fields'; import { ReactQueryClientProvider } from '../../../../../../../common/containers/query_client/query_client_provider'; import { UpsellingProvider } from '../../../../../../../common/components/upselling_provider'; -import { DiffableRuleContextProvider } from '../../diffable_rule_context'; +import { FinalRuleContextProvider } from '../../final_rule_context'; import type { DiffableRule } from '../../../../../../../../common/api/detection_engine'; import { FieldFinalSideContextProvider } from '../../field_final_side/context/field_final_side_context'; import { mockCustomQueryRule } from './mocks'; @@ -100,7 +100,7 @@ export function ThreeWayDiffStorybookProviders({ - @@ -110,7 +110,7 @@ export function ThreeWayDiffStorybookProviders({ > {children} - + diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/diffable_rule_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_rule_context.tsx similarity index 63% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/diffable_rule_context.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_rule_context.tsx index 4210b394c7618..3486fa8c23464 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/diffable_rule_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_rule_context.tsx @@ -10,41 +10,36 @@ import type { DiffableRule } from '../../../../../../common/api/detection_engine import { invariant } from '../../../../../../common/utils/invariant'; import type { SetRuleFieldResolvedValueFn } from '../../../model/prebuilt_rule_upgrade/set_rule_field_resolved_value'; -interface DiffableRuleContextType { +interface FinalRuleContextType { finalDiffableRule: DiffableRule; setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } -const DiffableRuleContext = createContext(null); +const FinalRuleContext = createContext(null); -interface DiffableRuleContextProviderProps { +interface FinalRuleContextProviderProps { finalDiffableRule: DiffableRule; setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; children: React.ReactNode; } -export function DiffableRuleContextProvider({ +export function FinalRuleContextProvider({ finalDiffableRule, setRuleFieldResolvedValue, children, -}: DiffableRuleContextProviderProps) { +}: FinalRuleContextProviderProps) { const contextValue = { finalDiffableRule, setRuleFieldResolvedValue, }; - return ( - {children} - ); + return {children}; } -export function useDiffableRuleContext() { - const context = useContext(DiffableRuleContext); +export function useFinalRuleContext() { + const context = useContext(FinalRuleContext); - invariant( - context !== null, - 'useDiffableRuleContext must be used inside a DiffableRuleContextProvider' - ); + invariant(context !== null, 'useFinalRuleContext must be used inside a FinalRuleContextProvider'); return context; } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade.tsx similarity index 83% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade.tsx index 1790ebf51f124..c0d7974080414 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade.tsx @@ -19,24 +19,24 @@ import { ThreeWayDiffConflict } from '../../../../../../../common/api/detection_ import type { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { FieldComparisonSide } from '../comparison_side/field_comparison_side'; import { FieldFinalSide } from '../field_final_side'; -import { FieldUpgradeConflictsResolverHeader } from './field_upgrade_conflicts_resolver_header'; -import { useDiffableRuleContext } from '../diffable_rule_context'; +import { FieldUpgradeHeader } from './field_upgrade_header'; +import { useFinalRuleContext } from '../final_rule_context'; import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; -interface FieldUpgradeConflictsResolverProps { +interface FieldUpgradeProps { fieldName: FieldName; fieldUpgradeState: FieldUpgradeState; fieldThreeWayDiff: RuleFieldsDiff[FieldName]; } -export function FieldUpgradeConflictsResolver({ +export function FieldUpgrade({ fieldName, fieldUpgradeState, fieldThreeWayDiff, -}: FieldUpgradeConflictsResolverProps): JSX.Element { +}: FieldUpgradeProps): JSX.Element { const { euiTheme } = useEuiTheme(); const hasConflict = fieldThreeWayDiff.conflict !== ThreeWayDiffConflict.NONE; - const { finalDiffableRule } = useDiffableRuleContext(); + const { finalDiffableRule } = useFinalRuleContext(); const isFieldCustomized = useMemo( () => fieldThreeWayDiff.has_base_version @@ -49,7 +49,7 @@ export function FieldUpgradeConflictsResolver diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/index.ts similarity index 86% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/index.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/index.ts index 75ff48ff541a1..af2bd34a7b6e8 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/index.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/index.ts @@ -5,4 +5,4 @@ * 2.0. */ -export * from './rule_upgrade_callout'; +export * from './rule_upgrade'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_conflicts_resolver.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx similarity index 58% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_conflicts_resolver.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx index 3379cf2ab3e96..08c3b6491ff54 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_conflicts_resolver.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx @@ -6,10 +6,13 @@ */ import React from 'react'; +import { EuiSpacer } from '@elastic/eui'; import type { RuleUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; -import { FieldUpgradeConflictsResolver } from './field_upgrade_conflicts_resolver'; import type { NonUpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; import { isNonUpgradeableFieldName } from '../../../../model/prebuilt_rule_upgrade/fields'; +import { RuleUpgradeInfoBar } from './rule_upgrade_info_bar'; +import { RuleUpgradeCallout } from './rule_upgrade_callout'; +import { FieldUpgrade } from './field_upgrade'; type FieldDiffEntries = Array< [ @@ -18,13 +21,11 @@ type FieldDiffEntries; -interface RuleUpgradeConflictsResolverProps { +interface RuleUpgradeProps { ruleUpgradeState: RuleUpgradeState; } -export function RuleUpgradeConflictsResolver({ - ruleUpgradeState, -}: RuleUpgradeConflictsResolverProps): React.ReactNode { +export function RuleUpgrade({ ruleUpgradeState }: RuleUpgradeProps): React.ReactNode { const fieldDiffEntries = Object.entries(ruleUpgradeState.diff.fields) as FieldDiffEntries< typeof ruleUpgradeState.diff.fields >; @@ -33,12 +34,21 @@ export function RuleUpgradeConflictsResolver({ return isNonUpgradeableFieldName(fieldName) === false; }) as FieldDiffEntries; - return fields.map(([fieldName, fieldDiff]) => ( - - )); + return ( + <> + + + + + + {fields.map(([fieldName, fieldDiff]) => ( + + ))} + + ); } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/rule_upgrade_callout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx similarity index 94% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/rule_upgrade_callout.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx index a9c1582aa0909..32bd52e0e7cce 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/rule_upgrade_callout.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx @@ -7,8 +7,8 @@ import React, { useMemo } from 'react'; import { EuiCallOut } from '@elastic/eui'; -import type { RuleUpgradeState } from '../../../../../model/prebuilt_rule_upgrade'; -import { FieldUpgradeState } from '../../../../../model/prebuilt_rule_upgrade'; +import type { RuleUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; +import { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { ActionRequiredBadge } from '../badges/action_required'; import { ReviewRequiredBadge } from '../badges/review_required_badge'; import { ReadyForUpgradeBadge } from '../badges/ready_for_upgrade_badge'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_info_bar.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_info_bar.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/translations.tsx similarity index 58% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/translations.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/translations.tsx index 16f5520d98055..4b376eb908b0f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_callout/translations.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/translations.tsx @@ -5,7 +5,59 @@ * 2.0. */ +import React from 'react'; +import { EuiLink } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useKibana } from '../../../../../../common/lib/kibana/kibana_react'; + +export const NUM_OF_FIELDS_WITH_UPDATES = (count: number) => ( + {count} }} + /> +); + +export const NUM_OF_CONFLICTS = (count: number) => ( + {count} }} + /> +); + +const UPGRADE_RULES_DOCS_LINK = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.updateYourRulesDocsLink', + { + defaultMessage: 'update your rules', + } +); + +export function RuleUpgradeHelper(): JSX.Element { + const { + docLinks: { + links: { + securitySolution: { manageDetectionRules }, + }, + }, + } = useKibana().services; + const manageDetectionRulesSnoozeSection = `${manageDetectionRules}#edit-rules-settings`; + + return ( + + {UPGRADE_RULES_DOCS_LINK} + + ), + }} + /> + ); +} export const UPGRADE_STATUS = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.upgradeStatusTitle', diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade_conflicts_resolver_tab.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade_conflicts_resolver_tab.tsx deleted file mode 100644 index 95fa407fb7ca2..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade_conflicts_resolver_tab.tsx +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { EuiSpacer } from '@elastic/eui'; -import type { - RuleUpgradeState, - SetRuleFieldResolvedValueFn, -} from '../../../model/prebuilt_rule_upgrade'; -import { RuleUpgradeInfoBar } from './components/rule_upgrade_info_bar'; -import { RuleUpgradeConflictsResolver } from './components/rule_upgrade_conflicts_resolver'; -import { DiffableRuleContextProvider } from './diffable_rule_context'; -import { RuleUpgradeCallout } from './components/rule_upgrade_callout'; - -interface RuleUpgradeConflictsResolverTabProps { - ruleUpgradeState: RuleUpgradeState; - setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; -} - -export function RuleUpgradeConflictsResolverTab({ - ruleUpgradeState, - setRuleFieldResolvedValue, -}: RuleUpgradeConflictsResolverTabProps): JSX.Element { - return ( - - - - - - - - - ); -} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade_tab.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade_tab.tsx new file mode 100644 index 0000000000000..4bbd73e942b41 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade_tab.tsx @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { + RuleUpgradeState, + SetRuleFieldResolvedValueFn, +} from '../../../model/prebuilt_rule_upgrade'; +import { RuleUpgrade } from './rule_upgrade'; +import { FinalRuleContextProvider } from './final_rule_context'; + +interface RuleUpgradeTabProps { + ruleUpgradeState: RuleUpgradeState; + setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; +} + +export function RuleUpgradeTab({ + ruleUpgradeState, + setRuleFieldResolvedValue, +}: RuleUpgradeTabProps): JSX.Element { + return ( + + + + ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx index 75c8852e275f3..4a81ebdb6eabc 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx @@ -10,7 +10,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui'; import { camelCase, startCase } from 'lodash'; import { FormattedDate } from '../../../../../common/components/formatted_date'; import { SeverityBadge } from '../../../../../common/components/severity_badge'; -import { ModifiedBadge } from '../../../../rule_management/components/rule_details/three_way_diff/components/badges/modified_badge'; +import { ModifiedBadge } from '../../../../rule_management/components/rule_details/three_way_diff/badges/modified_badge'; import type { RuleUpgradeState } from '../../../../rule_management/model/prebuilt_rule_upgrade'; import { fieldToDisplayNameMap } from '../../../../rule_management/components/rule_details/diff_components/translations'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx index 21206c20df864..055e1faeb4456 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx @@ -13,24 +13,24 @@ import type { RuleUpgradeInfoForReview, RuleUpgradeSpecifier, } from '../../../../../../common/api/detection_engine'; +import { useIsPrebuiltRulesCustomizationEnabled } from '../../../../rule_management/hooks/use_is_prebuilt_rules_customization_enabled'; +import { useAppToasts } from '../../../../../common/hooks/use_app_toasts'; +import type { + RuleUpgradeState, + RulesUpgradeState, +} from '../../../../rule_management/model/prebuilt_rule_upgrade'; +import { RuleUpgradeTab } from '../../../../rule_management/components/rule_details/three_way_diff/rule_upgrade_tab'; +import { PerFieldRuleDiffTab } from '../../../../rule_management/components/rule_details/per_field_rule_diff_tab'; +import { useIsUpgradingSecurityPackages } from '../../../../rule_management/logic/use_upgrade_security_packages'; import type { RuleResponse, RuleSignatureId, } from '../../../../../../common/api/detection_engine/model/rule_schema'; import { invariant } from '../../../../../../common/utils/invariant'; -import { useAppToasts } from '../../../../../common/hooks/use_app_toasts'; -import { PerFieldRuleDiffTab } from '../../../../rule_management/components/rule_details/per_field_rule_diff_tab'; import { TabContentPadding } from '../../../../rule_management/components/rule_details/rule_details_flyout'; import { usePerformUpgradeSpecificRules } from '../../../../rule_management/logic/prebuilt_rules/use_perform_rule_upgrade'; import { usePrebuiltRulesUpgradeReview } from '../../../../rule_management/logic/prebuilt_rules/use_prebuilt_rules_upgrade_review'; import { RuleDiffTab } from '../../../../rule_management/components/rule_details/rule_diff_tab'; -import { RuleUpgradeConflictsResolverTab } from '../../../../rule_management/components/rule_details/three_way_diff/rule_upgrade_conflicts_resolver_tab'; -import { useIsPrebuiltRulesCustomizationEnabled } from '../../../../rule_management/hooks/use_is_prebuilt_rules_customization_enabled'; -import { useIsUpgradingSecurityPackages } from '../../../../rule_management/logic/use_upgrade_security_packages'; -import type { - RuleUpgradeState, - RulesUpgradeState, -} from '../../../../rule_management/model/prebuilt_rule_upgrade'; import { FieldUpgradeState } from '../../../../rule_management/model/prebuilt_rule_upgrade/field_upgrade_state'; import { isNonUpgradeableFieldName } from '../../../../rule_management/model/prebuilt_rule_upgrade/fields'; import { useRulePreviewFlyout } from '../use_rule_preview_flyout'; @@ -335,7 +335,7 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ // conflicts, only accept the target rule. if (isPrebuiltRulesCustomizationEnabled && !hasRuleTypeChange) { updateTabContent = ( - diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/rule_query.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/rule_query.tsx index 3cfd9f3b10f52..d05d0974f474d 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/rule_query.tsx +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/rule_query.tsx @@ -7,7 +7,6 @@ import React, { useMemo } from 'react'; import { EuiMarkdownEditor, EuiMarkdownFormat, EuiTitle } from '@elastic/eui'; -import { SideHeader } from '../../../../../detection_engine/rule_management/components/rule_details/three_way_diff/components/side_header'; import * as i18n from './translations'; interface RuleQueryProps { @@ -34,11 +33,9 @@ export const RuleQueryComponent = ({ title, query, canEdit }: RuleQueryProps) => }, [canEdit, query]); return ( <> - - -

{title}

-
-
+ +

{title}

+
{queryTextComponent} ); From 11d760001d13810e7e15a50c4307d467407b62a4 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 26 Nov 2024 13:14:19 +0100 Subject: [PATCH 15/77] simplify implementation by merging used react contexts --- ...tch_prebuilt_rules_upgrade_review_query.ts | 37 +----- .../field_comparison_side.stories.tsx | 10 +- .../comparison_side/field_comparison_side.tsx | 26 ++-- .../get_subfield_changes/index.ts | 8 +- .../three_way_diff/comparison_side/utils.ts | 13 +- .../components/field_final_side.tsx | 22 +--- .../components/field_final_side_content.tsx | 15 +-- .../components/field_final_side_header.tsx | 36 ++--- .../rule_field_edit_form_wrapper.tsx | 10 +- .../context/field_final_side_context.tsx | 85 ------------ .../three_way_diff/field_final_side/index.ts | 2 - .../final_edit/field_final_edit.tsx | 15 +-- .../final_readonly/field_final_readonly.tsx | 8 +- .../three_way_diff_storybook_providers.tsx | 40 ++++-- .../three_way_diff/final_rule_context.tsx | 45 ------- .../field_final_side_mode.ts => index.ts} | 5 +- .../rule_upgrade/field_upgrade.tsx | 39 ++---- .../rule_upgrade/field_upgrade_context.tsx | 124 ++++++++++++++++++ .../rule_upgrade/rule_upgrade.tsx | 92 +++++++++---- .../three_way_diff/rule_upgrade_tab.tsx | 33 ----- .../upgrade_prebuilt_rules_table_context.tsx | 2 +- 21 files changed, 288 insertions(+), 379 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/context/field_final_side_context.tsx delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_rule_context.tsx rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{field_final_side/field_final_side_mode.ts => index.ts} (76%) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_context.tsx delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade_tab.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_upgrade_review_query.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_upgrade_review_query.ts index 2b3cdff535aaf..92c16e9d0df03 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_upgrade_review_query.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_upgrade_review_query.ts @@ -9,12 +9,7 @@ import type { UseQueryOptions } from '@tanstack/react-query'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import { reviewRuleUpgrade } from '../../api'; import { REVIEW_RULE_UPGRADE_URL } from '../../../../../../common/api/detection_engine/prebuilt_rules/urls'; -import type { RuleUpgradeInfoForReview } from '../../../../../../common/api/detection_engine/prebuilt_rules'; -import { - NON_UPGRADEABLE_DIFFABLE_FIELDS, - ThreeWayDiffConflict, - type ReviewRuleUpgradeResponseBody, -} from '../../../../../../common/api/detection_engine/prebuilt_rules'; +import { type ReviewRuleUpgradeResponseBody } from '../../../../../../common/api/detection_engine/prebuilt_rules'; import { DEFAULT_QUERY_OPTIONS } from '../constants'; export const REVIEW_RULE_UPGRADE_QUERY_KEY = ['POST', REVIEW_RULE_UPGRADE_URL]; @@ -27,8 +22,6 @@ export const useFetchPrebuiltRulesUpgradeReviewQuery = ( async ({ signal }) => { const response = await reviewRuleUpgrade({ signal }); - cleanupNonCustomizableFieldDiffs(response.rules); - return response; }, { @@ -54,31 +47,3 @@ export const useInvalidateFetchPrebuiltRulesUpgradeReviewQuery = () => { }); }, [queryClient]); }; - -/** - * Cleans up non customizable field diffs to avoid leaking in UI - * - * It modifies data in place due to performance considerations. - */ -function cleanupNonCustomizableFieldDiffs(rules: RuleUpgradeInfoForReview[]): void { - for (const rule of rules) { - for (const nonCustomizableFieldName of NON_UPGRADEABLE_DIFFABLE_FIELDS) { - const nonCustomizableFieldDiff = rule.diff.fields[nonCustomizableFieldName]; - - if (nonCustomizableFieldDiff?.conflict === ThreeWayDiffConflict.NONE) { - rule.diff.num_fields_with_updates--; - } - - if (nonCustomizableFieldDiff?.conflict === ThreeWayDiffConflict.SOLVABLE) { - rule.diff.num_fields_with_conflicts--; - } - - if (nonCustomizableFieldDiff?.conflict === ThreeWayDiffConflict.NON_SOLVABLE) { - rule.diff.num_fields_with_non_solvable_conflicts--; - rule.diff.num_fields_with_conflicts--; - } - - delete rule.diff.fields[nonCustomizableFieldName]; - } - } -} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.stories.tsx index d9079a0669d20..004b7ff25670b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.stories.tsx @@ -44,14 +44,8 @@ interface TemplateProps { resolvedValue?: DiffableAllFields[FieldName]; } -const Template: Story> = (args) => { - return ( - - ); +const Template: Story> = () => { + return ; }; export const NoBaseVersion = Template.bind({}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx index 86b9725c52d5a..26e65d7593da2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx @@ -10,37 +10,27 @@ import { EuiFlexGroup, EuiTitle } from '@elastic/eui'; import { VersionsPicker } from '../versions_picker/versions_picker'; import type { Version } from '../versions_picker/constants'; import { SelectedVersions } from '../versions_picker/constants'; +import { FieldUpgradeSideHeader } from '../field_upgrade_side_header'; +import { useFieldUpgradeContext } from '../rule_upgrade/field_upgrade_context'; import { pickFieldValueForVersion } from './utils'; -import type { - DiffableAllFields, - ThreeWayDiff, -} from '../../../../../../../common/api/detection_engine'; import { getSubfieldChanges } from './get_subfield_changes'; import { SubfieldChanges } from './subfield_changes'; -import { FieldUpgradeSideHeader } from '../field_upgrade_side_header'; import { ComparisonSideHelpInfo } from './comparison_side_help_info'; import * as i18n from './translations'; -interface FieldComparisonSideProps { - fieldName: FieldName; - fieldThreeWayDiff: ThreeWayDiff; - resolvedValue: DiffableAllFields[FieldName]; -} +export function FieldComparisonSide(): JSX.Element { + const { fieldName, fieldDiff, finalDiffableRule } = useFieldUpgradeContext(); + const resolvedValue = finalDiffableRule[fieldName]; -export function FieldComparisonSide({ - fieldName, - fieldThreeWayDiff, - resolvedValue, -}: FieldComparisonSideProps) { const [selectedVersions, setSelectedVersions] = useState( SelectedVersions.CurrentFinal ); const [oldVersionType, newVersionType] = selectedVersions.split('_') as [Version, Version]; - const oldFieldValue = pickFieldValueForVersion(oldVersionType, fieldThreeWayDiff, resolvedValue); + const oldFieldValue = pickFieldValueForVersion(oldVersionType, fieldDiff, resolvedValue); - const newFieldValue = pickFieldValueForVersion(newVersionType, fieldThreeWayDiff, resolvedValue); + const newFieldValue = pickFieldValueForVersion(newVersionType, fieldDiff, resolvedValue); const subfieldChanges = getSubfieldChanges(fieldName, oldFieldValue, newFieldValue); @@ -55,7 +45,7 @@ export function FieldComparisonSide({

diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/get_subfield_changes/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/get_subfield_changes/index.ts index c3628d74176c3..0ac093b895a73 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/get_subfield_changes/index.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/get_subfield_changes/index.ts @@ -28,10 +28,10 @@ import type { SubfieldChanges } from '../types'; * @param newFieldValue - The new value of the field. * @returns - An array of subfield changes. */ -export const getSubfieldChanges = ( - fieldName: FieldName, - oldFieldValue?: DiffableAllFields[FieldName], - newFieldValue?: DiffableAllFields[FieldName] +export const getSubfieldChanges = ( + fieldName: keyof DiffableAllFields, + oldFieldValue: unknown, + newFieldValue: unknown ): SubfieldChanges => { switch (fieldName) { /* diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts index d0673c460a1d5..21397db2c02ba 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts @@ -7,10 +7,7 @@ import stringify from 'json-stable-stringify'; import { Version } from '../versions_picker/constants'; -import type { - DiffableAllFields, - ThreeWayDiff, -} from '../../../../../../../common/api/detection_engine'; +import type { ThreeWayDiff } from '../../../../../../../common/api/detection_engine'; /** * Picks the field value for a given version either from a three-way diff object or from a user-set resolved value. @@ -20,11 +17,11 @@ import type { * @param resolvedValue - A value field will be upgraded to. * @returns - The field value for the specified version */ -export function pickFieldValueForVersion( +export function pickFieldValueForVersion( version: Version, - fieldThreeWayDiff: ThreeWayDiff, - resolvedValue: DiffableAllFields[FieldName] -): DiffableAllFields[FieldName] | undefined { + fieldThreeWayDiff: ThreeWayDiff, + resolvedValue: unknown +): unknown { if (version === Version.Final) { return resolvedValue; } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side.tsx index 7d630e47f416f..8a6c312d74db0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side.tsx @@ -6,31 +6,15 @@ */ import React from 'react'; -import { FieldFinalSideMode } from '../field_final_side_mode'; -import { FieldUpgradeState } from '../../../../../model/prebuilt_rule_upgrade'; -import type { UpgradeableDiffableFields } from '../../../../../model/prebuilt_rule_upgrade/fields'; -import { FieldFinalSideContextProvider } from '../context/field_final_side_context'; import { FieldEditFormContextProvider } from '../context/field_edit_form_context'; import { FieldFinalSideContent } from './field_final_side_content'; import { FieldFinalSideHeader } from './field_final_side_header'; -interface FieldFinalSideProps { - fieldName: UpgradeableDiffableFields; - fieldUpgradeState: FieldUpgradeState; -} - -export function FieldFinalSide({ fieldName, fieldUpgradeState }: FieldFinalSideProps): JSX.Element { - const initialMode = - fieldUpgradeState === FieldUpgradeState.NonSolvableConflict - ? FieldFinalSideMode.Edit - : FieldFinalSideMode.Readonly; - +export function FieldFinalSide(): JSX.Element { return ( - - - - + + ); } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_content.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_content.tsx index 64f943a3372e6..69452c2d4aab2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_content.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_content.tsx @@ -9,18 +9,17 @@ import React from 'react'; import { EuiButtonEmpty, EuiFlexGroup } from '@elastic/eui'; import { FieldFinalReadOnly } from '../../final_readonly'; import { FieldFinalEdit } from '../../final_edit'; -import { FieldFinalSideMode } from '../field_final_side_mode'; import { assertUnreachable } from '../../../../../../../../common/utility_types'; -import { useFieldFinalSideContext } from '../context/field_final_side_context'; +import { + FieldFinalSideMode, + useFieldUpgradeContext, +} from '../../rule_upgrade/field_upgrade_context'; import * as i18n from './translations'; export function FieldFinalSideContent(): JSX.Element { - const { - state: { mode }, - actions: { setEditMode, setReadOnlyMode }, - } = useFieldFinalSideContext(); + const { rightSideMode, setEditMode, setReadOnlyMode } = useFieldUpgradeContext(); - switch (mode) { + switch (rightSideMode) { case FieldFinalSideMode.Readonly: return ( <> @@ -44,6 +43,6 @@ export function FieldFinalSideContent(): JSX.Element { ); default: - return assertUnreachable(mode); + return assertUnreachable(rightSideMode); } } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx index f9a6362f30c35..d157d129bb376 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx @@ -11,26 +11,28 @@ import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; import type { DiffableAllFields } from '../../../../../../../../common/api/detection_engine'; import { FieldUpgradeState } from '../../../../../model/prebuilt_rule_upgrade'; import { FieldUpgradeSideHeader } from '../../field_upgrade_side_header'; -import { useFieldFinalSideContext } from '../context/field_final_side_context'; -import { FieldFinalSideMode } from '../field_final_side_mode'; import { assertUnreachable } from '../../../../../../../../common/utility_types'; +import { + FieldFinalSideMode, + useFieldUpgradeContext, +} from '../../rule_upgrade/field_upgrade_context'; import { useFieldEditFormContext } from '../context/field_edit_form_context'; -import { useFinalRuleContext } from '../../final_rule_context'; import { FieldFinalSideHelpInfo } from './field_final_side_help_info'; import * as i18n from './translations'; -interface FieldFinalSideHeaderProps { - fieldUpgradeState: FieldUpgradeState; -} - -export function FieldFinalSideHeader({ - fieldUpgradeState, -}: FieldFinalSideHeaderProps): JSX.Element { +export function FieldFinalSideHeader(): JSX.Element { const { - state: { fieldName, mode }, - } = useFieldFinalSideContext(); + fieldName, + fieldUpgradeState, + rightSideMode, + finalDiffableRule, + setRuleFieldResolvedValue, + } = useFieldUpgradeContext(); const { form } = useFieldEditFormContext(); - const { finalDiffableRule, setRuleFieldResolvedValue } = useFinalRuleContext(); + const isFieldReadyForUpgrade = + fieldUpgradeState === FieldUpgradeState.NoConflict || + fieldUpgradeState === FieldUpgradeState.Accepted; + const handleAccept = useCallback( () => setRuleFieldResolvedValue({ @@ -42,12 +44,12 @@ export function FieldFinalSideHeader({ ); const handleSave = useCallback(() => form?.submit(), [form]); - switch (mode) { + switch (rightSideMode) { case FieldFinalSideMode.Readonly: return ( - {fieldUpgradeState !== FieldUpgradeState.Accepted && ( + {!isFieldReadyForUpgrade && ( {i18n.ACCEPT} @@ -65,13 +67,13 @@ export function FieldFinalSideHeader({ disabled={!form?.isValid} onClick={handleSave} > - {fieldUpgradeState !== FieldUpgradeState.Accepted ? i18n.SAVE_AND_ACCEPT : i18n.SAVE} + {!isFieldReadyForUpgrade ? i18n.SAVE_AND_ACCEPT : i18n.SAVE} ); default: - return assertUnreachable(mode); + return assertUnreachable(rightSideMode); } } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_form_wrapper.tsx index 443b6243d2eb8..51b9da783c419 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_form_wrapper.tsx @@ -17,8 +17,7 @@ import type { DiffableAllFields, DiffableRule, } from '../../../../../../../../common/api/detection_engine'; -import { useFieldFinalSideContext } from '../context/field_final_side_context'; -import { useFinalRuleContext } from '../../final_rule_context'; +import { useFieldUpgradeContext } from '../../rule_upgrade/field_upgrade_context'; import { useFieldEditFormContext } from '../context/field_edit_form_context'; import type { RuleFieldEditComponentProps } from './rule_field_edit_component_props'; import { useConfirmValidationErrorsModal } from '../../../../../../../common/hooks/use_confirm_validation_errors_modal'; @@ -57,11 +56,8 @@ export function RuleFieldEditFormWrapper({ serializer, }: RuleFieldEditFormWrapperProps) { const { registerForm } = useFieldEditFormContext(); - const { - state: { fieldName }, - actions: { setReadOnlyMode }, - } = useFieldFinalSideContext(); - const { finalDiffableRule, setRuleFieldResolvedValue } = useFinalRuleContext(); + const { fieldName, finalDiffableRule, setReadOnlyMode, setRuleFieldResolvedValue } = + useFieldUpgradeContext(); const deserialize = useCallback( (defaultValue: FormData): FormData => diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/context/field_final_side_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/context/field_final_side_context.tsx deleted file mode 100644 index 295bb31fc3f5c..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/context/field_final_side_context.tsx +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { createContext, useContext, type PropsWithChildren, useMemo } from 'react'; -import { useBoolean } from '@kbn/react-hooks'; -import type { UpgradeableDiffableFields } from '../../../../../model/prebuilt_rule_upgrade/fields'; -import { invariant } from '../../../../../../../../common/utils/invariant'; -import { FieldFinalSideMode } from '../field_final_side_mode'; - -interface FieldFinalSideState { - /** - * Field name of an upgradable field from DiffableRule - */ - fieldName: UpgradeableDiffableFields; - /** - * Field final side view mode `Readonly` or `Editing` - */ - mode: FieldFinalSideMode; -} - -interface FieldFinalSideActions { - /** - * Sets Readonly field final side view mode - */ - setReadOnlyMode: () => void; - /** - * Sets Editing field final side view mode - */ - setEditMode: () => void; -} - -interface FieldFinalSideContextType { - state: FieldFinalSideState; - actions: FieldFinalSideActions; -} - -const FieldFinalSideContext = createContext(null); - -interface FieldFinalSideContextProviderProps { - fieldName: UpgradeableDiffableFields; - initialMode: FieldFinalSideMode; -} - -export function FieldFinalSideContextProvider({ - children, - fieldName, - initialMode, -}: PropsWithChildren) { - const [editing, { on: setEditMode, off: setReadOnlyMode }] = useBoolean( - initialMode === FieldFinalSideMode.Edit - ); - - const contextValue: FieldFinalSideContextType = useMemo( - () => ({ - state: { - fieldName, - mode: editing ? FieldFinalSideMode.Edit : FieldFinalSideMode.Readonly, - }, - actions: { - setReadOnlyMode, - setEditMode, - }, - }), - [fieldName, editing, setReadOnlyMode, setEditMode] - ); - - return ( - {children} - ); -} - -export function useFieldFinalSideContext(): FieldFinalSideContextType { - const context = useContext(FieldFinalSideContext); - - invariant( - context !== null, - 'useFieldFinalSideContext must be used inside a FieldFinalSideContextProvider' - ); - - return context; -} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/index.ts index a0d86970f9956..bcab35a1c27b1 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/index.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/index.ts @@ -5,8 +5,6 @@ * 2.0. */ -export * from './field_final_side_mode'; export * from './components/field_final_side'; export type * from './components/rule_field_edit_component_props'; export * from './components/rule_field_edit_form_wrapper'; -export { useFieldFinalSideContext } from './context/field_final_side_context'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx index be8950a1534c3..542e9aabcddd2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_final_edit.tsx @@ -18,8 +18,7 @@ import type { UpgradeableMachineLearningFields, } from '../../../../model/prebuilt_rule_upgrade/fields'; import { isCommonFieldName } from '../../../../model/prebuilt_rule_upgrade/fields'; -import { useFieldFinalSideContext } from '../field_final_side'; -import { useFinalRuleContext } from '../final_rule_context'; +import { useFieldUpgradeContext } from '../rule_upgrade/field_upgrade_context'; import { CommonRuleFieldEdit } from './common_rule_field_edit'; import { CustomQueryRuleFieldEdit } from './custom_query_rule_field_edit'; import { SavedQueryRuleFieldEdit } from './saved_query_rule_field_edit'; @@ -31,18 +30,16 @@ import { EsqlRuleFieldEdit } from './esql_rule_field_edit'; import { MachineLearningRuleFieldEdit } from './machine_learning_rule_field_edit'; export function FieldFinalEdit(): JSX.Element { - const { finalDiffableRule } = useFinalRuleContext(); - const { type } = finalDiffableRule; - const { - state: { fieldName }, - } = useFieldFinalSideContext(); + fieldName, + finalDiffableRule: { type: ruleType }, + } = useFieldUpgradeContext(); if (isCommonFieldName(fieldName)) { return ; } - switch (type) { + switch (ruleType) { case 'query': return ; case 'saved_query': @@ -62,6 +59,6 @@ export function FieldFinalEdit(): JSX.Element { case 'new_terms': return ; default: - return assertUnreachable(type); + return assertUnreachable(ruleType); } } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx index 404509f2bf64d..33abbb4792946 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_final_readonly.tsx @@ -18,8 +18,7 @@ import type { DiffableMachineLearningFields, } from '../../../../../../../common/api/detection_engine'; import { assertUnreachable } from '../../../../../../../common/utility_types'; -import { useFinalRuleContext } from '../final_rule_context'; -import { useFieldFinalSideContext } from '../field_final_side'; +import { useFieldUpgradeContext } from '../rule_upgrade/field_upgrade_context'; import { CustomQueryRuleFieldReadOnly } from './custom_query_rule_field_readonly'; import { SavedQueryRuleFieldReadOnly } from './saved_query_rule_field_readonly'; import { EqlRuleFieldReadOnly } from './eql_rule_field_readonly'; @@ -31,10 +30,7 @@ import { NewTermsRuleFieldReadOnly } from './new_terms_rule_field_readonly'; import { CommonRuleFieldReadOnly } from './common_rule_field_readonly'; export function FieldFinalReadOnly(): JSX.Element { - const { finalDiffableRule } = useFinalRuleContext(); - const { - state: { fieldName }, - } = useFieldFinalSideContext(); + const { fieldName, finalDiffableRule } = useFieldUpgradeContext(); const { data: commonField } = useMemo( () => DiffableCommonFields.keyof().safeParse(fieldName), diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/three_way_diff_storybook_providers.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/three_way_diff_storybook_providers.tsx index 89327dd0f6c07..d961f3d23befb 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/three_way_diff_storybook_providers.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/three_way_diff_storybook_providers.tsx @@ -16,11 +16,12 @@ import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; import type { UpgradeableDiffableFields } from '../../../../../model/prebuilt_rule_upgrade/fields'; import { ReactQueryClientProvider } from '../../../../../../../common/containers/query_client/query_client_provider'; import { UpsellingProvider } from '../../../../../../../common/components/upselling_provider'; -import { FinalRuleContextProvider } from '../../final_rule_context'; -import type { DiffableRule } from '../../../../../../../../common/api/detection_engine'; -import { FieldFinalSideContextProvider } from '../../field_final_side/context/field_final_side_context'; +import { FieldUpgradeContextProvider } from '../../rule_upgrade/field_upgrade_context'; +import type { + DiffableRule, + RuleResponse, +} from '../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from './mocks'; -import { FieldFinalSideMode } from '../../field_final_side'; function createKibanaServicesMock(overrides?: Partial) { const baseMock = { @@ -95,22 +96,35 @@ export function ThreeWayDiffStorybookProviders({ const store = createMockStore(); + const ruleUpgradeStateMock = { + id: 'test-id', + rule_id: 'test-id', + current_rule: {} as RuleResponse, + target_rule: {} as RuleResponse, + diff: { + fields: {}, + num_fields_with_updates: 0, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + revision: 1, + finalRule: finalDiffableRule, + hasUnresolvedConflicts: false, + fieldsUpgradeState: {}, + }; + return ( - - - {children} - - + {children} + diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_rule_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_rule_context.tsx deleted file mode 100644 index 3486fa8c23464..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_rule_context.tsx +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { createContext, useContext } from 'react'; -import type { DiffableRule } from '../../../../../../common/api/detection_engine'; -import { invariant } from '../../../../../../common/utils/invariant'; -import type { SetRuleFieldResolvedValueFn } from '../../../model/prebuilt_rule_upgrade/set_rule_field_resolved_value'; - -interface FinalRuleContextType { - finalDiffableRule: DiffableRule; - setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; -} - -const FinalRuleContext = createContext(null); - -interface FinalRuleContextProviderProps { - finalDiffableRule: DiffableRule; - setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; - children: React.ReactNode; -} - -export function FinalRuleContextProvider({ - finalDiffableRule, - setRuleFieldResolvedValue, - children, -}: FinalRuleContextProviderProps) { - const contextValue = { - finalDiffableRule, - setRuleFieldResolvedValue, - }; - - return {children}; -} - -export function useFinalRuleContext() { - const context = useContext(FinalRuleContext); - - invariant(context !== null, 'useFinalRuleContext must be used inside a FinalRuleContextProvider'); - - return context; -} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_mode.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/index.ts similarity index 76% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_mode.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/index.ts index 8c0dc3db3d261..95e6836ca8f09 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/field_final_side_mode.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/index.ts @@ -5,7 +5,4 @@ * 2.0. */ -export enum FieldFinalSideMode { - Readonly = 'readonly', - Edit = 'edit', -} +export { RuleUpgrade as RuleUpgradeTab } from './rule_upgrade'; 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 c0d7974080414..04ddb1bd6a52e 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 @@ -10,39 +10,22 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer, useEuiTheme } from '@elastic/eui' import { css } from '@emotion/css'; import { isEqual } from 'lodash'; import { SplitAccordion } from '../../../../../../common/components/split_accordion'; -import type { - DiffableAllFields, - RuleFieldsDiff, - ThreeWayDiff, -} from '../../../../../../../common/api/detection_engine'; import { ThreeWayDiffConflict } from '../../../../../../../common/api/detection_engine'; -import type { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { FieldComparisonSide } from '../comparison_side/field_comparison_side'; import { FieldFinalSide } from '../field_final_side'; import { FieldUpgradeHeader } from './field_upgrade_header'; -import { useFinalRuleContext } from '../final_rule_context'; -import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; +import { useFieldUpgradeContext } from './field_upgrade_context'; -interface FieldUpgradeProps { - fieldName: FieldName; - fieldUpgradeState: FieldUpgradeState; - fieldThreeWayDiff: RuleFieldsDiff[FieldName]; -} - -export function FieldUpgrade({ - fieldName, - fieldUpgradeState, - fieldThreeWayDiff, -}: FieldUpgradeProps): JSX.Element { +export function FieldUpgrade(): JSX.Element { const { euiTheme } = useEuiTheme(); - const hasConflict = fieldThreeWayDiff.conflict !== ThreeWayDiffConflict.NONE; - const { finalDiffableRule } = useFinalRuleContext(); + const { fieldName, fieldUpgradeState, fieldDiff } = useFieldUpgradeContext(); + const hasConflict = fieldDiff.conflict !== ThreeWayDiffConflict.NONE; const isFieldCustomized = useMemo( () => - fieldThreeWayDiff.has_base_version - ? !isEqual(fieldThreeWayDiff.base_version, fieldThreeWayDiff.current_version) + fieldDiff.has_base_version + ? !isEqual(fieldDiff.base_version, fieldDiff.current_version) : false, - [fieldThreeWayDiff] + [fieldDiff] ); return ( @@ -60,11 +43,7 @@ export function FieldUpgrade({ > - } - resolvedValue={finalDiffableRule[fieldName] as DiffableAllFields[FieldName]} - /> + ({ `} /> - + 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 new file mode 100644 index 0000000000000..407809484a951 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_context.tsx @@ -0,0 +1,124 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { createContext, useContext, useMemo } from 'react'; +import { useBoolean } from '@kbn/react-hooks'; +import type { DiffableRule, ThreeWayDiff } from '../../../../../../../common/api/detection_engine'; +import { invariant } from '../../../../../../../common/utils/invariant'; +import type { SetRuleFieldResolvedValueFn } from '../../../../model/prebuilt_rule_upgrade/set_rule_field_resolved_value'; +import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; +import type { RuleUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; +import { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; + +export enum FieldFinalSideMode { + Readonly = 'readonly', + Edit = 'edit', +} + +interface FieldUpgradeContextType { + /** + * Field name of an upgradable field from DiffableRule + */ + fieldName: UpgradeableDiffableFields; + /** + * Field's upgrade state + */ + fieldUpgradeState: FieldUpgradeState; + /** + * Field's three way diff + */ + fieldDiff: ThreeWayDiff; + /** + * Current final diffable rule including resolved values + */ + finalDiffableRule: DiffableRule; + /** + * Field final side view mode `Readonly` or `Editing` + */ + rightSideMode: FieldFinalSideMode; + /** + * Sets field's resolved value + */ + setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; + /** + * Sets field's right side `readonly` mode + */ + setReadOnlyMode: () => void; + /** + * Sets field's right side `edit` mode + */ + setEditMode: () => void; +} + +const FieldUpgradeContext = createContext(null); + +interface FieldUpgradeContextProviderProps { + ruleUpgradeState: RuleUpgradeState; + fieldName: UpgradeableDiffableFields; + setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; + children: React.ReactNode; +} + +export function FieldUpgradeContextProvider({ + ruleUpgradeState, + fieldName, + setRuleFieldResolvedValue, + children, +}: FieldUpgradeContextProviderProps) { + const fieldUpgradeState = ruleUpgradeState.fieldsUpgradeState[fieldName]; + const fieldDiff = ruleUpgradeState.diff.fields[fieldName]; + const initialRightSideMode = + fieldUpgradeState === FieldUpgradeState.NonSolvableConflict + ? FieldFinalSideMode.Edit + : FieldFinalSideMode.Readonly; + + const [editing, { on: setEditMode, off: setReadOnlyMode }] = useBoolean( + initialRightSideMode === FieldFinalSideMode.Edit + ); + + if (!fieldDiff) { + throw new Error(`Field diff is not found for ${fieldName}.`); + } + + const contextValue: FieldUpgradeContextType = useMemo( + () => ({ + fieldName, + fieldUpgradeState, + fieldDiff, + finalDiffableRule: ruleUpgradeState.finalRule, + rightSideMode: editing ? FieldFinalSideMode.Edit : FieldFinalSideMode.Readonly, + setRuleFieldResolvedValue, + setReadOnlyMode, + setEditMode, + }), + [ + fieldName, + fieldUpgradeState, + fieldDiff, + ruleUpgradeState.finalRule, + editing, + setRuleFieldResolvedValue, + setReadOnlyMode, + setEditMode, + ] + ); + + return ( + {children} + ); +} + +export function useFieldUpgradeContext() { + const context = useContext(FieldUpgradeContext); + + invariant( + context !== null, + 'useFieldUpgradeContext must be used inside a FieldUpgradeContextProvider' + ); + + return context; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx index 08c3b6491ff54..a875d7e3939b2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx @@ -5,50 +5,90 @@ * 2.0. */ -import React from 'react'; +import React, { memo } from 'react'; import { EuiSpacer } from '@elastic/eui'; -import type { RuleUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; -import type { NonUpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; -import { isNonUpgradeableFieldName } from '../../../../model/prebuilt_rule_upgrade/fields'; +import type { PartialRuleDiff } from '../../../../../../../common/api/detection_engine'; +import { + NON_UPGRADEABLE_DIFFABLE_FIELDS, + ThreeWayDiffConflict, +} from '../../../../../../../common/api/detection_engine'; +import type { + RuleUpgradeState, + SetRuleFieldResolvedValueFn, +} from '../../../../model/prebuilt_rule_upgrade'; +import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; import { RuleUpgradeInfoBar } from './rule_upgrade_info_bar'; import { RuleUpgradeCallout } from './rule_upgrade_callout'; import { FieldUpgrade } from './field_upgrade'; - -type FieldDiffEntries = Array< - [ - Exclude, - Required[Exclude] - ] ->; +import { FieldUpgradeContextProvider } from './field_upgrade_context'; interface RuleUpgradeProps { ruleUpgradeState: RuleUpgradeState; + setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } -export function RuleUpgrade({ ruleUpgradeState }: RuleUpgradeProps): React.ReactNode { - const fieldDiffEntries = Object.entries(ruleUpgradeState.diff.fields) as FieldDiffEntries< - typeof ruleUpgradeState.diff.fields - >; - - const fields = fieldDiffEntries.filter(([fieldName]) => { - return isNonUpgradeableFieldName(fieldName) === false; - }) as FieldDiffEntries; +export const RuleUpgrade = memo(function RuleUpgrade({ + ruleUpgradeState, + setRuleFieldResolvedValue, +}: RuleUpgradeProps): JSX.Element { + const cleanedRuleUpgradeState = { + ...ruleUpgradeState, + diff: cleanupNonCustomizableFieldDiffs(ruleUpgradeState.diff), + }; + const fieldNames = Object.keys( + cleanedRuleUpgradeState.diff.fields + ) as UpgradeableDiffableFields[]; return ( <> - + - + - {fields.map(([fieldName, fieldDiff]) => ( - ( + + setRuleFieldResolvedValue={setRuleFieldResolvedValue} + > + + ))} ); +}); + +/** + * Cleans up non customizable field diffs + */ +function cleanupNonCustomizableFieldDiffs(diff: PartialRuleDiff): PartialRuleDiff { + const result = { + ...diff, + fields: { + ...diff.fields, + }, + }; + + for (const nonCustomizableFieldName of NON_UPGRADEABLE_DIFFABLE_FIELDS) { + const nonCustomizableFieldDiff = result.fields[nonCustomizableFieldName]; + + if (nonCustomizableFieldDiff?.conflict === ThreeWayDiffConflict.NONE) { + result.num_fields_with_updates--; + } + + if (nonCustomizableFieldDiff?.conflict === ThreeWayDiffConflict.SOLVABLE) { + result.num_fields_with_conflicts--; + } + + if (nonCustomizableFieldDiff?.conflict === ThreeWayDiffConflict.NON_SOLVABLE) { + result.num_fields_with_non_solvable_conflicts--; + result.num_fields_with_conflicts--; + } + + delete result.fields[nonCustomizableFieldName]; + } + + return result; } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade_tab.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade_tab.tsx deleted file mode 100644 index 4bbd73e942b41..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade_tab.tsx +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import type { - RuleUpgradeState, - SetRuleFieldResolvedValueFn, -} from '../../../model/prebuilt_rule_upgrade'; -import { RuleUpgrade } from './rule_upgrade'; -import { FinalRuleContextProvider } from './final_rule_context'; - -interface RuleUpgradeTabProps { - ruleUpgradeState: RuleUpgradeState; - setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; -} - -export function RuleUpgradeTab({ - ruleUpgradeState, - setRuleFieldResolvedValue, -}: RuleUpgradeTabProps): JSX.Element { - return ( - - - - ); -} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx index 055e1faeb4456..e30efc3706a61 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx @@ -19,7 +19,7 @@ import type { RuleUpgradeState, RulesUpgradeState, } from '../../../../rule_management/model/prebuilt_rule_upgrade'; -import { RuleUpgradeTab } from '../../../../rule_management/components/rule_details/three_way_diff/rule_upgrade_tab'; +import { RuleUpgradeTab } from '../../../../rule_management/components/rule_details/three_way_diff'; import { PerFieldRuleDiffTab } from '../../../../rule_management/components/rule_details/per_field_rule_diff_tab'; import { useIsUpgradingSecurityPackages } from '../../../../rule_management/logic/use_upgrade_security_packages'; import type { From 13db2dacaecaa1019e7c9c7c6649c9305aea9ae0 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 26 Nov 2024 13:38:55 +0100 Subject: [PATCH 16/77] use a proper key for SubfieldChanges component rendered items --- .../three_way_diff/comparison_side/subfield_changes.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/subfield_changes.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/subfield_changes.tsx index af10edbe1c599..68d737abd40ae 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/subfield_changes.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/subfield_changes.tsx @@ -30,7 +30,7 @@ export function SubfieldChanges({ fieldName, subfieldChanges }: SubfieldChangesP return ( <> Date: Tue, 26 Nov 2024 14:29:09 +0100 Subject: [PATCH 17/77] remove unused translations keys --- .../plugins/private/translations/translations/fr-FR.json | 4 ---- .../plugins/private/translations/translations/ja-JP.json | 4 ---- .../plugins/private/translations/translations/zh-CN.json | 4 ---- 3 files changed, 12 deletions(-) diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index 79b8cc8c74439..5d9eb663cc38a 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -39094,18 +39094,14 @@ "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasNonSolvableConflictsDescription": "Veuillez apporter une contribution au conflit non résolu. Vous pouvez également conserver la version actuelle sans les mises à jour, ou accepter la mise à jour Elastic tout en perdant vos modifications.", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflicts": "{count} des champs {count, plural, one {a} other {ont}} un conflit de mise à jour. Veuillez examiner la mise à jour en cours suggérée.", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflictsDescription": "Veuillez consulter la version mise à jour recommandée avant de l'accepter. Vous pouvez modifier le champ, puis l'enregistrer, si nécessaire.", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleIsReadyForUpgrade": "La mise à jour est prête à être appliquée.", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleIsReadyForUpgradeDescription": "Tous les conflits ont maintenant été examinés et résolus, veuillez mettre à jour la règle.", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.separator": "-", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.solvableConflict": "Conflit résolu", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.solvableConflictDescription": "Nous avons suggéré une mise à jour pour ce champ modifié, veuillez la consulter avant d'accepter.", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.updateAccepted": "Mise à jour acceptée", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.updateAcceptedDescription": "Vous pouvez toujours apporter des modifications, veuillez consulter/accepter tous les autres conflits avant de mettre à jour la règle.", "xpack.securitySolution.detectionEngine.rules.upgradeRules.finalUpdate": "Mise à jour finale", "xpack.securitySolution.detectionEngine.rules.upgradeRules.noRulesBodyTitle": "Il n’y a actuellement aucune mise à jour disponible pour vos règles Elastic installées.", "xpack.securitySolution.detectionEngine.rules.upgradeRules.noRulesTitle": "Toutes les règles Elastic sont à jour", "xpack.securitySolution.detectionEngine.rules.upgradeRules.ruleUpgradeHelper": "Découvrez comment {docsLink}.", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.saveButtonLabel": "Enregistrer", "xpack.securitySolution.detectionEngine.rules.upgradeRules.searchBarPlaceholder": "Rechercher par nom de règle", "xpack.securitySolution.detectionEngine.rules.upgradeRules.updatedVersionDescriptionLabel": "Affiche la règle qui sera installée", "xpack.securitySolution.detectionEngine.rules.upgradeRules.updateYourRulesDocsLink": "mettre à jour vos règles", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index 52c4a1bf5b8c9..b1cd897acdaf9 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -38951,18 +38951,14 @@ "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasNonSolvableConflictsDescription": "未解決の競合の情報を入力してください。更新を適用せずに現在の状態を維持することもできます。Elasticの更新を承認すると、修正内容は失われます。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflicts": "{count}個のフィールド{count, plural, other {には}}更新の競合があります。更新中の候補の更新を確認してください。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflictsDescription": "更新を承認する前に、提案された更新バージョンを確認してください。変更する場合は、編集してフィールドを保存できます。", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleIsReadyForUpgrade": "更新を適用できます。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleIsReadyForUpgradeDescription": "すべての競合が確認され、解決されました。ルールを更新してください。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.separator": "-", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.solvableConflict": "解決された競合", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.solvableConflictDescription": "この修正されたフィールドの更新を提案しました。承認する前に確認してください。", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.updateAccepted": "更新が承認されました", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.updateAcceptedDescription": "変更を行うことができます。ルールを更新する前に、他のすべての競合を確認/承認してください。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.finalUpdate": "最終更新", "xpack.securitySolution.detectionEngine.rules.upgradeRules.noRulesBodyTitle": "現在、インストールされているElasticルールに利用可能な更新はありません。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.noRulesTitle": "すべてのElasticルールが最新です", "xpack.securitySolution.detectionEngine.rules.upgradeRules.ruleUpgradeHelper": "{docsLink}方法を確認してください。", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.saveButtonLabel": "保存", "xpack.securitySolution.detectionEngine.rules.upgradeRules.searchBarPlaceholder": "ルール名で検索", "xpack.securitySolution.detectionEngine.rules.upgradeRules.updatedVersionDescriptionLabel": "インストールされるルールを表示します", "xpack.securitySolution.detectionEngine.rules.upgradeRules.updateYourRulesDocsLink": "ルールを更新", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index c7b9faa1dd4b9..4a8250680c9da 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -38375,18 +38375,14 @@ "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasNonSolvableConflictsDescription": "请为未解决的冲突提供输入。您还可以保持现状而不进行更新,也可以接受 Elastic 更新但丢失修改。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflicts": "{count} 个字段{count, plural, other {存在}}更新冲突,请复查正在更新的建议更新。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflictsDescription": "在接受更新之前,请复查建议的已更新版本。如果希望更改字段,您可以编辑然后保存字段。", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleIsReadyForUpgrade": "更新已准备就绪,可以应用。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleIsReadyForUpgradeDescription": "现已复查并解决所有冲突,请更新规则。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.separator": "-", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.solvableConflict": "已解决冲突", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.solvableConflictDescription": "我们已为这个已修改字段推荐了更新,请在接受前进行复查。", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.updateAccepted": "已接受更新", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.updateAcceptedDescription": "您仍然可以做出更改,在更新规则之前,请复查/接受所有其他冲突。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.finalUpdate": "最后更新", "xpack.securitySolution.detectionEngine.rules.upgradeRules.noRulesBodyTitle": "您已安装的 Elastic 规则当前没有可用更新。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.noRulesTitle": "所有 Elastic 规则均保持最新", "xpack.securitySolution.detectionEngine.rules.upgradeRules.ruleUpgradeHelper": "了解如何 {docsLink}。", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.saveButtonLabel": "保存", "xpack.securitySolution.detectionEngine.rules.upgradeRules.searchBarPlaceholder": "按规则名称搜索", "xpack.securitySolution.detectionEngine.rules.upgradeRules.updatedVersionDescriptionLabel": "显示将安装的规则", "xpack.securitySolution.detectionEngine.rules.upgradeRules.updateYourRulesDocsLink": "更新您的规则", From 155aa853aa651e8a09c37af7889243842d1ba168 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 26 Nov 2024 18:29:56 +0100 Subject: [PATCH 18/77] simplify layout for field update header --- .../field_upgrade_state_info.tsx | 18 ++++++++++++++---- .../rule_upgrade/field_upgrade_header.tsx | 13 ++++++------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/field_upgrade_state_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/field_upgrade_state_info.tsx index 3ce3427dff829..a7ed834eb3b21 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/field_upgrade_state_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/field_upgrade_state_info.tsx @@ -6,7 +6,7 @@ */ import React, { useMemo } from 'react'; -import { EuiText } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; import { assertUnreachable } from '../../../../../../../common/utility_types'; import { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { ReadyForUpgradeBadge } from '../badges/ready_for_upgrade_badge'; @@ -59,9 +59,19 @@ export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JS return ( <> - - {badge}  {title} - {description ? `${i18n.SEPARATOR} ${i18n.NO_CONFLICT_DESCRIPTION}` : null} + + + {badge} + + {title} + + + {description ? ( + + {i18n.SEPARATOR} {i18n.NO_CONFLICT_DESCRIPTION} + + ) : null} + ); 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 261894097db94..7cb5d0dbc8843 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 @@ -7,7 +7,7 @@ import React from 'react'; import { camelCase, startCase } from 'lodash'; -import { EuiFlexGroup, EuiTitle } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; import { fieldToDisplayNameMap } from '../../diff_components/translations'; import type { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { ModifiedBadge } from '../badges/modified_badge'; @@ -28,20 +28,19 @@ export function FieldUpgradeHeader({ isCustomized, }: FieldUpgradeHeaderProps): JSX.Element { return ( - +
{fieldToDisplayNameMap[fieldName] ?? startCase(camelCase(fieldName))}
- + {isCustomized && ( - <> + -   - + )} - +
); } From 55436ef27f29a39088123e653bc027436c22a13b Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Wed, 27 Nov 2024 11:48:48 +0100 Subject: [PATCH 19/77] simplify conflicts number calculation --- .../rule_upgrade/rule_upgrade_callout.tsx | 27 ++++--------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx index 32bd52e0e7cce..ae673a8f233eb 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx @@ -5,10 +5,9 @@ * 2.0. */ -import React, { useMemo } from 'react'; +import React from 'react'; import { EuiCallOut } from '@elastic/eui'; import type { RuleUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; -import { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { ActionRequiredBadge } from '../badges/action_required'; import { ReviewRequiredBadge } from '../badges/review_required_badge'; import { ReadyForUpgradeBadge } from '../badges/ready_for_upgrade_badge'; @@ -19,26 +18,10 @@ interface RuleUpgradeCalloutProps { } export function RuleUpgradeCallout({ ruleUpgradeState }: RuleUpgradeCalloutProps): JSX.Element { - const fieldsUpgradeState = ruleUpgradeState.fieldsUpgradeState; - const { numOfNonSolvableConflicts, numOfSolvableConflicts } = useMemo(() => { - let numOfFieldsWithNonSolvableConflicts = 0; - let numOfFieldsWithSolvableConflicts = 0; - - for (const fieldName of Object.keys(fieldsUpgradeState)) { - if (fieldsUpgradeState[fieldName] === FieldUpgradeState.NonSolvableConflict) { - numOfFieldsWithNonSolvableConflicts++; - } - - if (fieldsUpgradeState[fieldName] === FieldUpgradeState.SolvableConflict) { - numOfFieldsWithSolvableConflicts++; - } - } - - return { - numOfNonSolvableConflicts: numOfFieldsWithNonSolvableConflicts, - numOfSolvableConflicts: numOfFieldsWithSolvableConflicts, - }; - }, [fieldsUpgradeState]); + const numOfNonSolvableConflicts = ruleUpgradeState.diff.num_fields_with_non_solvable_conflicts; + const numOfSolvableConflicts = + ruleUpgradeState.diff.num_fields_with_conflicts - + ruleUpgradeState.diff.num_fields_with_non_solvable_conflicts; if (numOfNonSolvableConflicts > 0) { return ( From e99dcf85d492e47cb49e93489a0132693320aea3 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Wed, 27 Nov 2024 11:50:19 +0100 Subject: [PATCH 20/77] show current rule update info as last update --- .../upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx index 4a81ebdb6eabc..4f5596b2f8e04 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx @@ -29,8 +29,8 @@ export const UpgradeFlyoutSubHeader = memo(function UpgradeFlyoutSubHeader({ {':'} {' '} {i18n.UPDATED_BY_AND_WHEN( - ruleUpgradeState.target_rule.created_by, - + ruleUpgradeState.current_rule.updated_by, + )}
); From 0dd8ac974f5b3ca22d850cef04292c2fa9d8e837 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Wed, 27 Nov 2024 11:56:49 +0100 Subject: [PATCH 21/77] copy side header to SIEM migrations --- .../translation_tab/rule_query.tsx | 9 ++++-- .../translation_tab/side_header.tsx | 29 +++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/side_header.tsx diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/rule_query.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/rule_query.tsx index d05d0974f474d..68375c053acef 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/rule_query.tsx +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/rule_query.tsx @@ -7,6 +7,7 @@ import React, { useMemo } from 'react'; import { EuiMarkdownEditor, EuiMarkdownFormat, EuiTitle } from '@elastic/eui'; +import { SideHeader } from './side_header'; import * as i18n from './translations'; interface RuleQueryProps { @@ -33,9 +34,11 @@ export const RuleQueryComponent = ({ title, query, canEdit }: RuleQueryProps) => }, [canEdit, query]); return ( <> - -

{title}

-
+ + +

{title}

+
+
{queryTextComponent} ); diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/side_header.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/side_header.tsx new file mode 100644 index 0000000000000..574e3f526f856 --- /dev/null +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/side_header.tsx @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { PropsWithChildren } from 'react'; +import React from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, useEuiTheme } from '@elastic/eui'; +import { css } from '@emotion/css'; + +export function SideHeader({ children }: PropsWithChildren<{}>) { + const { euiTheme } = useEuiTheme(); + + return ( + <> + + {children} + + + + ); +} From 2ab328a48388af5c531f4b0342d86d78de2ee3cc Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Thu, 28 Nov 2024 19:52:09 +0100 Subject: [PATCH 22/77] fix broken imports --- .../final_edit/fields/esql_query/esql_query_edit_adapter.tsx | 2 +- .../final_edit/fields/esql_query/esql_query_edit_form.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/esql_query/esql_query_edit_adapter.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/esql_query/esql_query_edit_adapter.tsx index faf43d5b88b22..a3b1faf667d99 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/esql_query/esql_query_edit_adapter.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/esql_query/esql_query_edit_adapter.tsx @@ -7,8 +7,8 @@ import React from 'react'; import type { DataViewBase } from '@kbn/es-query'; +import type { RuleFieldEditComponentProps } from '../../../field_final_side'; import { EsqlQueryEdit } from '../../../../../../../rule_creation/components/esql_query_edit'; -import type { RuleFieldEditComponentProps } from '../rule_field_edit_component_props'; import { useDiffableRuleDataView } from '../hooks/use_diffable_rule_data_view'; export function EsqlQueryEditAdapter({ diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/esql_query/esql_query_edit_form.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/esql_query/esql_query_edit_form.tsx index a156ef747aedc..dd482b6962d8a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/esql_query/esql_query_edit_form.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/esql_query/esql_query_edit_form.tsx @@ -7,7 +7,7 @@ import React from 'react'; import type { FormData, FormSchema } from '../../../../../../../../shared_imports'; -import { RuleFieldEditFormWrapper } from '../rule_field_edit_form_wrapper'; +import { RuleFieldEditFormWrapper } from '../../../field_final_side'; import type { FieldValueQueryBar } from '../../../../../../../rule_creation_ui/components/query_bar_field'; import { type DiffableRule, From 6abef528e10b7f8afeb94c0008099cf0cfe14982 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 29 Nov 2024 09:44:56 +0100 Subject: [PATCH 23/77] use human friendly names for rule/field versions --- .../comparison_side_help_info.tsx | 64 +++++++++- .../comparison_side/field_comparison_side.tsx | 6 +- .../three_way_diff/comparison_side/utils.ts | 2 +- .../versions_picker/constants.ts | 0 .../versions_picker/translations.ts | 109 ++++++++++++++++++ .../versions_picker.stories.tsx | 0 .../versions_picker/versions_picker.tsx | 0 .../rule_upgrade/field_upgrade_header.tsx | 2 +- .../field_upgrade_state_info.tsx | 12 +- .../field_upgrade_state_info/index.ts | 0 .../field_upgrade_state_info/translations.tsx | 0 .../versions_picker/translations.ts | 57 --------- 12 files changed, 183 insertions(+), 69 deletions(-) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{ => comparison_side}/versions_picker/constants.ts (100%) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/translations.ts rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{ => comparison_side}/versions_picker/versions_picker.stories.tsx (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{ => comparison_side}/versions_picker/versions_picker.tsx (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{ => rule_upgrade}/field_upgrade_state_info/field_upgrade_state_info.tsx (82%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{ => rule_upgrade}/field_upgrade_state_info/index.ts (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{ => rule_upgrade}/field_upgrade_state_info/translations.tsx (100%) delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/versions_picker/translations.ts diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx index e1eaa9b1e96cd..fd263177a58c3 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx @@ -9,6 +9,14 @@ 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 { i18n } from '@kbn/i18n'; +import { TITLE } from './translations'; +import { + BASE_VERSION, + CURRENT_VERSION, + FINAL_VERSION, + TARGET_VERSION, +} from './versions_picker/translations'; /** * Theme doesn't expose width variables. Using provided size variables will require @@ -35,9 +43,63 @@ export function ComparisonSideHelpInfo(): JSX.Element { {TITLE}, + versions: ( + <> +
+
    +
  • + {BASE_VERSION} {'-'} {BASE_VERSION_EXPLANATION} +
  • +
  • + {CURRENT_VERSION} {'-'} {CURRENT_VERSION_EXPLANATION} +
  • +
  • + {TARGET_VERSION} {'-'} {TARGET_VERSION_EXPLANATION} +
  • +
  • + {FINAL_VERSION} {'-'} {FINAL_VERSION_EXPLANATION} +
  • +
+ + ), + }} />
); } + +const BASE_VERSION_EXPLANATION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeHelpText.baseVersionExplanation', + { + defaultMessage: 'version originally installed from Elastic prebuilt rules package', + } +); + +const CURRENT_VERSION_EXPLANATION = ( + {BASE_VERSION}, + }} + /> +); + +const TARGET_VERSION_EXPLANATION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeHelpText.currentVersionExplanation', + { + defaultMessage: 'version coming from a new version of Elastic prebuilt rules package', + } +); + +const FINAL_VERSION_EXPLANATION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeHelpText.currentVersionExplanation', + { + defaultMessage: + 'version used to the update the rule. Initial value is suggested by the diff algorithm.', + } +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx index 26e65d7593da2..7234c58680639 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx @@ -7,9 +7,9 @@ import React, { useState } from 'react'; import { EuiFlexGroup, EuiTitle } from '@elastic/eui'; -import { VersionsPicker } from '../versions_picker/versions_picker'; -import type { Version } from '../versions_picker/constants'; -import { SelectedVersions } from '../versions_picker/constants'; +import { VersionsPicker } from './versions_picker/versions_picker'; +import type { Version } from './versions_picker/constants'; +import { SelectedVersions } from './versions_picker/constants'; import { FieldUpgradeSideHeader } from '../field_upgrade_side_header'; import { useFieldUpgradeContext } from '../rule_upgrade/field_upgrade_context'; import { pickFieldValueForVersion } from './utils'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts index 21397db2c02ba..8f97d3462d358 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts @@ -6,7 +6,7 @@ */ import stringify from 'json-stable-stringify'; -import { Version } from '../versions_picker/constants'; +import { Version } from './versions_picker/constants'; import type { ThreeWayDiff } from '../../../../../../../common/api/detection_engine'; /** diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/versions_picker/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/versions_picker/constants.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/translations.ts new file mode 100644 index 0000000000000..3367b7dc85997 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/translations.ts @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const BASE_VERSION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVersionLabel', + { + defaultMessage: 'Original', + } +); + +export const CURRENT_VERSION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.currentVersionLabel', + { + defaultMessage: 'Current', + } +); + +export const TARGET_VERSION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.targetVersionLabel', + { + defaultMessage: 'Elastic update', + } +); + +export const FINAL_VERSION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.finalVersionLabel', + { + defaultMessage: 'Final', + } +); + +export const BASE_VS_TARGET = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsTargetLabel', + { + defaultMessage: '{base} vs {target}', + values: { + base: BASE_VERSION, + target: TARGET_VERSION, + }, + } +); + +export const BASE_VS_CURRENT = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsCurrentLabel', + { + defaultMessage: '{base} vs {current}', + values: { + base: BASE_VERSION, + current: CURRENT_VERSION, + }, + } +); + +export const BASE_VS_FINAL = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsFinalLabel', + { + defaultMessage: '{base} vs {final}', + values: { + base: BASE_VERSION, + final: FINAL_VERSION, + }, + } +); + +export const CURRENT_VS_TARGET = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.currentVsTargetLabel', + { + defaultMessage: '{current} vs {target}', + values: { + current: CURRENT_VERSION, + target: TARGET_VERSION, + }, + } +); + +export const CURRENT_VS_FINAL = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.currentVsFinalLabel', + { + defaultMessage: '{current} vs {final}', + values: { + current: CURRENT_VERSION, + final: FINAL_VERSION, + }, + } +); + +export const TARGET_VS_FINAL = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.targetVsFinalLabel', + { + defaultMessage: '{target} vs {final}', + values: { + target: TARGET_VERSION, + final: FINAL_VERSION, + }, + } +); + +export const VERSION_PICKER_ARIA_LABEL = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.ariaLabel', + { + defaultMessage: 'Select versions to compare', + } +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/versions_picker/versions_picker.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.stories.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/versions_picker/versions_picker.stories.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.stories.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/versions_picker/versions_picker.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/versions_picker/versions_picker.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx 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 7cb5d0dbc8843..89dee1b434cec 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,7 +11,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; import { fieldToDisplayNameMap } from '../../diff_components/translations'; import type { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { ModifiedBadge } from '../badges/modified_badge'; -import { FieldUpgradeStateInfo } from '../field_upgrade_state_info'; +import { FieldUpgradeStateInfo } from './field_upgrade_state_info'; interface FieldUpgradeHeaderProps { fieldName: string; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/field_upgrade_state_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx similarity index 82% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/field_upgrade_state_info.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx index a7ed834eb3b21..656a1fb9cc859 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/field_upgrade_state_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx @@ -7,11 +7,11 @@ import React, { useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; -import { assertUnreachable } from '../../../../../../../common/utility_types'; -import { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; -import { ReadyForUpgradeBadge } from '../badges/ready_for_upgrade_badge'; -import { ReviewRequiredBadge } from '../badges/review_required_badge'; -import { ActionRequiredBadge } from '../badges/action_required'; +import { assertUnreachable } from '../../../../../../../../common/utility_types'; +import { FieldUpgradeState } from '../../../../../model/prebuilt_rule_upgrade'; +import { ReadyForUpgradeBadge } from '../../badges/ready_for_upgrade_badge'; +import { ReviewRequiredBadge } from '../../badges/review_required_badge'; +import { ActionRequiredBadge } from '../../badges/action_required'; import * as i18n from './translations'; interface FieldUpgradeStateInfoProps { @@ -60,7 +60,7 @@ export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JS return ( <> - + {badge} {title} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/index.ts similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/index.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/index.ts diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/translations.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_upgrade_state_info/translations.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/translations.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/versions_picker/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/versions_picker/translations.ts deleted file mode 100644 index 15699edc206e7..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/versions_picker/translations.ts +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const BASE_VS_TARGET = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsTargetLabel', - { - defaultMessage: 'Base vs Target', - } -); - -export const BASE_VS_CURRENT = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsCurrentLabel', - { - defaultMessage: 'Base vs Current', - } -); - -export const BASE_VS_FINAL = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsFinalLabel', - { - defaultMessage: 'Base vs Final', - } -); - -export const CURRENT_VS_TARGET = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.currentVsTargetLabel', - { - defaultMessage: 'Current vs Target', - } -); - -export const CURRENT_VS_FINAL = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.currentVsFinalLabel', - { - defaultMessage: 'Current vs Final', - } -); - -export const TARGET_VS_FINAL = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.targetVsFinalLabel', - { - defaultMessage: 'Target vs Final', - } -); - -export const VERSION_PICKER_ARIA_LABEL = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.ariaLabel', - { - defaultMessage: 'Select versions to compare', - } -); From 1e707b9da8fe53c105317c7e92855e741de7dfd9 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 3 Dec 2024 08:42:15 +0100 Subject: [PATCH 24/77] display a proper field description --- .../field_upgrade_state_info/field_upgrade_state_info.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx index 656a1fb9cc859..9328c407c8165 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx @@ -66,11 +66,11 @@ export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JS {title} - {description ? ( + {description && ( - {i18n.SEPARATOR} {i18n.NO_CONFLICT_DESCRIPTION} + {i18n.SEPARATOR} {description} - ) : null} + )} From 8494eeae6619ef1e886eee8e11438e1bbc9c81d1 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 3 Dec 2024 08:42:40 +0100 Subject: [PATCH 25/77] fix translations --- .../translations/translations/fr-FR.json | 7 -- .../translations/translations/ja-JP.json | 7 -- .../translations/translations/zh-CN.json | 7 -- .../comparison_side_help_info.tsx | 10 +-- .../versions_picker/constants.ts | 12 +-- .../versions_picker/translations.ts | 85 ++++--------------- .../components/field_final_side_help_info.tsx | 2 +- 7 files changed, 28 insertions(+), 102 deletions(-) diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index 5d9eb663cc38a..a7773bc59ee7c 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -39106,15 +39106,8 @@ "xpack.securitySolution.detectionEngine.rules.upgradeRules.updatedVersionDescriptionLabel": "Affiche la règle qui sera installée", "xpack.securitySolution.detectionEngine.rules.upgradeRules.updateYourRulesDocsLink": "mettre à jour vos règles", "xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeAll": "Tout mettre à jour", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeHelpText": "Choisissez les valeurs de champ utilisées dans la règle mise à niveau.", "xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeSelected": "Mettre à jour {numberOfSelectedRules} règle(s) sélectionnée(s)", "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.ariaLabel": "Sélectionnez les versions à comparer", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsCurrentLabel": "Base - Actuel", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsFinalLabel": "Base - Final", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsTargetLabel": "Base - Cible", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.currentVsFinalLabel": "Actuel - Final", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.currentVsTargetLabel": "Actuel - Cible", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.targetVsFinalLabel": "Actuel - Final", "xpack.securitySolution.detectionEngine.rulesSnoozeBadge.error.unableToFetch": "Impossible de récupérer les paramètres de répétition", "xpack.securitySolution.detectionEngine.ruleStatus.askAssistant": "Demander à l'assistant", "xpack.securitySolution.detectionEngine.ruleStatus.askAssistantDesc": "Message d'erreur de l'exécution de la règle", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index b1cd897acdaf9..464f021624699 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -38963,15 +38963,8 @@ "xpack.securitySolution.detectionEngine.rules.upgradeRules.updatedVersionDescriptionLabel": "インストールされるルールを表示します", "xpack.securitySolution.detectionEngine.rules.upgradeRules.updateYourRulesDocsLink": "ルールを更新", "xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeAll": "すべて更新", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeHelpText": "アップグレードされたルールで使用されるフィールド値を選択してください。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeSelected": "{numberOfSelectedRules}個の選択したルールを更新", "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.ariaLabel": "比較するバージョンを選択", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsCurrentLabel": "基本と現在", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsFinalLabel": "基本と最終", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsTargetLabel": "基本とターゲット", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.currentVsFinalLabel": "現在と最終", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.currentVsTargetLabel": "現在とターゲット", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.targetVsFinalLabel": "ターゲットと最終", "xpack.securitySolution.detectionEngine.rulesSnoozeBadge.error.unableToFetch": "スヌーズ設定を取得できません", "xpack.securitySolution.detectionEngine.ruleStatus.askAssistant": "アシスタントに聞く", "xpack.securitySolution.detectionEngine.ruleStatus.askAssistantDesc": "ルールの実行失敗メッセージ", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index 4a8250680c9da..86b67d3c4ad34 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -38387,15 +38387,8 @@ "xpack.securitySolution.detectionEngine.rules.upgradeRules.updatedVersionDescriptionLabel": "显示将安装的规则", "xpack.securitySolution.detectionEngine.rules.upgradeRules.updateYourRulesDocsLink": "更新您的规则", "xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeAll": "全部更新", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeHelpText": "选择用在已升级规则中的字段值。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeSelected": "更新 {numberOfSelectedRules} 个选定规则", "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.ariaLabel": "选择要比较的版本", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsCurrentLabel": "基础与当前", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsFinalLabel": "基础与最终", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsTargetLabel": "基础与目标", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.currentVsFinalLabel": "当前与最终", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.currentVsTargetLabel": "当前与目标", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.targetVsFinalLabel": "目标与最终", "xpack.securitySolution.detectionEngine.rulesSnoozeBadge.error.unableToFetch": "无法提取暂停设置", "xpack.securitySolution.detectionEngine.ruleStatus.askAssistant": "询问助手", "xpack.securitySolution.detectionEngine.ruleStatus.askAssistantDesc": "规则的执行失败消息", diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx index fd263177a58c3..47e5e537f3ab0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx @@ -42,7 +42,7 @@ export function ComparisonSideHelpInfo(): JSX.Element { {TITLE}, @@ -73,7 +73,7 @@ export function ComparisonSideHelpInfo(): JSX.Element { } const BASE_VERSION_EXPLANATION = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeHelpText.baseVersionExplanation', + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.baseVersionExplanation', { defaultMessage: 'version originally installed from Elastic prebuilt rules package', } @@ -81,7 +81,7 @@ const BASE_VERSION_EXPLANATION = i18n.translate( const CURRENT_VERSION_EXPLANATION = ( {BASE_VERSION}, @@ -90,14 +90,14 @@ const CURRENT_VERSION_EXPLANATION = ( ); const TARGET_VERSION_EXPLANATION = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeHelpText.currentVersionExplanation', + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.targetVersionExplanation', { defaultMessage: 'version coming from a new version of Elastic prebuilt rules package', } ); const FINAL_VERSION_EXPLANATION = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradeHelpText.currentVersionExplanation', + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.finalVersionExplanation', { defaultMessage: 'version used to the update the rule. Initial value is suggested by the diff algorithm.', diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts index 73a7e89a200a3..04d38ed10dce2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts @@ -27,32 +27,32 @@ export enum SelectedVersions { export const CURRENT_OPTIONS: EuiSelectOption[] = [ { value: SelectedVersions.CurrentFinal, - text: i18n.CURRENT_VS_FINAL, + text: i18n.VERSION1_VS_VERSION2(i18n.CURRENT_VERSION, i18n.FINAL_VERSION), }, { value: SelectedVersions.CurrentTarget, - text: i18n.CURRENT_VS_TARGET, + text: i18n.VERSION1_VS_VERSION2(i18n.CURRENT_VERSION, i18n.TARGET_VERSION), }, ]; export const TARGET_OPTIONS: EuiSelectOption[] = [ { value: SelectedVersions.TargetFinal, - text: i18n.TARGET_VS_FINAL, + text: i18n.VERSION1_VS_VERSION2(i18n.TARGET_VERSION, i18n.FINAL_VERSION), }, ]; export const BASE_OPTIONS: EuiSelectOption[] = [ { value: SelectedVersions.BaseFinal, - text: i18n.BASE_VS_FINAL, + text: i18n.VERSION1_VS_VERSION2(i18n.BASE_VERSION, i18n.FINAL_VERSION), }, { value: SelectedVersions.BaseTarget, - text: i18n.BASE_VS_TARGET, + text: i18n.VERSION1_VS_VERSION2(i18n.BASE_VERSION, i18n.TARGET_VERSION), }, { value: SelectedVersions.BaseCurrent, - text: i18n.BASE_VS_CURRENT, + text: i18n.VERSION1_VS_VERSION2(i18n.BASE_VERSION, i18n.CURRENT_VERSION), }, ]; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/translations.ts index 3367b7dc85997..0f63b8be2aa92 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/translations.ts @@ -8,98 +8,45 @@ import { i18n } from '@kbn/i18n'; export const BASE_VERSION = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVersionLabel', + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.baseVersionLabel', { defaultMessage: 'Original', } ); export const CURRENT_VERSION = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.currentVersionLabel', + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.currentVersionLabel', { defaultMessage: 'Current', } ); export const TARGET_VERSION = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.targetVersionLabel', + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.targetVersionLabel', { defaultMessage: 'Elastic update', } ); export const FINAL_VERSION = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.finalVersionLabel', + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.finalVersionLabel', { defaultMessage: 'Final', } ); -export const BASE_VS_TARGET = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsTargetLabel', - { - defaultMessage: '{base} vs {target}', - values: { - base: BASE_VERSION, - target: TARGET_VERSION, - }, - } -); - -export const BASE_VS_CURRENT = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsCurrentLabel', - { - defaultMessage: '{base} vs {current}', - values: { - base: BASE_VERSION, - current: CURRENT_VERSION, - }, - } -); - -export const BASE_VS_FINAL = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsFinalLabel', - { - defaultMessage: '{base} vs {final}', - values: { - base: BASE_VERSION, - final: FINAL_VERSION, - }, - } -); - -export const CURRENT_VS_TARGET = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.currentVsTargetLabel', - { - defaultMessage: '{current} vs {target}', - values: { - current: CURRENT_VERSION, - target: TARGET_VERSION, - }, - } -); - -export const CURRENT_VS_FINAL = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.currentVsFinalLabel', - { - defaultMessage: '{current} vs {final}', - values: { - current: CURRENT_VERSION, - final: FINAL_VERSION, - }, - } -); - -export const TARGET_VS_FINAL = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.targetVsFinalLabel', - { - defaultMessage: '{target} vs {final}', - values: { - target: TARGET_VERSION, - final: FINAL_VERSION, - }, - } -); +export const VERSION1_VS_VERSION2 = (version1: string, version2: string): string => { + return i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.version1VsVersion2', + { + defaultMessage: '{version1} vs {version2}', + values: { + version1, + version2, + }, + } + ); +}; export const VERSION_PICKER_ARIA_LABEL = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.ariaLabel', diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_help_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_help_info.tsx index 32a55401dbf3c..e3e0b38da7d63 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_help_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_help_info.tsx @@ -34,7 +34,7 @@ export function FieldFinalSideHelpInfo(): JSX.Element { From 7a2715bbb2fae4150b75fe7d2e4823a9a3bcf42c Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 3 Dec 2024 11:06:14 +0100 Subject: [PATCH 26/77] fix rule upgrade state callout --- .../rule_upgrade/rule_upgrade_callout.tsx | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx index ae673a8f233eb..e3204c6028eed 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx @@ -5,9 +5,9 @@ * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; import { EuiCallOut } from '@elastic/eui'; -import type { RuleUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; +import { FieldUpgradeState, type RuleUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { ActionRequiredBadge } from '../badges/action_required'; import { ReviewRequiredBadge } from '../badges/review_required_badge'; import { ReadyForUpgradeBadge } from '../badges/ready_for_upgrade_badge'; @@ -18,10 +18,21 @@ interface RuleUpgradeCalloutProps { } export function RuleUpgradeCallout({ ruleUpgradeState }: RuleUpgradeCalloutProps): JSX.Element { - const numOfNonSolvableConflicts = ruleUpgradeState.diff.num_fields_with_non_solvable_conflicts; - const numOfSolvableConflicts = - ruleUpgradeState.diff.num_fields_with_conflicts - - ruleUpgradeState.diff.num_fields_with_non_solvable_conflicts; + const fieldsUpgradeState = ruleUpgradeState.fieldsUpgradeState; + const [numOfNonSolvableConflicts, numOfSolvableConflicts] = useMemo(() => { + let nonSolvableConflicts = 0; + let solvableConflicts = 0; + + for (const state of Object.values(fieldsUpgradeState)) { + if (state === FieldUpgradeState.NonSolvableConflict) { + nonSolvableConflicts++; + } else if (state === FieldUpgradeState.SolvableConflict) { + solvableConflicts++; + } + } + + return [nonSolvableConflicts, solvableConflicts]; + }, [fieldsUpgradeState]); if (numOfNonSolvableConflicts > 0) { return ( From d77b40f14713f24fa43f45b1a87c537c7fc8c4b4 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 3 Dec 2024 12:31:48 +0100 Subject: [PATCH 27/77] add a proper key for subfield changes --- .../three_way_diff/comparison_side/subfield_changes.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/subfield_changes.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/subfield_changes.tsx index 68d737abd40ae..a5d44438f161c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/subfield_changes.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/subfield_changes.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { Fragment } from 'react'; import { EuiHorizontalRule } from '@elastic/eui'; import type { SubfieldChanges } from './types'; import { Subfield } from './subfield'; @@ -28,16 +28,15 @@ export function SubfieldChanges({ fieldName, subfieldChanges }: SubfieldChangesP const shouldShowSeparator = index !== subfieldChanges.length - 1; return ( - <> + {shouldShowSeparator ? : null} - + ); })} From 6f773f7f31d86eed71fc2f68a4648a4691fd6508 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 3 Dec 2024 12:34:27 +0100 Subject: [PATCH 28/77] fix rule upgrade info --- .../perform_rule_upgrade_route.ts | 2 +- .../rule_upgrade/rule_upgrade.tsx | 50 ++--------------- .../rule_upgrade/rule_upgrade_info_bar.tsx | 4 +- .../rule_upgrade/translations.tsx | 2 +- .../rule_upgrade_state.ts | 7 ++- .../upgrade_flyout_subheader.tsx | 8 ++- .../use_prebuilt_rules_upgrade_state.ts | 54 +++++++++++++++++-- 7 files changed, 70 insertions(+), 57 deletions(-) diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_upgrade/perform_rule_upgrade_route.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_upgrade/perform_rule_upgrade_route.ts index 0021aece67455..9908193705243 100644 --- a/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_upgrade/perform_rule_upgrade_route.ts +++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_upgrade/perform_rule_upgrade_route.ts @@ -50,7 +50,7 @@ export const FIELDS_TO_UPGRADE_TO_TARGET_VERSION = [ // Fields which are part of DiffableRule but are not upgradeable // and need to be omittted from the DiffableUpgradableFields -export const NON_UPGRADEABLE_DIFFABLE_FIELDS = ['type', 'rule_id', 'version'] as const; +export const NON_UPGRADEABLE_DIFFABLE_FIELDS: Readonly = ['type', 'rule_id', 'version']; type NON_UPGRADEABLE_DIFFABLE_FIELDS_TO_OMIT_TYPE = { readonly [key in (typeof NON_UPGRADEABLE_DIFFABLE_FIELDS)[number]]: true; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx index a875d7e3939b2..c8fc36cc75f5c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx @@ -7,11 +7,6 @@ import React, { memo } from 'react'; import { EuiSpacer } from '@elastic/eui'; -import type { PartialRuleDiff } from '../../../../../../../common/api/detection_engine'; -import { - NON_UPGRADEABLE_DIFFABLE_FIELDS, - ThreeWayDiffConflict, -} from '../../../../../../../common/api/detection_engine'; import type { RuleUpgradeState, SetRuleFieldResolvedValueFn, @@ -31,25 +26,21 @@ export const RuleUpgrade = memo(function RuleUpgrade({ ruleUpgradeState, setRuleFieldResolvedValue, }: RuleUpgradeProps): JSX.Element { - const cleanedRuleUpgradeState = { - ...ruleUpgradeState, - diff: cleanupNonCustomizableFieldDiffs(ruleUpgradeState.diff), - }; const fieldNames = Object.keys( - cleanedRuleUpgradeState.diff.fields + ruleUpgradeState.fieldsUpgradeState ) as UpgradeableDiffableFields[]; return ( <> - + - + {fieldNames.map((fieldName) => ( @@ -59,36 +50,3 @@ export const RuleUpgrade = memo(function RuleUpgrade({ ); }); - -/** - * Cleans up non customizable field diffs - */ -function cleanupNonCustomizableFieldDiffs(diff: PartialRuleDiff): PartialRuleDiff { - const result = { - ...diff, - fields: { - ...diff.fields, - }, - }; - - for (const nonCustomizableFieldName of NON_UPGRADEABLE_DIFFABLE_FIELDS) { - const nonCustomizableFieldDiff = result.fields[nonCustomizableFieldName]; - - if (nonCustomizableFieldDiff?.conflict === ThreeWayDiffConflict.NONE) { - result.num_fields_with_updates--; - } - - if (nonCustomizableFieldDiff?.conflict === ThreeWayDiffConflict.SOLVABLE) { - result.num_fields_with_conflicts--; - } - - if (nonCustomizableFieldDiff?.conflict === ThreeWayDiffConflict.NON_SOLVABLE) { - result.num_fields_with_non_solvable_conflicts--; - result.num_fields_with_conflicts--; - } - - delete result.fields[nonCustomizableFieldName]; - } - - return result; -} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx index 970f04f383274..9c6f34aafff0a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx @@ -20,8 +20,8 @@ interface UpgradeInfoBarProps { } export function RuleUpgradeInfoBar({ ruleUpgradeState }: UpgradeInfoBarProps): JSX.Element { - const numOfFieldsWithUpdates = ruleUpgradeState.diff.num_fields_with_updates; - const numOfConflicts = ruleUpgradeState.diff.num_fields_with_conflicts; + const numOfFieldsWithUpdates = ruleUpgradeState.customizableFieldsDiff.num_fields_with_updates; + const numOfConflicts = ruleUpgradeState.customizableFieldsDiff.num_fields_with_conflicts; return ( 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 4b376eb908b0f..d93cdfccad3ec 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 @@ -14,7 +14,7 @@ import { useKibana } from '../../../../../../common/lib/kibana/kibana_react'; export const NUM_OF_FIELDS_WITH_UPDATES = (count: number) => ( {count} }} /> ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/rule_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/rule_upgrade_state.ts index 0c72361bb29dc..8bb38cbf476f0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/rule_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/rule_upgrade_state.ts @@ -5,6 +5,7 @@ * 2.0. */ +import type { PartialRuleDiff } from '../../../../../common/api/detection_engine'; import { type DiffableRule, type RuleUpgradeInfoForReview, @@ -16,12 +17,16 @@ export interface RuleUpgradeState extends RuleUpgradeInfoForReview { * Rule containing desired values users expect to see in the upgraded rule. */ finalRule: DiffableRule; + /** + * Customizable fields diff. It's the same as diff but doesn't contain non customizable fields like `version`. + */ + customizableFieldsDiff: PartialRuleDiff; /** * Indicates whether there are conflicts blocking rule upgrading. */ hasUnresolvedConflicts: boolean; /** - * Stores a record of field names mapped to field upgrade state. + * Stores a record of customizable field names mapped to field upgrade state. */ fieldsUpgradeState: FieldsUpgradeState; } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx index 4f5596b2f8e04..bc004db92debc 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx @@ -50,12 +50,16 @@ export const UpgradeFlyoutSubHeader = memo(function UpgradeFlyoutSubHeader({ const customized = ruleUpgradeState.current_rule.rule_source.type === 'external' && ruleUpgradeState.current_rule.rule_source.is_customized && ; - const fieldUpdates = ( + const fieldsNamesWithUpdates = Object.entries(ruleUpgradeState.customizableFieldsDiff.fields) + .filter(([, diff]) => diff.has_update) + .map(([fieldName]) => fieldName); + + const fieldUpdates = fieldsNamesWithUpdates.length > 0 && ( {i18n.FIELD_UPDATES} {':'}{' '} - {Object.keys(ruleUpgradeState.diff.fields) + {fieldsNamesWithUpdates .map((fieldName) => fieldToDisplayNameMap[fieldName] ?? startCase(camelCase(fieldName))) .join(', ')} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts index dfed81605bb27..e117e6aaa50e0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts @@ -6,6 +6,7 @@ */ import { useCallback, useMemo, useState } from 'react'; +import { pick } from 'lodash'; import { useIsPrebuiltRulesCustomizationEnabled } from '../../../../rule_management/hooks/use_is_prebuilt_rules_customization_enabled'; import type { RulesUpgradeState, @@ -13,6 +14,7 @@ import type { SetRuleFieldResolvedValueFn, } from '../../../../rule_management/model/prebuilt_rule_upgrade'; import { FieldUpgradeState } from '../../../../rule_management/model/prebuilt_rule_upgrade'; +import type { PartialRuleDiff } from '../../../../../../common/api/detection_engine'; import { type FieldsDiff, type DiffableAllFields, @@ -20,8 +22,10 @@ import { type RuleUpgradeInfoForReview, ThreeWayDiffConflict, type RuleSignatureId, + NON_UPGRADEABLE_DIFFABLE_FIELDS, } from '../../../../../../common/api/detection_engine'; import { convertRuleToDiffable } from '../../../../../../common/detection_engine/prebuilt_rules/diff/convert_rule_to_diffable'; +import { assertUnreachable } from '../../../../../../common/utility_types'; type RuleResolvedConflicts = Partial; type RulesResolvedConflicts = Record; @@ -54,14 +58,17 @@ export function usePrebuiltRulesUpgradeState( const state: RulesUpgradeState = {}; for (const ruleUpgradeInfo of ruleUpgradeInfos) { + const customizableFieldsDiff = calcCustomizableFieldsDiff(ruleUpgradeInfo.diff); + state[ruleUpgradeInfo.rule_id] = { ...ruleUpgradeInfo, + customizableFieldsDiff, finalRule: calcFinalDiffableRule( ruleUpgradeInfo, rulesResolvedConflicts[ruleUpgradeInfo.rule_id] ?? {} ), fieldsUpgradeState: calcFieldsState( - ruleUpgradeInfo.diff.fields, + customizableFieldsDiff, rulesResolvedConflicts[ruleUpgradeInfo.rule_id] ?? {} ), hasUnresolvedConflicts: isPrebuiltRulesCustomizationEnabled @@ -82,6 +89,38 @@ export function usePrebuiltRulesUpgradeState( }; } +function calcCustomizableFieldsDiff(ruleFieldsDiff: PartialRuleDiff): PartialRuleDiff { + const cutomizableFieldNames = Object.keys(ruleFieldsDiff.fields).filter( + (fieldName) => !NON_UPGRADEABLE_DIFFABLE_FIELDS.includes(fieldName) + ); + const fieldsDiff = pick(ruleFieldsDiff.fields, cutomizableFieldNames); + + let numFieldsWithUpdates = 0; + let numFieldsWithConflicts = 0; + let numFieldsWithNonSolvableConflicts = 0; + + for (const fieldDiff of Object.values(fieldsDiff)) { + if (fieldDiff.has_update) { + numFieldsWithUpdates++; + } + + if (fieldDiff.conflict !== ThreeWayDiffConflict.NONE) { + numFieldsWithConflicts++; + } + + if (fieldDiff.conflict === ThreeWayDiffConflict.NON_SOLVABLE) { + numFieldsWithNonSolvableConflicts++; + } + } + + return { + num_fields_with_updates: numFieldsWithUpdates, + num_fields_with_conflicts: numFieldsWithConflicts, + num_fields_with_non_solvable_conflicts: numFieldsWithNonSolvableConflicts, + fields: fieldsDiff, + }; +} + function calcFinalDiffableRule( ruleUpgradeInfo: RuleUpgradeInfoForReview, ruleResolvedConflicts: RuleResolvedConflicts @@ -109,13 +148,17 @@ function convertRuleFieldsDiffToDiffable( } function calcFieldsState( - ruleFieldsDiff: FieldsDiff>, + ruleDiff: PartialRuleDiff, ruleResolvedConflicts: RuleResolvedConflicts ): FieldsUpgradeState { const fieldsState: FieldsUpgradeState = {}; - for (const fieldName of Object.keys(ruleFieldsDiff)) { - switch (ruleFieldsDiff[fieldName].conflict) { + for (const fieldName of Object.keys(ruleDiff.fields)) { + const conflict = + ruleDiff.fields[fieldName as keyof typeof ruleDiff.fields]?.conflict ?? + ThreeWayDiffConflict.NONE; + + switch (conflict) { case ThreeWayDiffConflict.NONE: fieldsState[fieldName] = FieldUpgradeState.NoConflict; break; @@ -127,6 +170,9 @@ function calcFieldsState( case ThreeWayDiffConflict.NON_SOLVABLE: fieldsState[fieldName] = FieldUpgradeState.NonSolvableConflict; break; + + default: + assertUnreachable(conflict); } } From 6e50d6bc09067718ed1182f675935ca461684116 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 3 Dec 2024 13:06:40 +0100 Subject: [PATCH 29/77] fix improper rule.id usage for rule upgrade flyout --- .../use_add_prebuilt_rules_table_columns.tsx | 2 +- .../use_upgrade_prebuilt_rules_table_columns.tsx | 2 +- .../components/rules_table/use_rule_preview_flyout.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx index a0a317e72b4c2..4e15de4011fab 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx @@ -55,7 +55,7 @@ export const RULE_NAME_COLUMN: TableColumn = { field: 'name', name: i18n.COLUMN_RULE, render: (value: RuleResponse['name'], rule: RuleResponse) => ( - + ), sortable: true, truncateText: true, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_prebuilt_rules_table_columns.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_prebuilt_rules_table_columns.tsx index c2b1f8e3dbe46..919664c100b2f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_prebuilt_rules_table_columns.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_prebuilt_rules_table_columns.tsx @@ -59,7 +59,7 @@ const RULE_NAME_COLUMN: TableColumn = { field: 'current_rule.name', name: i18n.COLUMN_RULE, render: (value: RuleUpgradeState['current_rule']['name'], ruleUpgradeState: RuleUpgradeState) => ( - + ), sortable: true, truncateText: true, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rule_preview_flyout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rule_preview_flyout.tsx index 1ab0105e19271..2578871dec9b8 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rule_preview_flyout.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rule_preview_flyout.tsx @@ -72,7 +72,7 @@ export function useRulePreviewFlyout({ ), openRulePreview: useCallback( (ruleId: RuleSignatureId) => { - const ruleToShowInFlyout = rules.find((x) => x.id === ruleId); + const ruleToShowInFlyout = rules.find((x) => x.rule_id === ruleId); invariant(ruleToShowInFlyout, `Rule with id ${ruleId} not found`); setRuleForPreview(ruleToShowInFlyout); From e4863173237dd24e19132577a9a723a22e3e5e92 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 3 Dec 2024 13:14:47 +0100 Subject: [PATCH 30/77] move upgradeAllRule to UpgradePrebuiltRulesTableContext --- .../upgrade_prebuilt_rules_table_buttons.tsx | 22 ++--- .../upgrade_prebuilt_rules_table_context.tsx | 56 ++++++------ .../use_rule_preview_flyout.tsx | 87 +++++++++++++++++++ 3 files changed, 123 insertions(+), 42 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rules_preview_flyout/use_rule_preview_flyout.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx index 8a1d201149654..ff2f389564b79 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx @@ -21,14 +21,14 @@ export const UpgradePrebuiltRulesTableButtons = ({ }: UpgradePrebuiltRulesTableButtonsProps) => { const { state: { - ruleUpgradeInfos, + rulesUpgradeState, hasRulesToUpgrade, loadingRules, isRefetching, isUpgradingSecurityPackages, isPrebuiltRulesCustomizationEnabled, }, - actions: { upgradeRules }, + actions: { upgradeRules, upgradeAllRules }, } = useUpgradePrebuiltRulesTableContext(); const [{ loading: isUserDataLoading, canUserCRUD }] = useUserData(); const canUserEditRules = canUserCRUD && !isUserDataLoading; @@ -38,10 +38,12 @@ export const UpgradePrebuiltRulesTableButtons = ({ const isRuleUpgrading = loadingRules.length > 0; const isRequestInProgress = isRuleUpgrading || isRefetching || isUpgradingSecurityPackages; + const everyFieldHasConflict = Object.values(rulesUpgradeState).every( + ({ diff }) => diff.num_fields_with_conflicts > 0 + ); const doAllSelectedRulesHaveConflicts = - isPrebuiltRulesCustomizationEnabled && isAllRuleHaveConflicts(selectedRules); - const doAllRulesHaveConflicts = - isPrebuiltRulesCustomizationEnabled && isAllRuleHaveConflicts(ruleUpgradeInfos); + isPrebuiltRulesCustomizationEnabled && everyFieldHasConflict; + const doAllRulesHaveConflicts = isPrebuiltRulesCustomizationEnabled && everyFieldHasConflict; const { selectedRulesButtonTooltip, allRulesButtonTooltip } = useBulkUpdateButtonsTooltipContent({ canUserEditRules, @@ -55,12 +57,6 @@ export const UpgradePrebuiltRulesTableButtons = ({ [selectedRules, upgradeRules] ); - const upgradeAllRules = useCallback( - // Upgrade all rules, ignoring filter and selection - () => upgradeRules(ruleUpgradeInfos.map((rule) => rule.rule_id)), - [ruleUpgradeInfos, upgradeRules] - ); - return ( {shouldDisplayUpgradeSelectedRulesButton ? ( @@ -146,7 +142,3 @@ const useBulkUpdateButtonsTooltipContent = ({ allRulesButtonTooltip: undefined, }; }; - -function isAllRuleHaveConflicts(rules: Array<{ diff: { num_fields_with_conflicts: number } }>) { - return rules.every((rule) => rule.diff.num_fields_with_conflicts > 0); -} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx index e30efc3706a61..5b18dd68776ff 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx @@ -10,7 +10,6 @@ import type { Dispatch, SetStateAction } from 'react'; import React, { createContext, useCallback, useContext, useMemo, useState } from 'react'; import type { RuleFieldsToUpgrade, - RuleUpgradeInfoForReview, RuleUpgradeSpecifier, } from '../../../../../../common/api/detection_engine'; import { useIsPrebuiltRulesCustomizationEnabled } from '../../../../rule_management/hooks/use_is_prebuilt_rules_customization_enabled'; @@ -33,7 +32,7 @@ import { usePrebuiltRulesUpgradeReview } from '../../../../rule_management/logic import { RuleDiffTab } from '../../../../rule_management/components/rule_details/rule_diff_tab'; import { FieldUpgradeState } from '../../../../rule_management/model/prebuilt_rule_upgrade/field_upgrade_state'; import { isNonUpgradeableFieldName } from '../../../../rule_management/model/prebuilt_rule_upgrade/fields'; -import { useRulePreviewFlyout } from '../use_rule_preview_flyout'; +import { useRulePreviewFlyout } from '../use_rules_preview_flyout/use_rule_preview_flyout'; import { MlJobUpgradeModal } from './modals/ml_job_upgrade_modal'; import { UpgradeConflictsModal } from './modals/upgrade_conflicts_modal'; import type { UpgradePrebuiltRulesTableFilterOptions } from './use_filter_prebuilt_rules_to_upgrade'; @@ -46,10 +45,6 @@ import * as ruleDetailsI18n from '../../../../rule_management/components/rule_de import * as i18n from './translations'; export interface UpgradePrebuiltRulesTableState { - /** - * Rule upgrade state (all rules available for upgrade) - */ - ruleUpgradeInfos: RuleUpgradeInfoForReview[]; /** * Rule upgrade state after applying `filterOptions` */ @@ -102,6 +97,7 @@ export const PREBUILT_RULE_UPDATE_FLYOUT_ANCHOR = 'updatePrebuiltRulePreview'; export interface UpgradePrebuiltRulesTableActions { reFetchRules: () => void; upgradeRules: (ruleIds: RuleSignatureId[]) => void; + upgradeAllRules: () => void; setFilterOptions: Dispatch>; openRulePreview: (ruleId: string) => void; } @@ -264,6 +260,12 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ [isPrebuiltRulesCustomizationEnabled, upgradeRulesToResolved, upgradeRulesToTarget] ); + const upgradeAllRules = useCallback( + // Upgrade all rules, ignoring filter and selection + () => upgradeRules(ruleUpgradeInfos.map((rule) => rule.rule_id)), + [ruleUpgradeInfos, upgradeRules] + ); + const subHeaderFactory = useCallback( (rule: RuleResponse) => rulesUpgradeState[rule.rule_id] ? ( @@ -392,18 +394,18 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ () => ({ reFetchRules: refetch, upgradeRules, + upgradeAllRules, setFilterOptions, openRulePreview, }), - [refetch, upgradeRules, openRulePreview] + [refetch, upgradeRules, upgradeAllRules, openRulePreview] ); - const providerValue = useMemo(() => { - return { + const providerValue = useMemo( + () => ({ state: { - ruleUpgradeInfos, rulesUpgradeState, - hasRulesToUpgrade: isFetched && ruleUpgradeInfos.length > 0, + hasRulesToUpgrade: isFetched && Object.keys(rulesUpgradeState).length > 0, filterOptions, tags, isFetched, @@ -415,22 +417,22 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ isPrebuiltRulesCustomizationEnabled, }, actions, - }; - }, [ - ruleUpgradeInfos, - rulesUpgradeState, - filterOptions, - tags, - isFetched, - isLoading, - loadingJobs, - isRefetching, - isUpgradingSecurityPackages, - loadingRules, - dataUpdatedAt, - actions, - isPrebuiltRulesCustomizationEnabled, - ]); + }), + [ + rulesUpgradeState, + filterOptions, + tags, + isFetched, + isLoading, + loadingJobs, + isRefetching, + isUpgradingSecurityPackages, + loadingRules, + dataUpdatedAt, + actions, + isPrebuiltRulesCustomizationEnabled, + ] + ); return ( diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rules_preview_flyout/use_rule_preview_flyout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rules_preview_flyout/use_rule_preview_flyout.tsx new file mode 100644 index 0000000000000..53054b5c3403d --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rules_preview_flyout/use_rule_preview_flyout.tsx @@ -0,0 +1,87 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ReactNode } from 'react'; +import React, { useCallback, useState, useMemo } from 'react'; +import type { EuiTabbedContentTab } from '@elastic/eui'; +import { invariant } from '../../../../../../common/utils/invariant'; +import type { RuleSignatureId } from '../../../../../../common/api/detection_engine'; +import { RuleDetailsFlyout } from '../../../../rule_management/components/rule_details/rule_details_flyout'; + +interface RuleLike { + rule_id: RuleSignatureId; +} + +interface UseRulePreviewFlyoutParams { + rules: T[]; + ruleActionsFactory: (rule: T, closeRulePreview: () => void) => ReactNode; + extraTabsFactory?: (rule: T) => EuiTabbedContentTab[]; + subHeaderFactory?: (rule: T) => ReactNode; + flyoutProps: RulePreviewFlyoutProps; +} + +interface RulePreviewFlyoutProps { + /** + * Rule preview flyout unique id used in HTML + */ + id: string; + dataTestSubj: string; +} + +interface UseRulePreviewFlyoutResult { + rulePreviewFlyout: ReactNode; + openRulePreview: (ruleId: RuleSignatureId) => void; + closeRulePreview: () => void; +} + +export function useRulePreviewFlyout({ + rules, + extraTabsFactory, + ruleActionsFactory, + subHeaderFactory, + flyoutProps, +}: UseRulePreviewFlyoutParams): UseRulePreviewFlyoutResult { + const [rule, setRuleForPreview] = useState(); + const closeRulePreview = useCallback(() => setRuleForPreview(undefined), []); + const subHeader = useMemo( + () => (rule ? subHeaderFactory?.(rule) : null), + [subHeaderFactory, rule] + ); + const ruleActions = useMemo( + () => rule && ruleActionsFactory(rule, closeRulePreview), + [rule, ruleActionsFactory, closeRulePreview] + ); + const extraTabs = useMemo( + () => (rule && extraTabsFactory ? extraTabsFactory(rule) : []), + [rule, extraTabsFactory] + ); + + return { + rulePreviewFlyout: rule && ( + + ), + openRulePreview: useCallback( + (ruleId: RuleSignatureId) => { + const ruleToShowInFlyout = rules.find((x) => x.rule_id === ruleId); + + invariant(ruleToShowInFlyout, `Rule with rule_id ${ruleId} not found`); + setRuleForPreview(ruleToShowInFlyout); + }, + [rules, setRuleForPreview] + ), + closeRulePreview, + }; +} From 496e63e99c8dc8060eb7b0cd6b1b71a42ee89255 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 3 Dec 2024 13:23:58 +0100 Subject: [PATCH 31/77] simplify hasUnresolvedConflicts calculation --- .../use_prebuilt_rules_upgrade_state.ts | 35 +++++-------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts index e117e6aaa50e0..0dc428ee33460 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts @@ -59,6 +59,10 @@ export function usePrebuiltRulesUpgradeState( for (const ruleUpgradeInfo of ruleUpgradeInfos) { const customizableFieldsDiff = calcCustomizableFieldsDiff(ruleUpgradeInfo.diff); + const fieldsUpgradeState = calcFieldsState( + customizableFieldsDiff, + rulesResolvedConflicts[ruleUpgradeInfo.rule_id] ?? {} + ); state[ruleUpgradeInfo.rule_id] = { ...ruleUpgradeInfo, @@ -67,15 +71,11 @@ export function usePrebuiltRulesUpgradeState( ruleUpgradeInfo, rulesResolvedConflicts[ruleUpgradeInfo.rule_id] ?? {} ), - fieldsUpgradeState: calcFieldsState( - customizableFieldsDiff, - rulesResolvedConflicts[ruleUpgradeInfo.rule_id] ?? {} - ), + fieldsUpgradeState, hasUnresolvedConflicts: isPrebuiltRulesCustomizationEnabled - ? getUnacceptedConflictsCount( - ruleUpgradeInfo.diff.fields, - rulesResolvedConflicts[ruleUpgradeInfo.rule_id] ?? {} - ) > 0 + ? Object.values(fieldsUpgradeState).some( + (x) => x !== FieldUpgradeState.NoConflict && x !== FieldUpgradeState.Accepted + ) : false, }; } @@ -182,22 +182,3 @@ function calcFieldsState( return fieldsState; } - -function getUnacceptedConflictsCount( - ruleFieldsDiff: FieldsDiff>, - ruleResolvedConflicts: RuleResolvedConflicts -): number { - const fieldNames = Object.keys(ruleFieldsDiff); - const fieldNamesWithConflict = fieldNames.filter( - (fieldName) => ruleFieldsDiff[fieldName].conflict !== ThreeWayDiffConflict.NONE - ); - const fieldNamesWithConflictSet = new Set(fieldNamesWithConflict); - - for (const resolvedConflictField of Object.keys(ruleResolvedConflicts)) { - if (fieldNamesWithConflictSet.has(resolvedConflictField)) { - fieldNamesWithConflictSet.delete(resolvedConflictField); - } - } - - return fieldNamesWithConflictSet.size; -} From 49d56c0b3f161e5d7a15a138db88125ecb5b5b0f Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 3 Dec 2024 13:48:14 +0100 Subject: [PATCH 32/77] improve calcCustomizableFieldsDiff implementation --- .../upgrade_prebuilt_rules_table.tsx | 7 +- .../upgrade_prebuilt_rules_table_context.tsx | 2 +- .../use_prebuilt_rules_upgrade_state.ts | 27 +++--- .../use_rule_preview_flyout.tsx | 87 ------------------- 4 files changed, 20 insertions(+), 103 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rules_preview_flyout/use_rule_preview_flyout.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table.tsx index 2437a5e87866d..5c33ec46d96e0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table.tsx @@ -38,9 +38,6 @@ const NO_ITEMS_MESSAGE = ( * Table Component for displaying rules that have available updates */ export const UpgradePrebuiltRulesTable = React.memo(() => { - const upgradeRulesTableContext = useUpgradePrebuiltRulesTableContext(); - const [selected, setSelected] = useState([]); - const { state: { rulesUpgradeState, @@ -49,7 +46,9 @@ export const UpgradePrebuiltRulesTable = React.memo(() => { isRefetching, isUpgradingSecurityPackages, }, - } = upgradeRulesTableContext; + } = useUpgradePrebuiltRulesTableContext(); + const [selected, setSelected] = useState([]); + const ruleUpgradeStatesArray = useMemo( () => Object.values(rulesUpgradeState), [rulesUpgradeState] diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx index 5b18dd68776ff..0364a1ac01f13 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx @@ -32,7 +32,7 @@ import { usePrebuiltRulesUpgradeReview } from '../../../../rule_management/logic import { RuleDiffTab } from '../../../../rule_management/components/rule_details/rule_diff_tab'; import { FieldUpgradeState } from '../../../../rule_management/model/prebuilt_rule_upgrade/field_upgrade_state'; import { isNonUpgradeableFieldName } from '../../../../rule_management/model/prebuilt_rule_upgrade/fields'; -import { useRulePreviewFlyout } from '../use_rules_preview_flyout/use_rule_preview_flyout'; +import { useRulePreviewFlyout } from '../use_rule_preview_flyout'; import { MlJobUpgradeModal } from './modals/ml_job_upgrade_modal'; import { UpgradeConflictsModal } from './modals/upgrade_conflicts_modal'; import type { UpgradePrebuiltRulesTableFilterOptions } from './use_filter_prebuilt_rules_to_upgrade'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts index 0dc428ee33460..e4fbaa87aeea9 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts @@ -6,7 +6,6 @@ */ import { useCallback, useMemo, useState } from 'react'; -import { pick } from 'lodash'; import { useIsPrebuiltRulesCustomizationEnabled } from '../../../../rule_management/hooks/use_is_prebuilt_rules_customization_enabled'; import type { RulesUpgradeState, @@ -14,7 +13,10 @@ import type { SetRuleFieldResolvedValueFn, } from '../../../../rule_management/model/prebuilt_rule_upgrade'; import { FieldUpgradeState } from '../../../../rule_management/model/prebuilt_rule_upgrade'; -import type { PartialRuleDiff } from '../../../../../../common/api/detection_engine'; +import type { + PartialRuleDiff, + RuleFieldsDiff, +} from '../../../../../../common/api/detection_engine'; import { type FieldsDiff, type DiffableAllFields, @@ -90,25 +92,28 @@ export function usePrebuiltRulesUpgradeState( } function calcCustomizableFieldsDiff(ruleFieldsDiff: PartialRuleDiff): PartialRuleDiff { - const cutomizableFieldNames = Object.keys(ruleFieldsDiff.fields).filter( - (fieldName) => !NON_UPGRADEABLE_DIFFABLE_FIELDS.includes(fieldName) - ); - const fieldsDiff = pick(ruleFieldsDiff.fields, cutomizableFieldNames); - + const fieldsDiff: Partial = {}; let numFieldsWithUpdates = 0; let numFieldsWithConflicts = 0; let numFieldsWithNonSolvableConflicts = 0; - for (const fieldDiff of Object.values(fieldsDiff)) { - if (fieldDiff.has_update) { + for (const [fieldName, diff] of Object.entries(ruleFieldsDiff.fields)) { + if (NON_UPGRADEABLE_DIFFABLE_FIELDS.includes(fieldName)) { + // eslint-disable-next-line no-continue + continue; + } + + fieldsDiff[fieldName as keyof RuleFieldsDiff] = diff; + + if (diff.has_update) { numFieldsWithUpdates++; } - if (fieldDiff.conflict !== ThreeWayDiffConflict.NONE) { + if (diff.conflict !== ThreeWayDiffConflict.NONE) { numFieldsWithConflicts++; } - if (fieldDiff.conflict === ThreeWayDiffConflict.NON_SOLVABLE) { + if (diff.conflict === ThreeWayDiffConflict.NON_SOLVABLE) { numFieldsWithNonSolvableConflicts++; } } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rules_preview_flyout/use_rule_preview_flyout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rules_preview_flyout/use_rule_preview_flyout.tsx deleted file mode 100644 index 53054b5c3403d..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rules_preview_flyout/use_rule_preview_flyout.tsx +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { ReactNode } from 'react'; -import React, { useCallback, useState, useMemo } from 'react'; -import type { EuiTabbedContentTab } from '@elastic/eui'; -import { invariant } from '../../../../../../common/utils/invariant'; -import type { RuleSignatureId } from '../../../../../../common/api/detection_engine'; -import { RuleDetailsFlyout } from '../../../../rule_management/components/rule_details/rule_details_flyout'; - -interface RuleLike { - rule_id: RuleSignatureId; -} - -interface UseRulePreviewFlyoutParams { - rules: T[]; - ruleActionsFactory: (rule: T, closeRulePreview: () => void) => ReactNode; - extraTabsFactory?: (rule: T) => EuiTabbedContentTab[]; - subHeaderFactory?: (rule: T) => ReactNode; - flyoutProps: RulePreviewFlyoutProps; -} - -interface RulePreviewFlyoutProps { - /** - * Rule preview flyout unique id used in HTML - */ - id: string; - dataTestSubj: string; -} - -interface UseRulePreviewFlyoutResult { - rulePreviewFlyout: ReactNode; - openRulePreview: (ruleId: RuleSignatureId) => void; - closeRulePreview: () => void; -} - -export function useRulePreviewFlyout({ - rules, - extraTabsFactory, - ruleActionsFactory, - subHeaderFactory, - flyoutProps, -}: UseRulePreviewFlyoutParams): UseRulePreviewFlyoutResult { - const [rule, setRuleForPreview] = useState(); - const closeRulePreview = useCallback(() => setRuleForPreview(undefined), []); - const subHeader = useMemo( - () => (rule ? subHeaderFactory?.(rule) : null), - [subHeaderFactory, rule] - ); - const ruleActions = useMemo( - () => rule && ruleActionsFactory(rule, closeRulePreview), - [rule, ruleActionsFactory, closeRulePreview] - ); - const extraTabs = useMemo( - () => (rule && extraTabsFactory ? extraTabsFactory(rule) : []), - [rule, extraTabsFactory] - ); - - return { - rulePreviewFlyout: rule && ( - - ), - openRulePreview: useCallback( - (ruleId: RuleSignatureId) => { - const ruleToShowInFlyout = rules.find((x) => x.rule_id === ruleId); - - invariant(ruleToShowInFlyout, `Rule with rule_id ${ruleId} not found`); - setRuleForPreview(ruleToShowInFlyout); - }, - [rules, setRuleForPreview] - ), - closeRulePreview, - }; -} From 2d1ae44480357312b1c4b9bfbb3a86328de0a52f Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 3 Dec 2024 16:12:58 +0100 Subject: [PATCH 33/77] update field modified condition --- .../three_way_diff/rule_upgrade/field_upgrade.tsx | 4 +--- .../use_prebuilt_rules_upgrade_state.ts | 4 +++- 2 files changed, 4 insertions(+), 4 deletions(-) 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 04ddb1bd6a52e..5f99434979ae5 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 @@ -22,9 +22,7 @@ export function FieldUpgrade(): JSX.Element { const hasConflict = fieldDiff.conflict !== ThreeWayDiffConflict.NONE; const isFieldCustomized = useMemo( () => - fieldDiff.has_base_version - ? !isEqual(fieldDiff.base_version, fieldDiff.current_version) - : false, + fieldDiff.base_version ? !isEqual(fieldDiff.base_version, fieldDiff.current_version) : false, [fieldDiff] ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts index e4fbaa87aeea9..23b23c413bc9a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts @@ -76,7 +76,9 @@ export function usePrebuiltRulesUpgradeState( fieldsUpgradeState, hasUnresolvedConflicts: isPrebuiltRulesCustomizationEnabled ? Object.values(fieldsUpgradeState).some( - (x) => x !== FieldUpgradeState.NoConflict && x !== FieldUpgradeState.Accepted + (x) => + x === FieldUpgradeState.SolvableConflict || + x === FieldUpgradeState.NonSolvableConflict ) : false, }; From 5ef654c0e56a10a3388fc16b8d1957c4b185d0cc Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 3 Dec 2024 17:26:37 +0100 Subject: [PATCH 34/77] add dynamically updating rule upgrade state --- .../rule_upgrade/rule_upgrade_info_bar.tsx | 26 ++++++++++++++++--- .../rule_upgrade/translations.tsx | 14 +++++++--- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx index 9c6f34aafff0a..e53bd52f90750 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx @@ -5,8 +5,8 @@ * 2.0. */ -import React from 'react'; -import type { RuleUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; +import React, { useMemo } from 'react'; +import { FieldUpgradeState, type RuleUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { UtilityBar, UtilityBarGroup, @@ -21,7 +21,20 @@ interface UpgradeInfoBarProps { export function RuleUpgradeInfoBar({ ruleUpgradeState }: UpgradeInfoBarProps): JSX.Element { const numOfFieldsWithUpdates = ruleUpgradeState.customizableFieldsDiff.num_fields_with_updates; - const numOfConflicts = ruleUpgradeState.customizableFieldsDiff.num_fields_with_conflicts; + const numOfSolvedConflicts = useMemo( + () => + Object.values(ruleUpgradeState.fieldsUpgradeState).filter( + (x) => x === FieldUpgradeState.SolvableConflict + ).length, + [ruleUpgradeState.fieldsUpgradeState] + ); + const numOfUnsolvedConflicts = useMemo( + () => + Object.values(ruleUpgradeState.fieldsUpgradeState).filter( + (x) => x === FieldUpgradeState.NonSolvableConflict + ).length, + [ruleUpgradeState.fieldsUpgradeState] + ); return ( @@ -33,7 +46,12 @@ export function RuleUpgradeInfoBar({ ruleUpgradeState }: UpgradeInfoBarProps): J - {i18n.NUM_OF_CONFLICTS(numOfConflicts)} + {i18n.NUM_OF_SOLVED_CONFLICTS(numOfSolvedConflicts)} + + + + + {i18n.NUM_OF_UNSOLVED_CONFLICTS(numOfUnsolvedConflicts)} 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 d93cdfccad3ec..aae8b45f47b23 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 @@ -19,10 +19,18 @@ export const NUM_OF_FIELDS_WITH_UPDATES = (count: number) => ( /> ); -export const NUM_OF_CONFLICTS = (count: number) => ( +export const NUM_OF_SOLVED_CONFLICTS = (count: number) => ( {count} }} + /> +); + +export const NUM_OF_UNSOLVED_CONFLICTS = (count: number) => ( + {count} }} /> ); From 63d8f7bc7193e9b72ab7666e1e72340b6ed50bd2 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 3 Dec 2024 21:59:11 +0100 Subject: [PATCH 35/77] delay unnecessary calculations until rule upgrade flyout is shown --- .../perform_rule_upgrade_route.ts | 2 +- .../rule_upgrade/field_upgrade_context.tsx | 46 +++++++- .../rule_upgrade/rule_upgrade.tsx | 45 +++++++- .../rule_upgrade/rule_upgrade_callout.tsx | 27 ++--- .../rule_upgrade/rule_upgrade_info_bar.tsx | 35 ++---- .../fields_upgrade_state.ts | 8 +- .../rule_upgrade_state.ts | 18 +-- .../upgrade_flyout_subheader.tsx | 9 +- .../upgrade_prebuilt_rules_table_context.tsx | 17 +-- .../use_prebuilt_rules_upgrade_state.ts | 106 ++++-------------- 10 files changed, 142 insertions(+), 171 deletions(-) diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_upgrade/perform_rule_upgrade_route.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_upgrade/perform_rule_upgrade_route.ts index 9908193705243..0021aece67455 100644 --- a/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_upgrade/perform_rule_upgrade_route.ts +++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_upgrade/perform_rule_upgrade_route.ts @@ -50,7 +50,7 @@ export const FIELDS_TO_UPGRADE_TO_TARGET_VERSION = [ // Fields which are part of DiffableRule but are not upgradeable // and need to be omittted from the DiffableUpgradableFields -export const NON_UPGRADEABLE_DIFFABLE_FIELDS: Readonly = ['type', 'rule_id', 'version']; +export const NON_UPGRADEABLE_DIFFABLE_FIELDS = ['type', 'rule_id', 'version'] as const; type NON_UPGRADEABLE_DIFFABLE_FIELDS_TO_OMIT_TYPE = { readonly [key in (typeof NON_UPGRADEABLE_DIFFABLE_FIELDS)[number]]: true; 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 407809484a951..92170d057828e 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,8 +7,13 @@ import React, { createContext, useContext, useMemo } from 'react'; import { useBoolean } from '@kbn/react-hooks'; -import type { DiffableRule, ThreeWayDiff } from '../../../../../../../common/api/detection_engine'; +import type { + DiffableRule, + FieldsDiff, + 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'; import type { SetRuleFieldResolvedValueFn } from '../../../../model/prebuilt_rule_upgrade/set_rule_field_resolved_value'; import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; import type { RuleUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; @@ -69,7 +74,7 @@ export function FieldUpgradeContextProvider({ setRuleFieldResolvedValue, children, }: FieldUpgradeContextProviderProps) { - const fieldUpgradeState = ruleUpgradeState.fieldsUpgradeState[fieldName]; + const { state: fieldUpgradeState } = ruleUpgradeState.fieldsUpgradeState[fieldName]; const fieldDiff = ruleUpgradeState.diff.fields[fieldName]; const initialRightSideMode = fieldUpgradeState === FieldUpgradeState.NonSolvableConflict @@ -89,7 +94,7 @@ export function FieldUpgradeContextProvider({ fieldName, fieldUpgradeState, fieldDiff, - finalDiffableRule: ruleUpgradeState.finalRule, + finalDiffableRule: calcFinalDiffableRule(ruleUpgradeState), rightSideMode: editing ? FieldFinalSideMode.Edit : FieldFinalSideMode.Readonly, setRuleFieldResolvedValue, setReadOnlyMode, @@ -99,7 +104,7 @@ export function FieldUpgradeContextProvider({ fieldName, fieldUpgradeState, fieldDiff, - ruleUpgradeState.finalRule, + ruleUpgradeState, editing, setRuleFieldResolvedValue, setReadOnlyMode, @@ -122,3 +127,36 @@ export function useFieldUpgradeContext() { return context; } + +function calcFinalDiffableRule(ruleUpgradeState: RuleUpgradeState): DiffableRule { + const fieldsResolvedValues = Object.entries(ruleUpgradeState.fieldsUpgradeState).reduce< + Record + >((result, [fieldName, fieldState]) => { + if (fieldState.state === FieldUpgradeState.Accepted && Boolean(fieldState.resolvedValue)) { + result[fieldName] = fieldState.resolvedValue; + } + + return result; + }, {}); + + return { + ...convertRuleToDiffable(ruleUpgradeState.target_rule), + ...convertRuleFieldsDiffToDiffable(ruleUpgradeState.diff.fields), + ...fieldsResolvedValues, + } as DiffableRule; +} + +/** + * Assembles a `DiffableRule` from rule fields diff `merged_version`s. + */ +function convertRuleFieldsDiffToDiffable( + ruleFieldsDiff: FieldsDiff> +): Partial { + const mergeVersionRule: Record = {}; + + for (const fieldName of Object.keys(ruleFieldsDiff)) { + mergeVersionRule[fieldName] = ruleFieldsDiff[fieldName].merged_version; + } + + return mergeVersionRule; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx index c8fc36cc75f5c..d02787de12e3f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx @@ -7,9 +7,11 @@ import React, { memo } from 'react'; import { EuiSpacer } from '@elastic/eui'; -import type { - RuleUpgradeState, - SetRuleFieldResolvedValueFn, +import type { ThreeWayDiff } from '../../../../../../../common/api/detection_engine'; +import { + FieldUpgradeState, + type RuleUpgradeState, + type SetRuleFieldResolvedValueFn, } from '../../../../model/prebuilt_rule_upgrade'; import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; import { RuleUpgradeInfoBar } from './rule_upgrade_info_bar'; @@ -26,6 +28,9 @@ export const RuleUpgrade = memo(function RuleUpgrade({ ruleUpgradeState, setRuleFieldResolvedValue, }: RuleUpgradeProps): JSX.Element { + const numOfFieldsWithUpdates = calcNumOfFieldsWithUpdates(ruleUpgradeState); + const numOfSolvableConflicts = calcNumOfSolvableConflicts(ruleUpgradeState); + const numOfNonSolvableConflicts = calcNumOfNonSolvableConflicts(ruleUpgradeState); const fieldNames = Object.keys( ruleUpgradeState.fieldsUpgradeState ) as UpgradeableDiffableFields[]; @@ -33,9 +38,16 @@ export const RuleUpgrade = memo(function RuleUpgrade({ return ( <> - + - + {fieldNames.map((fieldName) => ( ); }); + +function calcNumOfFieldsWithUpdates(ruleUpgradeState: RuleUpgradeState): number { + const fieldsDiffEntries: Array<[string, ThreeWayDiff]> = Object.entries( + ruleUpgradeState.diff.fields + ); + const fieldsUpgradeState = ruleUpgradeState.fieldsUpgradeState; + + return fieldsDiffEntries.filter( + ([fieldName, fieldDiff]) => Boolean(fieldsUpgradeState[fieldName]) && fieldDiff.has_update + ).length; +} + +function calcNumOfSolvableConflicts(ruleUpgradeState: RuleUpgradeState): number { + return Object.values(ruleUpgradeState.fieldsUpgradeState).filter( + ({ state }) => state === FieldUpgradeState.SolvableConflict + ).length; +} + +function calcNumOfNonSolvableConflicts(ruleUpgradeState: RuleUpgradeState): number { + return Object.values(ruleUpgradeState.fieldsUpgradeState).filter( + ({ state }) => state === FieldUpgradeState.NonSolvableConflict + ).length; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx index e3204c6028eed..51bc8ed76f5a5 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx @@ -5,35 +5,22 @@ * 2.0. */ -import React, { useMemo } from 'react'; +import React from 'react'; import { EuiCallOut } from '@elastic/eui'; -import { FieldUpgradeState, type RuleUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { ActionRequiredBadge } from '../badges/action_required'; import { ReviewRequiredBadge } from '../badges/review_required_badge'; import { ReadyForUpgradeBadge } from '../badges/ready_for_upgrade_badge'; import * as i18n from './translations'; interface RuleUpgradeCalloutProps { - ruleUpgradeState: RuleUpgradeState; + numOfSolvableConflicts: number; + numOfNonSolvableConflicts: number; } -export function RuleUpgradeCallout({ ruleUpgradeState }: RuleUpgradeCalloutProps): JSX.Element { - const fieldsUpgradeState = ruleUpgradeState.fieldsUpgradeState; - const [numOfNonSolvableConflicts, numOfSolvableConflicts] = useMemo(() => { - let nonSolvableConflicts = 0; - let solvableConflicts = 0; - - for (const state of Object.values(fieldsUpgradeState)) { - if (state === FieldUpgradeState.NonSolvableConflict) { - nonSolvableConflicts++; - } else if (state === FieldUpgradeState.SolvableConflict) { - solvableConflicts++; - } - } - - return [nonSolvableConflicts, solvableConflicts]; - }, [fieldsUpgradeState]); - +export function RuleUpgradeCallout({ + numOfSolvableConflicts, + numOfNonSolvableConflicts, +}: RuleUpgradeCalloutProps): JSX.Element { if (numOfNonSolvableConflicts > 0) { return ( - Object.values(ruleUpgradeState.fieldsUpgradeState).filter( - (x) => x === FieldUpgradeState.SolvableConflict - ).length, - [ruleUpgradeState.fieldsUpgradeState] - ); - const numOfUnsolvedConflicts = useMemo( - () => - Object.values(ruleUpgradeState.fieldsUpgradeState).filter( - (x) => x === FieldUpgradeState.NonSolvableConflict - ).length, - [ruleUpgradeState.fieldsUpgradeState] - ); - +export function RuleUpgradeInfoBar({ + numOfFieldsWithUpdates, + numOfSolvableConflicts, + numOfNonSolvableConflicts, +}: RuleUpgradeInfoBarProps): JSX.Element { return ( @@ -46,12 +35,12 @@ export function RuleUpgradeInfoBar({ ruleUpgradeState }: UpgradeInfoBarProps): J - {i18n.NUM_OF_SOLVED_CONFLICTS(numOfSolvedConflicts)} + {i18n.NUM_OF_SOLVED_CONFLICTS(numOfSolvableConflicts)} - {i18n.NUM_OF_UNSOLVED_CONFLICTS(numOfUnsolvedConflicts)} + {i18n.NUM_OF_UNSOLVED_CONFLICTS(numOfNonSolvableConflicts)} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/fields_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/fields_upgrade_state.ts index fb18061067ff8..36015470e96d2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/fields_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/fields_upgrade_state.ts @@ -7,4 +7,10 @@ import type { FieldUpgradeState } from './field_upgrade_state'; -export type FieldsUpgradeState = Record; +export type FieldsUpgradeState = Record< + string, + | { + state: Exclude; + } + | { state: FieldUpgradeState.Accepted; resolvedValue: unknown } +>; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/rule_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/rule_upgrade_state.ts index 8bb38cbf476f0..7cd1f9c9ef843 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/rule_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/rule_upgrade_state.ts @@ -5,28 +5,16 @@ * 2.0. */ -import type { PartialRuleDiff } from '../../../../../common/api/detection_engine'; -import { - type DiffableRule, - type RuleUpgradeInfoForReview, -} from '../../../../../common/api/detection_engine'; +import { type RuleUpgradeInfoForReview } from '../../../../../common/api/detection_engine'; import type { FieldsUpgradeState } from './fields_upgrade_state'; export interface RuleUpgradeState extends RuleUpgradeInfoForReview { /** - * Rule containing desired values users expect to see in the upgraded rule. - */ - finalRule: DiffableRule; - /** - * Customizable fields diff. It's the same as diff but doesn't contain non customizable fields like `version`. + * Stores a record of customizable field names mapped to field upgrade state. */ - customizableFieldsDiff: PartialRuleDiff; + fieldsUpgradeState: FieldsUpgradeState; /** * Indicates whether there are conflicts blocking rule upgrading. */ hasUnresolvedConflicts: boolean; - /** - * Stores a record of customizable field names mapped to field upgrade state. - */ - fieldsUpgradeState: FieldsUpgradeState; } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx index bc004db92debc..26f6a72b12085 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx @@ -8,6 +8,7 @@ import React, { memo } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui'; import { camelCase, startCase } from 'lodash'; +import type { FieldsDiff } from '../../../../../../common/api/detection_engine'; import { FormattedDate } from '../../../../../common/components/formatted_date'; import { SeverityBadge } from '../../../../../common/components/severity_badge'; import { ModifiedBadge } from '../../../../rule_management/components/rule_details/three_way_diff/badges/modified_badge'; @@ -50,10 +51,10 @@ export const UpgradeFlyoutSubHeader = memo(function UpgradeFlyoutSubHeader({ const customized = ruleUpgradeState.current_rule.rule_source.type === 'external' && ruleUpgradeState.current_rule.rule_source.is_customized && ; - const fieldsNamesWithUpdates = Object.entries(ruleUpgradeState.customizableFieldsDiff.fields) - .filter(([, diff]) => diff.has_update) - .map(([fieldName]) => fieldName); - + const fieldsDiff: FieldsDiff> = ruleUpgradeState.diff.fields; + const fieldsNamesWithUpdates = Object.keys(ruleUpgradeState.fieldsUpgradeState).filter( + (fieldName) => fieldsDiff[fieldName].has_update + ); const fieldUpdates = fieldsNamesWithUpdates.length > 0 && ( diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx index 0364a1ac01f13..422002a47056a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx @@ -31,7 +31,6 @@ import { usePerformUpgradeSpecificRules } from '../../../../rule_management/logi import { usePrebuiltRulesUpgradeReview } from '../../../../rule_management/logic/prebuilt_rules/use_prebuilt_rules_upgrade_review'; import { RuleDiffTab } from '../../../../rule_management/components/rule_details/rule_diff_tab'; import { FieldUpgradeState } from '../../../../rule_management/model/prebuilt_rule_upgrade/field_upgrade_state'; -import { isNonUpgradeableFieldName } from '../../../../rule_management/model/prebuilt_rule_upgrade/fields'; import { useRulePreviewFlyout } from '../use_rule_preview_flyout'; import { MlJobUpgradeModal } from './modals/ml_job_upgrade_modal'; import { UpgradeConflictsModal } from './modals/upgrade_conflicts_modal'; @@ -468,21 +467,15 @@ export const useUpgradePrebuiltRulesTableContext = (): UpgradePrebuiltRulesConte }; function constructRuleFieldsToUpgrade(ruleUpgradeState: RuleUpgradeState): RuleFieldsToUpgrade { - const finalRule = ruleUpgradeState.finalRule as Record; const ruleFieldsToUpgrade: Record = {}; - for (const fieldName of Object.keys(ruleUpgradeState.fieldsUpgradeState)) { - const fieldUpgradeState = ruleUpgradeState.fieldsUpgradeState[fieldName]; - - if (!isNonUpgradeableFieldName(fieldName) && fieldUpgradeState === FieldUpgradeState.Accepted) { - invariant( - fieldName in finalRule, - `Ready to upgrade field "${fieldName}" is not found in final rule` - ); - + for (const [fieldName, fieldUpgradeState] of Object.entries( + ruleUpgradeState.fieldsUpgradeState + )) { + if (fieldUpgradeState.state === FieldUpgradeState.Accepted) { ruleFieldsToUpgrade[fieldName] = { pick_version: 'RESOLVED', - resolved_value: finalRule[fieldName], + resolved_value: fieldUpgradeState.resolvedValue, }; } } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts index 23b23c413bc9a..d0d58336c1bae 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts @@ -13,20 +13,14 @@ import type { SetRuleFieldResolvedValueFn, } from '../../../../rule_management/model/prebuilt_rule_upgrade'; import { FieldUpgradeState } from '../../../../rule_management/model/prebuilt_rule_upgrade'; -import type { - PartialRuleDiff, - RuleFieldsDiff, -} from '../../../../../../common/api/detection_engine'; import { type FieldsDiff, type DiffableAllFields, - type DiffableRule, type RuleUpgradeInfoForReview, ThreeWayDiffConflict, type RuleSignatureId, NON_UPGRADEABLE_DIFFABLE_FIELDS, } from '../../../../../../common/api/detection_engine'; -import { convertRuleToDiffable } from '../../../../../../common/detection_engine/prebuilt_rules/diff/convert_rule_to_diffable'; import { assertUnreachable } from '../../../../../../common/utility_types'; type RuleResolvedConflicts = Partial; @@ -60,25 +54,19 @@ export function usePrebuiltRulesUpgradeState( const state: RulesUpgradeState = {}; for (const ruleUpgradeInfo of ruleUpgradeInfos) { - const customizableFieldsDiff = calcCustomizableFieldsDiff(ruleUpgradeInfo.diff); const fieldsUpgradeState = calcFieldsState( - customizableFieldsDiff, + ruleUpgradeInfo.diff.fields, rulesResolvedConflicts[ruleUpgradeInfo.rule_id] ?? {} ); state[ruleUpgradeInfo.rule_id] = { ...ruleUpgradeInfo, - customizableFieldsDiff, - finalRule: calcFinalDiffableRule( - ruleUpgradeInfo, - rulesResolvedConflicts[ruleUpgradeInfo.rule_id] ?? {} - ), fieldsUpgradeState, hasUnresolvedConflicts: isPrebuiltRulesCustomizationEnabled ? Object.values(fieldsUpgradeState).some( - (x) => - x === FieldUpgradeState.SolvableConflict || - x === FieldUpgradeState.NonSolvableConflict + ({ state: fieldState }) => + fieldState === FieldUpgradeState.SolvableConflict || + fieldState === FieldUpgradeState.NonSolvableConflict ) : false, }; @@ -93,89 +81,35 @@ export function usePrebuiltRulesUpgradeState( }; } -function calcCustomizableFieldsDiff(ruleFieldsDiff: PartialRuleDiff): PartialRuleDiff { - const fieldsDiff: Partial = {}; - let numFieldsWithUpdates = 0; - let numFieldsWithConflicts = 0; - let numFieldsWithNonSolvableConflicts = 0; - - for (const [fieldName, diff] of Object.entries(ruleFieldsDiff.fields)) { - if (NON_UPGRADEABLE_DIFFABLE_FIELDS.includes(fieldName)) { - // eslint-disable-next-line no-continue - continue; - } - - fieldsDiff[fieldName as keyof RuleFieldsDiff] = diff; - - if (diff.has_update) { - numFieldsWithUpdates++; - } - - if (diff.conflict !== ThreeWayDiffConflict.NONE) { - numFieldsWithConflicts++; - } - - if (diff.conflict === ThreeWayDiffConflict.NON_SOLVABLE) { - numFieldsWithNonSolvableConflicts++; - } - } - - return { - num_fields_with_updates: numFieldsWithUpdates, - num_fields_with_conflicts: numFieldsWithConflicts, - num_fields_with_non_solvable_conflicts: numFieldsWithNonSolvableConflicts, - fields: fieldsDiff, - }; -} - -function calcFinalDiffableRule( - ruleUpgradeInfo: RuleUpgradeInfoForReview, - ruleResolvedConflicts: RuleResolvedConflicts -): DiffableRule { - return { - ...convertRuleToDiffable(ruleUpgradeInfo.target_rule), - ...convertRuleFieldsDiffToDiffable(ruleUpgradeInfo.diff.fields), - ...ruleResolvedConflicts, - } as DiffableRule; -} - -/** - * Assembles a `DiffableRule` from rule fields diff `merged_version`s. - */ -function convertRuleFieldsDiffToDiffable( - ruleFieldsDiff: FieldsDiff> -): Partial { - const mergeVersionRule: Record = {}; - - for (const fieldName of Object.keys(ruleFieldsDiff)) { - mergeVersionRule[fieldName] = ruleFieldsDiff[fieldName].merged_version; - } - - return mergeVersionRule; -} +const NON_UPGRADEABLE_DIFFABLE_FIELDS_SET: Readonly> = new Set( + NON_UPGRADEABLE_DIFFABLE_FIELDS +); function calcFieldsState( - ruleDiff: PartialRuleDiff, + fieldsDiff: FieldsDiff>, ruleResolvedConflicts: RuleResolvedConflicts ): FieldsUpgradeState { const fieldsState: FieldsUpgradeState = {}; - for (const fieldName of Object.keys(ruleDiff.fields)) { - const conflict = - ruleDiff.fields[fieldName as keyof typeof ruleDiff.fields]?.conflict ?? - ThreeWayDiffConflict.NONE; + for (const fieldName of Object.keys(fieldsDiff)) { + if (NON_UPGRADEABLE_DIFFABLE_FIELDS_SET.has(fieldName)) { + // eslint-disable-next-line no-continue + continue; + } + + const conflict = fieldsDiff[fieldName]?.conflict ?? ThreeWayDiffConflict.NONE; switch (conflict) { case ThreeWayDiffConflict.NONE: - fieldsState[fieldName] = FieldUpgradeState.NoConflict; + fieldsState[fieldName] = { state: FieldUpgradeState.NoConflict }; break; case ThreeWayDiffConflict.SOLVABLE: - fieldsState[fieldName] = FieldUpgradeState.SolvableConflict; + fieldsState[fieldName] = { state: FieldUpgradeState.SolvableConflict }; break; case ThreeWayDiffConflict.NON_SOLVABLE: - fieldsState[fieldName] = FieldUpgradeState.NonSolvableConflict; + fieldsState[fieldName] = { state: FieldUpgradeState.NonSolvableConflict }; break; default: @@ -183,8 +117,8 @@ function calcFieldsState( } } - for (const fieldName of Object.keys(ruleResolvedConflicts)) { - fieldsState[fieldName] = FieldUpgradeState.Accepted; + for (const [fieldName, resolvedValue] of Object.entries(ruleResolvedConflicts)) { + fieldsState[fieldName] = { state: FieldUpgradeState.Accepted, resolvedValue }; } return fieldsState; From 0865ee24674113bbf358847b9c4866cbd9c281ea Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 3 Dec 2024 22:07:32 +0100 Subject: [PATCH 36/77] fix an icon --- .../field_final_side/components/field_final_side_content.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_content.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_content.tsx index 69452c2d4aab2..66fcee8547d7f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_content.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_content.tsx @@ -35,7 +35,7 @@ export function FieldFinalSideContent(): JSX.Element { return ( <> - + {i18n.CANCEL} From 9062b5618a211e83a7315a2face9e66e632dbff4 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 3 Dec 2024 22:11:35 +0100 Subject: [PATCH 37/77] fix hasRulesToUpgrade calculation --- .../upgrade_prebuilt_rules_table_context.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx index 422002a47056a..dba628690a8ff 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx @@ -404,7 +404,7 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ () => ({ state: { rulesUpgradeState, - hasRulesToUpgrade: isFetched && Object.keys(rulesUpgradeState).length > 0, + hasRulesToUpgrade: isFetched && ruleUpgradeInfos.length > 0, filterOptions, tags, isFetched, @@ -418,6 +418,7 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ actions, }), [ + ruleUpgradeInfos.length, rulesUpgradeState, filterOptions, tags, From 1f6b254696bb8967c3b54ad455224d6106009d2a Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Wed, 4 Dec 2024 12:02:59 +0100 Subject: [PATCH 38/77] remove unused translation keys --- .../plugins/private/translations/translations/fr-FR.json | 1 - .../plugins/private/translations/translations/ja-JP.json | 1 - .../plugins/private/translations/translations/zh-CN.json | 1 - 3 files changed, 3 deletions(-) diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index a7773bc59ee7c..fa24fbf2822f6 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -39083,7 +39083,6 @@ "xpack.securitySolution.detectionEngine.rules.upgradeRules.currentVersionDescriptionLabel": "Affiche la règle actuellement installée", "xpack.securitySolution.detectionEngine.rules.upgradeRules.currentVersionLabel": "Règle actuelle", "xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.fieldsWithUpdates": "La mise à niveau contient {count} {count, plural, one {champ} other {champs}}", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.numOfConflicts": "{count} {count, plural, one {conflit} other {conflits}}", "xpack.securitySolution.detectionEngine.rules.upgradeRules.editButtonLabel": "Modifier", "xpack.securitySolution.detectionEngine.rules.upgradeRules.elasticUpdateVersionLabel": "Mise à jour Elastic", "xpack.securitySolution.detectionEngine.rules.upgradeRules.expandHiddenDiffLinesLabel": "Développer {linesCount}{linesCount, plural, one {ligne} other {lignes}}", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index 464f021624699..71a2046c98a6d 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -38940,7 +38940,6 @@ "xpack.securitySolution.detectionEngine.rules.upgradeRules.currentVersionDescriptionLabel": "現在インストールされているルールを表示します", "xpack.securitySolution.detectionEngine.rules.upgradeRules.currentVersionLabel": "現在のルール", "xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.fieldsWithUpdates": "アップグレードには{count} {count, plural, other {個のフィールド}}があります", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.numOfConflicts": "{count} {count, plural, other {件の競合}}", "xpack.securitySolution.detectionEngine.rules.upgradeRules.editButtonLabel": "編集", "xpack.securitySolution.detectionEngine.rules.upgradeRules.elasticUpdateVersionLabel": "Elastic更新", "xpack.securitySolution.detectionEngine.rules.upgradeRules.expandHiddenDiffLinesLabel": "変更されていない{linesCount} {linesCount, plural, other {行}}を展開", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index 86b67d3c4ad34..7e41afcd75b3a 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -38364,7 +38364,6 @@ "xpack.securitySolution.detectionEngine.rules.upgradeRules.currentVersionDescriptionLabel": "显示当前安装的规则", "xpack.securitySolution.detectionEngine.rules.upgradeRules.currentVersionLabel": "当前规则", "xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.fieldsWithUpdates": "升级包含 {count} 个{count, plural, other {字段}}", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.numOfConflicts": "{count} 个{count, plural, other {冲突}}", "xpack.securitySolution.detectionEngine.rules.upgradeRules.editButtonLabel": "编辑", "xpack.securitySolution.detectionEngine.rules.upgradeRules.elasticUpdateVersionLabel": "Elastic 更新", "xpack.securitySolution.detectionEngine.rules.upgradeRules.expandHiddenDiffLinesLabel": "展开 {linesCount} 个未更改的{linesCount, plural, other {行}}", From 2fd19e7e992dfd80f615460c47ac8efb99873ac5 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Wed, 4 Dec 2024 12:13:34 +0100 Subject: [PATCH 39/77] reduce unnecessary rulesUpgradeState recalculation --- .../upgrade_prebuilt_rules_table.tsx | 10 +++----- .../upgrade_prebuilt_rules_table_buttons.tsx | 4 ++-- .../upgrade_prebuilt_rules_table_context.tsx | 24 +++++++++---------- .../use_filter_prebuilt_rules_to_upgrade.ts | 23 +++++++++--------- 4 files changed, 28 insertions(+), 33 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table.tsx index 5c33ec46d96e0..623f36c5ebb1d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table.tsx @@ -15,7 +15,7 @@ import { EuiSkeletonText, EuiSkeletonTitle, } from '@elastic/eui'; -import React, { useMemo, useState } from 'react'; +import React, { useState } from 'react'; import type { RuleUpgradeState } from '../../../../rule_management/model/prebuilt_rule_upgrade'; import * as i18n from '../../../../../detections/pages/detection_engine/rules/translations'; import { RULES_TABLE_INITIAL_PAGE_SIZE, RULES_TABLE_PAGE_SIZE_OPTIONS } from '../constants'; @@ -40,7 +40,7 @@ const NO_ITEMS_MESSAGE = ( export const UpgradePrebuiltRulesTable = React.memo(() => { const { state: { - rulesUpgradeState, + ruleUpgradeStates, hasRulesToUpgrade, isLoading, isRefetching, @@ -49,10 +49,6 @@ export const UpgradePrebuiltRulesTable = React.memo(() => { } = useUpgradePrebuiltRulesTableContext(); const [selected, setSelected] = useState([]); - const ruleUpgradeStatesArray = useMemo( - () => Object.values(rulesUpgradeState), - [rulesUpgradeState] - ); const rulesColumns = useUpgradePrebuiltRulesTableColumns(); const shouldShowProgress = isUpgradingSecurityPackages || isRefetching; @@ -101,7 +97,7 @@ export const UpgradePrebuiltRulesTable = React.memo(() => { { const { state: { - rulesUpgradeState, + ruleUpgradeStates, hasRulesToUpgrade, loadingRules, isRefetching, @@ -38,7 +38,7 @@ export const UpgradePrebuiltRulesTableButtons = ({ const isRuleUpgrading = loadingRules.length > 0; const isRequestInProgress = isRuleUpgrading || isRefetching || isUpgradingSecurityPackages; - const everyFieldHasConflict = Object.values(rulesUpgradeState).every( + const everyFieldHasConflict = ruleUpgradeStates.every( ({ diff }) => diff.num_fields_with_conflicts > 0 ); const doAllSelectedRulesHaveConflicts = diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx index dba628690a8ff..33d20e847a238 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx @@ -14,10 +14,7 @@ import type { } from '../../../../../../common/api/detection_engine'; import { useIsPrebuiltRulesCustomizationEnabled } from '../../../../rule_management/hooks/use_is_prebuilt_rules_customization_enabled'; import { useAppToasts } from '../../../../../common/hooks/use_app_toasts'; -import type { - RuleUpgradeState, - RulesUpgradeState, -} from '../../../../rule_management/model/prebuilt_rule_upgrade'; +import type { RuleUpgradeState } from '../../../../rule_management/model/prebuilt_rule_upgrade'; import { RuleUpgradeTab } from '../../../../rule_management/components/rule_details/three_way_diff'; import { PerFieldRuleDiffTab } from '../../../../rule_management/components/rule_details/per_field_rule_diff_tab'; import { useIsUpgradingSecurityPackages } from '../../../../rule_management/logic/use_upgrade_security_packages'; @@ -47,7 +44,7 @@ export interface UpgradePrebuiltRulesTableState { /** * Rule upgrade state after applying `filterOptions` */ - rulesUpgradeState: RulesUpgradeState; + ruleUpgradeStates: RuleUpgradeState[]; /** * Currently selected table filter */ @@ -142,12 +139,13 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ refetchInterval: false, // Disable automatic refetching since request is expensive keepPreviousData: true, // Use this option so that the state doesn't jump between "success" and "loading" on page change }); - const filteredRuleUpgradeInfos = useFilterPrebuiltRulesToUpgrade({ + const { rulesUpgradeState, setRuleFieldResolvedValue } = + usePrebuiltRulesUpgradeState(ruleUpgradeInfos); + const ruleUpgradeStates = useMemo(() => Object.values(rulesUpgradeState), [rulesUpgradeState]); + const filteredRuleUpgradeStates = useFilterPrebuiltRulesToUpgrade({ filterOptions, - rules: ruleUpgradeInfos, + data: ruleUpgradeStates, }); - const { rulesUpgradeState, setRuleFieldResolvedValue } = - usePrebuiltRulesUpgradeState(filteredRuleUpgradeInfos); const { isVisible: isLegacyMLJobsModalVisible, @@ -375,8 +373,8 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ [rulesUpgradeState, setRuleFieldResolvedValue, isPrebuiltRulesCustomizationEnabled] ); const filteredRules = useMemo( - () => filteredRuleUpgradeInfos.map((rule) => rule.target_rule), - [filteredRuleUpgradeInfos] + () => filteredRuleUpgradeStates.map(({ target_rule: targetRule }) => targetRule), + [filteredRuleUpgradeStates] ); const { rulePreviewFlyout, openRulePreview } = useRulePreviewFlyout({ rules: filteredRules, @@ -403,7 +401,7 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ const providerValue = useMemo( () => ({ state: { - rulesUpgradeState, + ruleUpgradeStates: filteredRuleUpgradeStates, hasRulesToUpgrade: isFetched && ruleUpgradeInfos.length > 0, filterOptions, tags, @@ -419,7 +417,7 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ }), [ ruleUpgradeInfos.length, - rulesUpgradeState, + filteredRuleUpgradeStates, filterOptions, tags, isFetched, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_filter_prebuilt_rules_to_upgrade.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_filter_prebuilt_rules_to_upgrade.ts index b5a0e123d7510..eadc9b3b46d51 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_filter_prebuilt_rules_to_upgrade.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_filter_prebuilt_rules_to_upgrade.ts @@ -14,16 +14,19 @@ export type UpgradePrebuiltRulesTableFilterOptions = Pick< 'filter' | 'tags' | 'ruleSource' >; -export const useFilterPrebuiltRulesToUpgrade = ({ - rules, - filterOptions, -}: { - rules: RuleUpgradeInfoForReview[]; +interface UseFilterPrebuiltRulesToUpgradeParams { + data: T[]; filterOptions: UpgradePrebuiltRulesTableFilterOptions; -}) => { - const filteredRules = useMemo(() => { +} + +export const useFilterPrebuiltRulesToUpgrade = ({ + data, + filterOptions, +}: UseFilterPrebuiltRulesToUpgradeParams): T[] => { + return useMemo(() => { const { filter, tags, ruleSource } = filterOptions; - return rules.filter((ruleInfo) => { + + return data.filter((ruleInfo) => { if (filter && !ruleInfo.current_rule.name.toLowerCase().includes(filter.toLowerCase())) { return false; } @@ -53,7 +56,5 @@ export const useFilterPrebuiltRulesToUpgrade = ({ return true; }); - }, [filterOptions, rules]); - - return filteredRules; + }, [filterOptions, data]); }; From e158773898628ab9d14328d6b4a8725af7252d8b Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Wed, 4 Dec 2024 16:48:19 +0100 Subject: [PATCH 40/77] simplify modals implementation --- .../upgrade_prebuilt_rules_table_context.tsx | 41 ++++---------- .../use_ml_jobs_upgrade_modal/index.ts | 8 +++ .../ml_jobs_upgrade_modal.tsx} | 20 +++---- .../translations.tsx | 2 +- .../use_ml_jobs_upgrade_modal.tsx | 46 ++++++++++++++++ .../use_upgrade_modals.tsx | 53 ------------------- .../use_upgrade_with_conflicts_modal/index.ts | 8 +++ .../translations.tsx | 0 .../upgrade_modal.tsx} | 19 ++++--- .../use_upgrade_modal.tsx | 30 +++++++++++ 10 files changed, 122 insertions(+), 105 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_ml_jobs_upgrade_modal/index.ts rename x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/{modals/ml_job_upgrade_modal/index.tsx => use_ml_jobs_upgrade_modal/ml_jobs_upgrade_modal.tsx} (80%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/{modals/ml_job_upgrade_modal => use_ml_jobs_upgrade_modal}/translations.tsx (95%) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_ml_jobs_upgrade_modal/use_ml_jobs_upgrade_modal.tsx delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_modals.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_with_conflicts_modal/index.ts rename x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/{modals/upgrade_conflicts_modal => use_upgrade_with_conflicts_modal}/translations.tsx (100%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/{modals/upgrade_conflicts_modal/index.tsx => use_upgrade_with_conflicts_modal/upgrade_modal.tsx} (63%) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_with_conflicts_modal/use_upgrade_modal.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx index 33d20e847a238..07912b7ca21ed 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx @@ -29,12 +29,11 @@ import { usePrebuiltRulesUpgradeReview } from '../../../../rule_management/logic import { RuleDiffTab } from '../../../../rule_management/components/rule_details/rule_diff_tab'; import { FieldUpgradeState } from '../../../../rule_management/model/prebuilt_rule_upgrade/field_upgrade_state'; import { useRulePreviewFlyout } from '../use_rule_preview_flyout'; -import { MlJobUpgradeModal } from './modals/ml_job_upgrade_modal'; -import { UpgradeConflictsModal } from './modals/upgrade_conflicts_modal'; import type { UpgradePrebuiltRulesTableFilterOptions } from './use_filter_prebuilt_rules_to_upgrade'; import { useFilterPrebuiltRulesToUpgrade } from './use_filter_prebuilt_rules_to_upgrade'; import { usePrebuiltRulesUpgradeState } from './use_prebuilt_rules_upgrade_state'; -import { useMlJobUpgradeModal, useUpgradeConflictsModal } from './use_upgrade_modals'; +import { useOutdatedMlJobsUpgradeModal } from './use_ml_jobs_upgrade_modal'; +import { useUpgradeWithConflictsModal } from './use_upgrade_with_conflicts_modal'; import { RuleTypeChangeCallout } from './rule_type_change_callout'; import { UpgradeFlyoutSubHeader } from './upgrade_flyout_subheader'; import * as ruleDetailsI18n from '../../../../rule_management/components/rule_details/translations'; @@ -148,20 +147,11 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ }); const { - isVisible: isLegacyMLJobsModalVisible, - legacyJobsInstalled, + modal: confirmLegacyMlJobsUpgradeModal, confirmLegacyMLJobs, - handleConfirm: handleLegacyMLJobsConfirm, - handleCancel: handleLegacyMLJobsCancel, - loadingJobs, - } = useMlJobUpgradeModal(); - - const { - isVisible: isConflictsModalVisible, - confirmConflictsUpgrade, - handleConfirm: handleConflictsConfirm, - handleCancel: handleConflictsCancel, - } = useUpgradeConflictsModal(); + isLoading: areMlJobsLoading, + } = useOutdatedMlJobsUpgradeModal(); + const { modal: upgradeConflictsModal, confirmConflictsUpgrade } = useUpgradeWithConflictsModal(); const { mutateAsync: upgradeSpecificRulesRequest } = usePerformUpgradeSpecificRules(); @@ -406,7 +396,7 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ filterOptions, tags, isFetched, - isLoading: isLoading || loadingJobs, + isLoading: isLoading || areMlJobsLoading, isRefetching, isUpgradingSecurityPackages, loadingRules, @@ -422,7 +412,7 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ tags, isFetched, isLoading, - loadingJobs, + areMlJobsLoading, isRefetching, isUpgradingSecurityPackages, loadingRules, @@ -435,19 +425,8 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ return ( <> - {isLegacyMLJobsModalVisible && ( - - )} - {isConflictsModalVisible && ( - - )} + {confirmLegacyMlJobsUpgradeModal} + {upgradeConflictsModal} {children} {rulePreviewFlyout} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_ml_jobs_upgrade_modal/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_ml_jobs_upgrade_modal/index.ts new file mode 100644 index 0000000000000..470224e90a547 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_ml_jobs_upgrade_modal/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './use_ml_jobs_upgrade_modal'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/modals/ml_job_upgrade_modal/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_ml_jobs_upgrade_modal/ml_jobs_upgrade_modal.tsx similarity index 80% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/modals/ml_job_upgrade_modal/index.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_ml_jobs_upgrade_modal/ml_jobs_upgrade_modal.tsx index 84c0a5a579ba6..37d6a84728aea 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/modals/ml_job_upgrade_modal/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_ml_jobs_upgrade_modal/ml_jobs_upgrade_modal.tsx @@ -5,9 +5,9 @@ * 2.0. */ +import React, { memo } from 'react'; import { EuiConfirmModal } from '@elastic/eui'; import type { MlSummaryJob } from '@kbn/ml-plugin/common'; -import React, { memo } from 'react'; import styled from 'styled-components'; import { rgba } from 'polished'; import * as i18n from './translations'; @@ -33,15 +33,17 @@ const JobsUL = styled.ul` } `; -export interface MlJobUpgradeModalProps { +interface OutdatedMlJobsUpgradeModalProps { jobs: MlSummaryJob[]; - onCancel: ( - event?: React.KeyboardEvent | React.MouseEvent - ) => void; - onConfirm?: (event: React.MouseEvent) => void; + onCancel: () => void; + onConfirm: () => void; } -const MlJobUpgradeModalComponent = ({ jobs, onCancel, onConfirm }: MlJobUpgradeModalProps) => { +export const OutdatedMlJobsUpgradeModal = memo(function LegacyMlJobsUpgradeModal({ + jobs, + onCancel, + onConfirm, +}: OutdatedMlJobsUpgradeModalProps): JSX.Element { return ( ); -}; - -export const MlJobUpgradeModal = memo(MlJobUpgradeModalComponent); +}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/modals/ml_job_upgrade_modal/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_ml_jobs_upgrade_modal/translations.tsx similarity index 95% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/modals/ml_job_upgrade_modal/translations.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_ml_jobs_upgrade_modal/translations.tsx index caf94e5c1a261..8250591de71cc 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/modals/ml_job_upgrade_modal/translations.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_ml_jobs_upgrade_modal/translations.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { MlJobCompatibilityLink } from '../../../../../../../common/components/links_to_docs'; +import { MlJobCompatibilityLink } from '../../../../../../common/components/links_to_docs'; export const ML_JOB_UPGRADE_MODAL_TITLE = i18n.translate( 'xpack.securitySolution.detectionEngine.mlJobUpgradeModal.messageTitle', diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_ml_jobs_upgrade_modal/use_ml_jobs_upgrade_modal.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_ml_jobs_upgrade_modal/use_ml_jobs_upgrade_modal.tsx new file mode 100644 index 0000000000000..cb4682f49a603 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_ml_jobs_upgrade_modal/use_ml_jobs_upgrade_modal.tsx @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ReactNode } from 'react'; +import React, { useCallback } from 'react'; +import { useBoolean } from '@kbn/react-hooks'; +import { useInstalledSecurityJobs } from '../../../../../../common/components/ml/hooks/use_installed_security_jobs'; +import { affectedJobIds } from '../../../../../../../common/machine_learning/affected_job_ids'; +import { useAsyncConfirmation } from '../../rules_table/use_async_confirmation'; +import { OutdatedMlJobsUpgradeModal } from './ml_jobs_upgrade_modal'; + +interface UseOutdatedMlJobsUpgradeModalResult { + modal: ReactNode; + isLoading: boolean; + confirmLegacyMLJobs: () => Promise; +} + +export function useOutdatedMlJobsUpgradeModal(): UseOutdatedMlJobsUpgradeModalResult { + const [isVisible, { on: showModal, off: hideModal }] = useBoolean(false); + const { loading, jobs } = useInstalledSecurityJobs(); + const legacyJobsInstalled = jobs.filter((job) => affectedJobIds.includes(job.id)); + const [confirmLegacyMLJobs, confirm, cancel] = useAsyncConfirmation({ + onInit: showModal, + onFinish: hideModal, + }); + + const handleLegacyMLJobsConfirm = useCallback(async () => { + if (legacyJobsInstalled.length > 0) { + return confirmLegacyMLJobs(); + } + + return true; + }, [confirmLegacyMLJobs, legacyJobsInstalled]); + + return { + modal: isVisible && ( + + ), + confirmLegacyMLJobs: handleLegacyMLJobsConfirm, + isLoading: loading, + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_modals.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_modals.tsx deleted file mode 100644 index 256ccf47c194f..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_modals.tsx +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { useCallback } from 'react'; -import { useInstalledSecurityJobs } from '../../../../../common/components/ml/hooks/use_installed_security_jobs'; -import { useBoolState } from '../../../../../common/hooks/use_bool_state'; -import { affectedJobIds } from '../../../../../../common/machine_learning/affected_job_ids'; -import { useAsyncConfirmation } from '../rules_table/use_async_confirmation'; - -export const useMlJobUpgradeModal = () => { - const [isVisible, showModal, hideModal] = useBoolState(false); - const { loading: loadingJobs, jobs } = useInstalledSecurityJobs(); - const legacyJobsInstalled = jobs.filter((job) => affectedJobIds.includes(job.id)); - const [confirmLegacyMLJobs, handleConfirm, handleCancel] = useAsyncConfirmation({ - onInit: showModal, - onFinish: hideModal, - }); - - const handleLegacyMLJobsConfirm = useCallback(async () => { - if (legacyJobsInstalled.length > 0) { - return confirmLegacyMLJobs(); - } - return true; - }, [confirmLegacyMLJobs, legacyJobsInstalled]); - - return { - isVisible, - legacyJobsInstalled, - confirmLegacyMLJobs: handleLegacyMLJobsConfirm, - handleConfirm, - handleCancel, - loadingJobs, - }; -}; - -export const useUpgradeConflictsModal = () => { - const [isVisible, showModal, hideModal] = useBoolState(false); - const [confirmConflictsUpgrade, handleConfirm, handleCancel] = useAsyncConfirmation({ - onInit: showModal, - onFinish: hideModal, - }); - - return { - isVisible, - confirmConflictsUpgrade, - handleConfirm, - handleCancel, - }; -}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_with_conflicts_modal/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_with_conflicts_modal/index.ts new file mode 100644 index 0000000000000..7a01864683869 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_with_conflicts_modal/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './use_upgrade_modal'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/modals/upgrade_conflicts_modal/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_with_conflicts_modal/translations.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/modals/upgrade_conflicts_modal/translations.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_with_conflicts_modal/translations.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/modals/upgrade_conflicts_modal/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_with_conflicts_modal/upgrade_modal.tsx similarity index 63% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/modals/upgrade_conflicts_modal/index.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_with_conflicts_modal/upgrade_modal.tsx index 0c664398c51f6..3374ae5c16b4d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/modals/upgrade_conflicts_modal/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_with_conflicts_modal/upgrade_modal.tsx @@ -9,14 +9,15 @@ import { EuiConfirmModal, EuiText } from '@elastic/eui'; import React, { memo } from 'react'; import * as i18n from './translations'; -export interface UpgradeConflictsModalProps { - onCancel: ( - event?: React.KeyboardEvent | React.MouseEvent - ) => void; - onConfirm?: (event: React.MouseEvent) => void; +interface UpgradeWithConflictsModalProps { + onCancel: () => void; + onConfirm: () => void; } -const UpgradeConflictsModalComponent = ({ onCancel, onConfirm }: UpgradeConflictsModalProps) => { +export const UpgradeWithConflictsModal = memo(function ConfirmUpgradeWithConflictsModal({ + onCancel, + onConfirm, +}: UpgradeWithConflictsModalProps): JSX.Element { return ( {i18n.UPGRADE_CONFLICTS_MODAL_BODY} ); -}; - -export const UpgradeConflictsModal = memo(UpgradeConflictsModalComponent); +}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_with_conflicts_modal/use_upgrade_modal.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_with_conflicts_modal/use_upgrade_modal.tsx new file mode 100644 index 0000000000000..0714ba458d34e --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_with_conflicts_modal/use_upgrade_modal.tsx @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ReactNode } from 'react'; +import React from 'react'; +import { useBoolean } from '@kbn/react-hooks'; +import { useAsyncConfirmation } from '../../rules_table/use_async_confirmation'; +import { UpgradeWithConflictsModal } from './upgrade_modal'; + +interface UseUpgradeWithConflictsModalResult { + modal: ReactNode; + confirmConflictsUpgrade: () => Promise; +} + +export function useUpgradeWithConflictsModal(): UseUpgradeWithConflictsModalResult { + const [isVisible, { on: showModal, off: hideModal }] = useBoolean(false); + const [confirmConflictsUpgrade, confirm, cancel] = useAsyncConfirmation({ + onInit: showModal, + onFinish: hideModal, + }); + + return { + modal: isVisible && , + confirmConflictsUpgrade, + }; +} From e5ad43706678368edb78042aef61346bf8b0e03e Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Wed, 4 Dec 2024 16:49:02 +0100 Subject: [PATCH 41/77] fix unnecessary header wrapping --- .../comparison_side/field_comparison_side.tsx | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx index 7234c58680639..0b9b37c91e226 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx @@ -6,7 +6,7 @@ */ import React, { useState } from 'react'; -import { EuiFlexGroup, EuiTitle } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; import { VersionsPicker } from './versions_picker/versions_picker'; import type { Version } from './versions_picker/constants'; import { SelectedVersions } from './versions_picker/constants'; @@ -37,18 +37,22 @@ export function FieldComparisonSide(): JSX.Element { return ( <> - - -

- {i18n.TITLE} - -

-
- + + + +

+ {i18n.TITLE} + +

+
+
+ + +
From 6bef7d53b803ddb8b6428e3fd2ebc902abb4506c Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Wed, 4 Dec 2024 19:06:45 +0100 Subject: [PATCH 42/77] rollback use_fetch_prebuilt_rules_upgrade_review_query.ts changes --- .../use_fetch_prebuilt_rules_upgrade_review_query.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_upgrade_review_query.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_upgrade_review_query.ts index 92c16e9d0df03..78e5cc26d6a8c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_upgrade_review_query.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_upgrade_review_query.ts @@ -9,7 +9,7 @@ import type { UseQueryOptions } from '@tanstack/react-query'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import { reviewRuleUpgrade } from '../../api'; import { REVIEW_RULE_UPGRADE_URL } from '../../../../../../common/api/detection_engine/prebuilt_rules/urls'; -import { type ReviewRuleUpgradeResponseBody } from '../../../../../../common/api/detection_engine/prebuilt_rules'; +import type { ReviewRuleUpgradeResponseBody } from '../../../../../../common/api/detection_engine/prebuilt_rules'; import { DEFAULT_QUERY_OPTIONS } from '../constants'; export const REVIEW_RULE_UPGRADE_QUERY_KEY = ['POST', REVIEW_RULE_UPGRADE_URL]; @@ -21,7 +21,6 @@ export const useFetchPrebuiltRulesUpgradeReviewQuery = ( REVIEW_RULE_UPGRADE_QUERY_KEY, async ({ signal }) => { const response = await reviewRuleUpgrade({ signal }); - return response; }, { From 7c99d900f96f78bbdada4d92add7d343fc8d8d82 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Thu, 5 Dec 2024 11:56:23 +0100 Subject: [PATCH 43/77] remove unnecessary file after rebase --- .../translation_tab/rule_query.tsx | 45 ------------------- .../translation_tab/side_header.tsx | 29 ------------ 2 files changed, 74 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/rule_query.tsx delete mode 100644 x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/side_header.tsx diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/rule_query.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/rule_query.tsx deleted file mode 100644 index 68375c053acef..0000000000000 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/rule_query.tsx +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useMemo } from 'react'; -import { EuiMarkdownEditor, EuiMarkdownFormat, EuiTitle } from '@elastic/eui'; -import { SideHeader } from './side_header'; -import * as i18n from './translations'; - -interface RuleQueryProps { - title: string; - query: string; - canEdit?: boolean; -} - -export const RuleQueryComponent = ({ title, query, canEdit }: RuleQueryProps) => { - const queryTextComponent = useMemo(() => { - if (canEdit) { - return ( - {}} - height={400} - initialViewMode={'viewing'} - /> - ); - } else { - return {query}; - } - }, [canEdit, query]); - return ( - <> - - -

{title}

-
-
- {queryTextComponent} - - ); -}; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/side_header.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/side_header.tsx deleted file mode 100644 index 574e3f526f856..0000000000000 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/translation_tab/side_header.tsx +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { PropsWithChildren } from 'react'; -import React from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, useEuiTheme } from '@elastic/eui'; -import { css } from '@emotion/css'; - -export function SideHeader({ children }: PropsWithChildren<{}>) { - const { euiTheme } = useEuiTheme(); - - return ( - <> - - {children} - - - - ); -} From 4684c3f90d435b8c9890b8133def50da11110e4d Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Thu, 5 Dec 2024 12:00:19 +0100 Subject: [PATCH 44/77] calc everyFieldHasConflict based on conflict resolution state --- .../upgrade_prebuilt_rules_table_buttons.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx index 5be1d950f1f87..7922feee0ab81 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx @@ -39,7 +39,7 @@ export const UpgradePrebuiltRulesTableButtons = ({ const isRuleUpgrading = loadingRules.length > 0; const isRequestInProgress = isRuleUpgrading || isRefetching || isUpgradingSecurityPackages; const everyFieldHasConflict = ruleUpgradeStates.every( - ({ diff }) => diff.num_fields_with_conflicts > 0 + ({ hasUnresolvedConflicts }) => hasUnresolvedConflicts ); const doAllSelectedRulesHaveConflicts = isPrebuiltRulesCustomizationEnabled && everyFieldHasConflict; From d94635be20a6a1a8254a829e631959290a9cc396 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Thu, 5 Dec 2024 17:18:35 +0100 Subject: [PATCH 45/77] display a number of solved and non solved conflicts in rule callout --- .../rule_upgrade/rule_upgrade_callout.tsx | 7 ++++++- .../rule_upgrade/translations.tsx | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx index 51bc8ed76f5a5..9f4fc2eca01a7 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx @@ -30,7 +30,12 @@ export function RuleUpgradeCallout({     - {i18n.RULE_HAS_NON_SOLVABLE_CONFLICTS(numOfNonSolvableConflicts)} + {numOfSolvableConflicts > 0 + ? i18n.RULE_HAS_NON_SOLVABLE_AND_SOLVABLE_CONFLICTS( + numOfNonSolvableConflicts, + numOfSolvableConflicts + ) + : i18n.RULE_HAS_NON_SOLVABLE_CONFLICTS(numOfNonSolvableConflicts)} } color="danger" 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 aae8b45f47b23..7e9fc8fca3021 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 @@ -74,13 +74,26 @@ export const UPGRADE_STATUS = i18n.translate( } ); +export const RULE_HAS_NON_SOLVABLE_AND_SOLVABLE_CONFLICTS = ( + numOfNonSolvableConflicts: number, + numOfSolvableConflicts: number +) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableAndNonSolvableConflicts', + { + values: { numOfNonSolvableConflicts, numOfSolvableConflicts }, + defaultMessage: + '{numOfNonSolvableConflicts} {numOfNonSolvableConflicts, plural, one {field has an unsolved conflict} other {fields have unsolved conflicts}} and {numOfSolvableConflicts} {numOfSolvableConflicts, plural, one {field has a solved conflict} other {fields have solved conflicts}}. Please review and provide a final update.', + } + ); + export const RULE_HAS_NON_SOLVABLE_CONFLICTS = (count: number) => i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasNonSolvableConflicts', { values: { count }, defaultMessage: - '{count} {count, plural, one {field has a unsolved conflict} other {fields have unsolved conflicts}}. Please review and provide a final update.', + '{count} {count, plural, one {field has an unsolved conflict} other {fields have unsolved conflicts}}. Please review and provide a final update.', } ); @@ -88,7 +101,7 @@ export const RULE_HAS_NON_SOLVABLE_CONFLICTS_DESCRIPTION = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasNonSolvableConflictsDescription', { defaultMessage: - 'Please provide an input for the unsolved conflict. You can also keep the current without the updates, or accept the Elastic update but lose your modifications.', + 'Please provide an input for the unsolved conflict. You can also keep the current version without the updates, or accept the Elastic update but lose your modifications.', } ); From e26cd43b7da8189d3ab25a8d7925ea13b5d2132d Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Thu, 5 Dec 2024 17:28:30 +0100 Subject: [PATCH 46/77] add modified badge tooltip --- .../three_way_diff/badges/modified_badge.tsx | 17 ++++++++++++----- .../rule_upgrade/field_upgrade_header.tsx | 3 ++- .../rule_upgrade/translations.tsx | 7 +++++++ .../translations.tsx | 7 +++++++ .../upgrade_flyout_subheader.tsx | 4 +++- 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/modified_badge.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/modified_badge.tsx index 1c05e3f690a18..bfe70af031835 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/modified_badge.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/modified_badge.tsx @@ -5,14 +5,21 @@ * 2.0. */ +import type { ReactNode } from 'react'; import React from 'react'; -import { EuiBadge } from '@elastic/eui'; +import { EuiBadge, EuiToolTip } from '@elastic/eui'; import * as i18n from './translations'; -export function ModifiedBadge(): JSX.Element { +interface ModifiedBadgeProps { + tooltip?: ReactNode; +} + +export function ModifiedBadge({ tooltip }: ModifiedBadgeProps): JSX.Element { return ( - - {i18n.MODIFIED} - + + + {i18n.MODIFIED} + + ); } 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 89dee1b434cec..8829d13d05cb4 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 @@ -12,6 +12,7 @@ import { fieldToDisplayNameMap } from '../../diff_components/translations'; import type { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { ModifiedBadge } from '../badges/modified_badge'; import { FieldUpgradeStateInfo } from './field_upgrade_state_info'; +import * as i18n from './translations'; interface FieldUpgradeHeaderProps { fieldName: string; @@ -36,7 +37,7 @@ export function FieldUpgradeHeader({ {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 7e9fc8fca3021..44455179e1d28 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 @@ -129,3 +129,10 @@ export const RULE_IS_READY_FOR_UPGRADE_DESCRIPTION = i18n.translate( defaultMessage: 'There are no conflicts and the update is ready to be applied.', } ); + +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', + } +); 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 743367a021a0b..0773eb95861e9 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 @@ -125,3 +125,10 @@ export const FIELD_UPDATES = i18n.translate( defaultMessage: 'Field updates', } ); + +export const RULE_MODIFIED_BADGE_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.detectionEngine.upgradeFlyout.fieldModifiedBadgeDescription', + { + defaultMessage: 'The rule was edited and field values differs from the stock values', + } +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx index 26f6a72b12085..36c39be5e66f6 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx @@ -49,7 +49,9 @@ export const UpgradeFlyoutSubHeader = memo(function UpgradeFlyoutSubHeader({ ); const customized = ruleUpgradeState.current_rule.rule_source.type === 'external' && - ruleUpgradeState.current_rule.rule_source.is_customized && ; + ruleUpgradeState.current_rule.rule_source.is_customized && ( + + ); const fieldsDiff: FieldsDiff> = ruleUpgradeState.diff.fields; const fieldsNamesWithUpdates = Object.keys(ruleUpgradeState.fieldsUpgradeState).filter( From 09a0edfe698da7a44beb3329dec6c6234dfe24a7 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Thu, 5 Dec 2024 17:32:51 +0100 Subject: [PATCH 47/77] fix variable naming --- .../rule_details/three_way_diff/rule_upgrade/translations.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 44455179e1d28..3e650e8602c20 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 @@ -50,7 +50,7 @@ export function RuleUpgradeHelper(): JSX.Element { }, }, } = useKibana().services; - const manageDetectionRulesSnoozeSection = `${manageDetectionRules}#edit-rules-settings`; + const manageDetectionRulesUpdateRulesSection = `${manageDetectionRules}#edit-rules-settings`; return ( + {UPGRADE_RULES_DOCS_LINK} ), From 8e8ecb751542f753db9d4948a21a99c8a7783f83 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Thu, 5 Dec 2024 21:01:21 +0100 Subject: [PATCH 48/77] set min-width for version picker component --- .../comparison_side/versions_picker/versions_picker.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx index 572e281ff3ae4..4710667e0b315 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx @@ -6,6 +6,7 @@ */ import React, { useCallback, useMemo } from 'react'; +import { css } from '@emotion/css'; import { EuiSelect } from '@elastic/eui'; import type { EuiSelectOption } from '@elastic/eui'; import { BASE_OPTIONS, CURRENT_OPTIONS, TARGET_OPTIONS, SelectedVersions } from './constants'; @@ -36,6 +37,7 @@ export function VersionsPicker({ return ( ); } + +const VERSIONS_PICKER_STYLES = css` + // Set min-width a bit wider than default + // to make English text in narrow screens readable + min-width: 220px; +`; From ebd5e83aad353cc761bacedb4aac0bfd74fa496b Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Thu, 5 Dec 2024 21:06:22 +0100 Subject: [PATCH 49/77] make field names in updates matching design --- .../upgrade_flyout_subheader.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx index 36c39be5e66f6..99dfc1335858b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx @@ -61,11 +61,11 @@ export const UpgradeFlyoutSubHeader = memo(function UpgradeFlyoutSubHeader({ {i18n.FIELD_UPDATES} - {':'}{' '} - {fieldsNamesWithUpdates - .map((fieldName) => fieldToDisplayNameMap[fieldName] ?? startCase(camelCase(fieldName))) - .join(', ')} - + {':'} +
{' '} + {fieldsNamesWithUpdates + .map((fieldName) => fieldToDisplayNameMap[fieldName] ?? startCase(camelCase(fieldName))) + .join(', ')}
); From eae9df78a21d69319e6a9f84205afad7a622e163 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Thu, 5 Dec 2024 21:08:08 +0100 Subject: [PATCH 50/77] fix translation keys --- .../rules_table/upgrade_prebuilt_rules_table/translations.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0773eb95861e9..24ac382c9f0cc 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 @@ -127,7 +127,7 @@ export const FIELD_UPDATES = i18n.translate( ); export const RULE_MODIFIED_BADGE_DESCRIPTION = i18n.translate( - 'xpack.securitySolution.detectionEngine.upgradeFlyout.fieldModifiedBadgeDescription', + 'xpack.securitySolution.detectionEngine.upgradeFlyout.ruleModifiedBadgeDescription', { defaultMessage: 'The rule was edited and field values differs from the stock values', } From 761407cc53ab6d105c6f0a80ce6638f3c35f705c Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 6 Dec 2024 11:26:38 +0100 Subject: [PATCH 51/77] fix update selected rules button's condition --- .../upgrade_prebuilt_rules_table_buttons.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx index 7922feee0ab81..8184481e25cc3 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx @@ -38,12 +38,13 @@ export const UpgradePrebuiltRulesTableButtons = ({ const isRuleUpgrading = loadingRules.length > 0; const isRequestInProgress = isRuleUpgrading || isRefetching || isUpgradingSecurityPackages; - const everyFieldHasConflict = ruleUpgradeStates.every( - ({ hasUnresolvedConflicts }) => hasUnresolvedConflicts - ); + const doAllSelectedRulesHaveConflicts = - isPrebuiltRulesCustomizationEnabled && everyFieldHasConflict; - const doAllRulesHaveConflicts = isPrebuiltRulesCustomizationEnabled && everyFieldHasConflict; + isPrebuiltRulesCustomizationEnabled && + selectedRules.every(({ hasUnresolvedConflicts }) => hasUnresolvedConflicts); + const doAllRulesHaveConflicts = + isPrebuiltRulesCustomizationEnabled && + ruleUpgradeStates.every(({ hasUnresolvedConflicts }) => hasUnresolvedConflicts); const { selectedRulesButtonTooltip, allRulesButtonTooltip } = useBulkUpdateButtonsTooltipContent({ canUserEditRules, From 54167fce2d70400193ceefdace4a42e6b192da84 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 6 Dec 2024 11:27:03 +0100 Subject: [PATCH 52/77] disallow rule upgrade requests without rules specified --- .../perform_rule_upgrade/perform_rule_upgrade_route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_upgrade/perform_rule_upgrade_route.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_upgrade/perform_rule_upgrade_route.ts index 0021aece67455..3ef53e7b7c67a 100644 --- a/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_upgrade/perform_rule_upgrade_route.ts +++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_upgrade/perform_rule_upgrade_route.ts @@ -115,7 +115,7 @@ export const RuleUpgradeSpecifier = z.object({ export type UpgradeSpecificRulesRequest = z.infer; export const UpgradeSpecificRulesRequest = z.object({ mode: z.literal('SPECIFIC_RULES'), - rules: z.array(RuleUpgradeSpecifier), + rules: z.array(RuleUpgradeSpecifier).min(1), pick_version: PickVersionValues.optional(), }); From f358957b5b3833057b57d5f740cef05b3c468b91 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 6 Dec 2024 13:15:44 +0100 Subject: [PATCH 53/77] post-rebase fix --- .../components/rule_field_edit_form_wrapper.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_form_wrapper.tsx index 51b9da783c419..ab12f62cfa27b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/rule_field_edit_form_wrapper.tsx @@ -6,12 +6,10 @@ */ import React, { useCallback, useEffect } from 'react'; -import { EuiButtonEmpty, EuiFlexGroup } from '@elastic/eui'; import { extractValidationMessages } from '../../../../../../rule_creation/logic/extract_validation_messages'; import type { FormWithWarningsSubmitHandler } from '../../../../../../../common/hooks/use_form_with_warnings'; import { useFormWithWarnings } from '../../../../../../../common/hooks/use_form_with_warnings'; import { Form } from '../../../../../../../shared_imports'; -import { useForm, Form } from '../../../../../../../shared_imports'; import type { FormSchema, FormData } from '../../../../../../../shared_imports'; import type { DiffableAllFields, From e744e2dd6395c7bd857e712ece20a24b7316a2f8 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 6 Dec 2024 14:01:58 +0100 Subject: [PATCH 54/77] allow to unset values --- .../three_way_diff/rule_upgrade/field_upgrade_context.tsx | 2 +- .../model/prebuilt_rule_upgrade/fields_upgrade_state.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) 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 92170d057828e..2dec30772efb1 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 @@ -132,7 +132,7 @@ function calcFinalDiffableRule(ruleUpgradeState: RuleUpgradeState): DiffableRule const fieldsResolvedValues = Object.entries(ruleUpgradeState.fieldsUpgradeState).reduce< Record >((result, [fieldName, fieldState]) => { - if (fieldState.state === FieldUpgradeState.Accepted && Boolean(fieldState.resolvedValue)) { + if (fieldState.state === FieldUpgradeState.Accepted) { result[fieldName] = fieldState.resolvedValue; } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/fields_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/fields_upgrade_state.ts index 36015470e96d2..075585f59f84c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/fields_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/fields_upgrade_state.ts @@ -5,6 +5,7 @@ * 2.0. */ +import type { DiffableAllFields } from '../../../../../common/api/detection_engine'; import type { FieldUpgradeState } from './field_upgrade_state'; export type FieldsUpgradeState = Record< @@ -12,5 +13,5 @@ export type FieldsUpgradeState = Record< | { state: Exclude; } - | { state: FieldUpgradeState.Accepted; resolvedValue: unknown } + | { state: FieldUpgradeState.Accepted; resolvedValue: DiffableAllFields[keyof DiffableAllFields] } >; From 4e36df8a3e4a31132f0caaab90ae5332c75e1411 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 6 Dec 2024 14:08:57 +0100 Subject: [PATCH 55/77] properly calculate customized state for optional fields --- .../three_way_diff/rule_upgrade/field_upgrade.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 5f99434979ae5..04ddb1bd6a52e 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 @@ -22,7 +22,9 @@ export function FieldUpgrade(): JSX.Element { const hasConflict = fieldDiff.conflict !== ThreeWayDiffConflict.NONE; const isFieldCustomized = useMemo( () => - fieldDiff.base_version ? !isEqual(fieldDiff.base_version, fieldDiff.current_version) : false, + fieldDiff.has_base_version + ? !isEqual(fieldDiff.base_version, fieldDiff.current_version) + : false, [fieldDiff] ); From 9a87fe52f3c00fe562dcfe75728a71b639e4c748 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 6 Dec 2024 16:53:17 +0100 Subject: [PATCH 56/77] fix rule upgrade state numbers --- .../rule_upgrade/rule_upgrade.tsx | 13 +---- .../rule_upgrade/rule_upgrade_callout.tsx | 13 ++--- .../rule_upgrade/rule_upgrade_info_bar.tsx | 13 +---- .../rule_upgrade/translations.tsx | 55 ++++--------------- 4 files changed, 21 insertions(+), 73 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx index d02787de12e3f..ca7bbf8de2145 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx @@ -7,7 +7,6 @@ import React, { memo } from 'react'; import { EuiSpacer } from '@elastic/eui'; -import type { ThreeWayDiff } from '../../../../../../../common/api/detection_engine'; import { FieldUpgradeState, type RuleUpgradeState, @@ -40,8 +39,7 @@ export const RuleUpgrade = memo(function RuleUpgrade({ ]> = Object.entries( - ruleUpgradeState.diff.fields - ); - const fieldsUpgradeState = ruleUpgradeState.fieldsUpgradeState; - - return fieldsDiffEntries.filter( - ([fieldName, fieldDiff]) => Boolean(fieldsUpgradeState[fieldName]) && fieldDiff.has_update - ).length; + return Object.keys(ruleUpgradeState.fieldsUpgradeState).length; } function calcNumOfSolvableConflicts(ruleUpgradeState: RuleUpgradeState): number { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx index 9f4fc2eca01a7..3b3c0c7e49e51 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_callout.tsx @@ -30,18 +30,13 @@ export function RuleUpgradeCallout({     - {numOfSolvableConflicts > 0 - ? i18n.RULE_HAS_NON_SOLVABLE_AND_SOLVABLE_CONFLICTS( - numOfNonSolvableConflicts, - numOfSolvableConflicts - ) - : i18n.RULE_HAS_NON_SOLVABLE_CONFLICTS(numOfNonSolvableConflicts)} + {i18n.RULE_HAS_CONFLICTS(numOfNonSolvableConflicts + numOfSolvableConflicts)} } color="danger" size="s" > -

{i18n.RULE_HAS_NON_SOLVABLE_CONFLICTS_DESCRIPTION}

+

{i18n.RULE_HAS_HARD_CONFLICTS_DESCRIPTION}

); } @@ -55,13 +50,13 @@ export function RuleUpgradeCallout({     - {i18n.RULE_HAS_SOLVABLE_CONFLICTS(numOfSolvableConflicts)} + {i18n.RULE_HAS_CONFLICTS(numOfSolvableConflicts)} } color="warning" size="s" > -

{i18n.RULE_HAS_SOLVABLE_CONFLICTS_DESCRIPTION}

+

{i18n.RULE_HAS_SOFT_CONFLICTS_DESCRIPTION}

); } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx index 7dcad2af3d612..cc1096514c97c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx @@ -16,14 +16,12 @@ import * as i18n from './translations'; interface RuleUpgradeInfoBarProps { numOfFieldsWithUpdates: number; - numOfSolvableConflicts: number; - numOfNonSolvableConflicts: number; + numOfConflicts: number; } export function RuleUpgradeInfoBar({ numOfFieldsWithUpdates, - numOfSolvableConflicts, - numOfNonSolvableConflicts, + numOfConflicts, }: RuleUpgradeInfoBarProps): JSX.Element { return ( @@ -35,12 +33,7 @@ export function RuleUpgradeInfoBar({ - {i18n.NUM_OF_SOLVED_CONFLICTS(numOfSolvableConflicts)} - - - - - {i18n.NUM_OF_UNSOLVED_CONFLICTS(numOfNonSolvableConflicts)} + {i18n.NUM_OF_CONFLICTS(numOfConflicts)} 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 3e650e8602c20..bc95924dd17f3 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 @@ -19,19 +19,11 @@ export const NUM_OF_FIELDS_WITH_UPDATES = (count: number) => ( /> ); -export const NUM_OF_SOLVED_CONFLICTS = (count: number) => ( +export const NUM_OF_CONFLICTS = (count: number) => ( {count} }} - /> -); - -export const NUM_OF_UNSOLVED_CONFLICTS = (count: number) => ( - {count} }} + defaultMessage="{countValue} {count, plural, one {conflict} other {conflicts}}" + values={{ countValue: {count}, count }} /> ); @@ -74,52 +66,29 @@ export const UPGRADE_STATUS = i18n.translate( } ); -export const RULE_HAS_NON_SOLVABLE_AND_SOLVABLE_CONFLICTS = ( - numOfNonSolvableConflicts: number, - numOfSolvableConflicts: number -) => - i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableAndNonSolvableConflicts', - { - values: { numOfNonSolvableConflicts, numOfSolvableConflicts }, - defaultMessage: - '{numOfNonSolvableConflicts} {numOfNonSolvableConflicts, plural, one {field has an unsolved conflict} other {fields have unsolved conflicts}} and {numOfSolvableConflicts} {numOfSolvableConflicts, plural, one {field has a solved conflict} other {fields have solved conflicts}}. Please review and provide a final update.', - } - ); - -export const RULE_HAS_NON_SOLVABLE_CONFLICTS = (count: number) => +export const RULE_HAS_CONFLICTS = (count: number) => i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasNonSolvableConflicts', + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasConflicts', { values: { count }, defaultMessage: - '{count} {count, plural, one {field has an unsolved conflict} other {fields have unsolved conflicts}}. Please review and provide a final update.', + '{count} {count, plural, one {field has a conflict} other {fields have conflicts}}. Please review and provide a final update.', } ); -export const RULE_HAS_NON_SOLVABLE_CONFLICTS_DESCRIPTION = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasNonSolvableConflictsDescription', +export const RULE_HAS_SOFT_CONFLICTS_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflictsDescription', { defaultMessage: - 'Please provide an input for the unsolved conflict. You can also keep the current version without the updates, or accept the Elastic update but lose your modifications.', + 'Please review and accept conflicts. You can also keep the current version without the updates, or accept the Elastic update but lose your modifications.', } ); -export const RULE_HAS_SOLVABLE_CONFLICTS = (count: number) => - i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflicts', - { - values: { count }, - defaultMessage: - '{count} {count, plural, one {field has a solved conflict} other {fields have solved conflicts}}. Please review the final update.', - } - ); - -export const RULE_HAS_SOLVABLE_CONFLICTS_DESCRIPTION = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflictsDescription', +export const RULE_HAS_HARD_CONFLICTS_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasNonSolvableConflictsDescription', { defaultMessage: - 'Please review and accept solved conflicts. You can also keep the current without the updates, or accept the Elastic update but lose your modifications.', + '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.', } ); From d125acb6b4b6b09669240dcc77c4d57652363dc7 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 6 Dec 2024 16:56:38 +0100 Subject: [PATCH 57/77] take into account conflict resolved state for field upgrade expandable state --- .../three_way_diff/rule_upgrade/field_upgrade.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 04ddb1bd6a52e..263a834a26a81 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 @@ -10,16 +10,18 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer, useEuiTheme } from '@elastic/eui' import { css } from '@emotion/css'; import { isEqual } from 'lodash'; import { SplitAccordion } from '../../../../../../common/components/split_accordion'; -import { ThreeWayDiffConflict } from '../../../../../../../common/api/detection_engine'; import { FieldComparisonSide } from '../comparison_side/field_comparison_side'; import { FieldFinalSide } from '../field_final_side'; import { FieldUpgradeHeader } from './field_upgrade_header'; import { useFieldUpgradeContext } from './field_upgrade_context'; +import { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; export function FieldUpgrade(): JSX.Element { const { euiTheme } = useEuiTheme(); const { fieldName, fieldUpgradeState, fieldDiff } = useFieldUpgradeContext(); - const hasConflict = fieldDiff.conflict !== ThreeWayDiffConflict.NONE; + const hasConflict = + fieldUpgradeState === FieldUpgradeState.SolvableConflict || + fieldUpgradeState === FieldUpgradeState.NonSolvableConflict; const isFieldCustomized = useMemo( () => fieldDiff.has_base_version From 56e68ae2dafdb69b6ebd27e6134924945cf21275 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 6 Dec 2024 17:29:54 +0100 Subject: [PATCH 58/77] add no update state --- .../badges/ready_for_upgrade_badge.tsx | 11 +++++++++-- .../components/field_final_side_header.tsx | 10 +++++----- .../field_upgrade_state_info.tsx | 7 +++++++ .../field_upgrade_state_info/translations.tsx | 15 +++++++++++++++ .../three_way_diff/rule_upgrade/rule_upgrade.tsx | 10 +++++++++- .../rule_upgrade/rule_upgrade_info_bar.tsx | 7 +++++++ .../three_way_diff/rule_upgrade/translations.tsx | 12 ++++++++++-- .../prebuilt_rule_upgrade/field_upgrade_state.ts | 3 ++- .../use_prebuilt_rules_upgrade_state.ts | 10 ++++++---- 9 files changed, 70 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/ready_for_upgrade_badge.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/ready_for_upgrade_badge.tsx index b6c5138cf0efe..c5498fe04dcfe 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/ready_for_upgrade_badge.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/badges/ready_for_upgrade_badge.tsx @@ -6,9 +6,16 @@ */ import React from 'react'; +import type { EuiBadgeProps } from '@elastic/eui'; import { EuiBadge } from '@elastic/eui'; import * as i18n from './translations'; -export function ReadyForUpgradeBadge(): JSX.Element { - return {i18n.READY_FOR_UPDATE}; +interface ReadyForUpgradeBadgeProps { + color?: EuiBadgeProps['color']; +} + +export function ReadyForUpgradeBadge({ + color = 'success', +}: ReadyForUpgradeBadgeProps): JSX.Element { + return {i18n.READY_FOR_UPDATE}; } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx index d157d129bb376..2c3d57c48134f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx @@ -29,9 +29,9 @@ export function FieldFinalSideHeader(): JSX.Element { setRuleFieldResolvedValue, } = useFieldUpgradeContext(); const { form } = useFieldEditFormContext(); - const isFieldReadyForUpgrade = - fieldUpgradeState === FieldUpgradeState.NoConflict || - fieldUpgradeState === FieldUpgradeState.Accepted; + const hasConflict = + fieldUpgradeState === FieldUpgradeState.SolvableConflict || + fieldUpgradeState === FieldUpgradeState.NonSolvableConflict; const handleAccept = useCallback( () => @@ -49,7 +49,7 @@ export function FieldFinalSideHeader(): JSX.Element { return ( - {!isFieldReadyForUpgrade && ( + {hasConflict && ( {i18n.ACCEPT} @@ -67,7 +67,7 @@ export function FieldFinalSideHeader(): JSX.Element { disabled={!form?.isValid} onClick={handleSave} > - {!isFieldReadyForUpgrade ? i18n.SAVE_AND_ACCEPT : i18n.SAVE} + {hasConflict ? i18n.SAVE_AND_ACCEPT : i18n.SAVE} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx index 9328c407c8165..93e0dedb0afe5 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx @@ -21,6 +21,13 @@ interface FieldUpgradeStateInfoProps { export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JSX.Element { const { color, badge, title, description } = useMemo(() => { switch (state) { + case FieldUpgradeState.NoUpdate: + return { + color: 'success', + title: i18n.NO_UPDATE, + description: i18n.NO_UPDATE_DESCRIPTION, + }; + case FieldUpgradeState.NoConflict: return { color: 'success', diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/translations.tsx index fbd96c9fbd01f..c3115c6ce0925 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/translations.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/translations.tsx @@ -7,6 +7,21 @@ import { i18n } from '@kbn/i18n'; +export const NO_UPDATE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.noUpdate', + { + defaultMessage: 'No update', + } +); + +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.', + } +); + export const NO_CONFLICT = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.noConflict', { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx index ca7bbf8de2145..ba069e0553930 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx @@ -27,6 +27,7 @@ export const RuleUpgrade = memo(function RuleUpgrade({ ruleUpgradeState, setRuleFieldResolvedValue, }: RuleUpgradeProps): JSX.Element { + const totalNumOfFields = calcTotalNumOfFields(ruleUpgradeState); const numOfFieldsWithUpdates = calcNumOfFieldsWithUpdates(ruleUpgradeState); const numOfSolvableConflicts = calcNumOfSolvableConflicts(ruleUpgradeState); const numOfNonSolvableConflicts = calcNumOfNonSolvableConflicts(ruleUpgradeState); @@ -38,6 +39,7 @@ export const RuleUpgrade = memo(function RuleUpgrade({ <> @@ -61,10 +63,16 @@ export const RuleUpgrade = memo(function RuleUpgrade({ ); }); -function calcNumOfFieldsWithUpdates(ruleUpgradeState: RuleUpgradeState): number { +function calcTotalNumOfFields(ruleUpgradeState: RuleUpgradeState): number { return Object.keys(ruleUpgradeState.fieldsUpgradeState).length; } +function calcNumOfFieldsWithUpdates(ruleUpgradeState: RuleUpgradeState): number { + return Object.values(ruleUpgradeState.fieldsUpgradeState).filter( + ({ state }) => state !== FieldUpgradeState.NoUpdate + ).length; +} + function calcNumOfSolvableConflicts(ruleUpgradeState: RuleUpgradeState): number { return Object.values(ruleUpgradeState.fieldsUpgradeState).filter( ({ state }) => state === FieldUpgradeState.SolvableConflict diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx index cc1096514c97c..3520734b2b257 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade_info_bar.tsx @@ -15,17 +15,24 @@ import { import * as i18n from './translations'; interface RuleUpgradeInfoBarProps { + totalNumOfFields: number; numOfFieldsWithUpdates: number; numOfConflicts: number; } export function RuleUpgradeInfoBar({ + totalNumOfFields, numOfFieldsWithUpdates, numOfConflicts, }: RuleUpgradeInfoBarProps): JSX.Element { return ( + + + {i18n.TOTAL_NUM_OF_FIELDS(totalNumOfFields)} + + {i18n.NUM_OF_FIELDS_WITH_UPDATES(numOfFieldsWithUpdates)} 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 bc95924dd17f3..7f0fb9c58f3e9 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 @@ -11,11 +11,19 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { useKibana } from '../../../../../../common/lib/kibana/kibana_react'; +export const TOTAL_NUM_OF_FIELDS = (count: number) => ( + {count}, count }} + /> +); + export const NUM_OF_FIELDS_WITH_UPDATES = (count: number) => ( {count} }} + defaultMessage="{countValue} {count, plural, one {field} other {fields}} in Elastic update" + values={{ countValue: {count}, count }} /> ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state.ts index dc92bbb8a6600..48d27409788a9 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state.ts @@ -6,8 +6,9 @@ */ export enum FieldUpgradeState { - Accepted = 'ACCEPTED', + NoUpdate = 'NO_UPDATE', NoConflict = 'NO_CONFLICT', + Accepted = 'ACCEPTED', SolvableConflict = 'SOLVABLE_CONFLICT', NonSolvableConflict = 'NON_SOLVABLE_CONFLICT', } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts index d0d58336c1bae..f19c1bb21d8f4 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts @@ -97,11 +97,13 @@ function calcFieldsState( continue; } - const conflict = fieldsDiff[fieldName]?.conflict ?? ThreeWayDiffConflict.NONE; + const fieldDiff = fieldsDiff[fieldName]; - switch (conflict) { + switch (fieldDiff.conflict) { case ThreeWayDiffConflict.NONE: - fieldsState[fieldName] = { state: FieldUpgradeState.NoConflict }; + fieldsState[fieldName] = { + state: fieldDiff.has_update ? FieldUpgradeState.NoConflict : FieldUpgradeState.NoUpdate, + }; break; case ThreeWayDiffConflict.SOLVABLE: @@ -113,7 +115,7 @@ function calcFieldsState( break; default: - assertUnreachable(conflict); + assertUnreachable(fieldDiff.conflict); } } From 2f7e68d1b8bb206e00a15337552d0c30f8684bcc Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 6 Dec 2024 18:06:30 +0100 Subject: [PATCH 59/77] fix translations keys --- .../private/translations/translations/fr-FR.json | 5 ----- .../private/translations/translations/ja-JP.json | 5 ----- .../private/translations/translations/zh-CN.json | 5 ----- .../three_way_diff/rule_upgrade/translations.tsx | 10 +++++----- 4 files changed, 5 insertions(+), 20 deletions(-) diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index fa24fbf2822f6..f16fdcc91869a 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -39082,17 +39082,12 @@ "xpack.securitySolution.detectionEngine.rules.upgradeRules.comparisonSide.title": "Affichage différé", "xpack.securitySolution.detectionEngine.rules.upgradeRules.currentVersionDescriptionLabel": "Affiche la règle actuellement installée", "xpack.securitySolution.detectionEngine.rules.upgradeRules.currentVersionLabel": "Règle actuelle", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.fieldsWithUpdates": "La mise à niveau contient {count} {count, plural, one {champ} other {champs}}", "xpack.securitySolution.detectionEngine.rules.upgradeRules.editButtonLabel": "Modifier", "xpack.securitySolution.detectionEngine.rules.upgradeRules.elasticUpdateVersionLabel": "Mise à jour Elastic", "xpack.securitySolution.detectionEngine.rules.upgradeRules.expandHiddenDiffLinesLabel": "Développer {linesCount}{linesCount, plural, one {ligne} other {lignes}}", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldReadOnly.noteLabel": "Guide d'investigation", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.nonSolvableConflict": "Conflit résolu", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.nonSolvableConflictDescription": "Nous avons suggéré une mise à jour pour ce champ modifié, veuillez la consulter avant d'accepter.", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasNonSolvableConflicts": "{count} des champs {count, plural, one {a} other {ont}} un conflit non résolu. Veuillez en prendre connaissance et apporter les modifications appropriées.", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasNonSolvableConflictsDescription": "Veuillez apporter une contribution au conflit non résolu. Vous pouvez également conserver la version actuelle sans les mises à jour, ou accepter la mise à jour Elastic tout en perdant vos modifications.", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflicts": "{count} des champs {count, plural, one {a} other {ont}} un conflit de mise à jour. Veuillez examiner la mise à jour en cours suggérée.", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflictsDescription": "Veuillez consulter la version mise à jour recommandée avant de l'accepter. Vous pouvez modifier le champ, puis l'enregistrer, si nécessaire.", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleIsReadyForUpgradeDescription": "Tous les conflits ont maintenant été examinés et résolus, veuillez mettre à jour la règle.", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.separator": "-", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.solvableConflict": "Conflit résolu", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index 71a2046c98a6d..7e3ffbce7e12d 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -38939,17 +38939,12 @@ "xpack.securitySolution.detectionEngine.rules.upgradeRules.comparisonSide.title": "差異ビュー", "xpack.securitySolution.detectionEngine.rules.upgradeRules.currentVersionDescriptionLabel": "現在インストールされているルールを表示します", "xpack.securitySolution.detectionEngine.rules.upgradeRules.currentVersionLabel": "現在のルール", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.fieldsWithUpdates": "アップグレードには{count} {count, plural, other {個のフィールド}}があります", "xpack.securitySolution.detectionEngine.rules.upgradeRules.editButtonLabel": "編集", "xpack.securitySolution.detectionEngine.rules.upgradeRules.elasticUpdateVersionLabel": "Elastic更新", "xpack.securitySolution.detectionEngine.rules.upgradeRules.expandHiddenDiffLinesLabel": "変更されていない{linesCount} {linesCount, plural, other {行}}を展開", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldReadOnly.noteLabel": "調査ガイド", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.nonSolvableConflict": "解決された競合", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.nonSolvableConflictDescription": "この修正されたフィールドの更新を提案しました。承認する前に確認してください。", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasNonSolvableConflicts": "{count}個のフィールド{count, plural, other {には}}未解決の競合があります。確認し、必要に応じて修正してください。", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasNonSolvableConflictsDescription": "未解決の競合の情報を入力してください。更新を適用せずに現在の状態を維持することもできます。Elasticの更新を承認すると、修正内容は失われます。", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflicts": "{count}個のフィールド{count, plural, other {には}}更新の競合があります。更新中の候補の更新を確認してください。", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflictsDescription": "更新を承認する前に、提案された更新バージョンを確認してください。変更する場合は、編集してフィールドを保存できます。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleIsReadyForUpgradeDescription": "すべての競合が確認され、解決されました。ルールを更新してください。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.separator": "-", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.solvableConflict": "解決された競合", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index 7e41afcd75b3a..e5dd4f6d8d44d 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -38363,17 +38363,12 @@ "xpack.securitySolution.detectionEngine.rules.upgradeRules.comparisonSide.title": "差异视图", "xpack.securitySolution.detectionEngine.rules.upgradeRules.currentVersionDescriptionLabel": "显示当前安装的规则", "xpack.securitySolution.detectionEngine.rules.upgradeRules.currentVersionLabel": "当前规则", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.fieldsWithUpdates": "升级包含 {count} 个{count, plural, other {字段}}", "xpack.securitySolution.detectionEngine.rules.upgradeRules.editButtonLabel": "编辑", "xpack.securitySolution.detectionEngine.rules.upgradeRules.elasticUpdateVersionLabel": "Elastic 更新", "xpack.securitySolution.detectionEngine.rules.upgradeRules.expandHiddenDiffLinesLabel": "展开 {linesCount} 个未更改的{linesCount, plural, other {行}}", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldReadOnly.noteLabel": "调查指南", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.nonSolvableConflict": "已解决冲突", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.nonSolvableConflictDescription": "我们已为这个已修改字段推荐了更新,请在接受前进行复查。", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasNonSolvableConflicts": "{count} 个字段{count, plural, other {存在}}未解决的冲突。请复查并做出相应更改。", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasNonSolvableConflictsDescription": "请为未解决的冲突提供输入。您还可以保持现状而不进行更新,也可以接受 Elastic 更新但丢失修改。", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflicts": "{count} 个字段{count, plural, other {存在}}更新冲突,请复查正在更新的建议更新。", - "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflictsDescription": "在接受更新之前,请复查建议的已更新版本。如果希望更改字段,您可以编辑然后保存字段。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleIsReadyForUpgradeDescription": "现已复查并解决所有冲突,请更新规则。", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.separator": "-", "xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.solvableConflict": "已解决冲突", 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 7f0fb9c58f3e9..4a73f096a271c 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 @@ -13,7 +13,7 @@ import { useKibana } from '../../../../../../common/lib/kibana/kibana_react'; export const TOTAL_NUM_OF_FIELDS = (count: number) => ( {count}, count }} /> @@ -21,7 +21,7 @@ export const TOTAL_NUM_OF_FIELDS = (count: number) => ( export const NUM_OF_FIELDS_WITH_UPDATES = (count: number) => ( {count}, count }} /> @@ -29,7 +29,7 @@ export const NUM_OF_FIELDS_WITH_UPDATES = (count: number) => ( export const NUM_OF_CONFLICTS = (count: number) => ( {count}, count }} /> @@ -85,7 +85,7 @@ export const RULE_HAS_CONFLICTS = (count: number) => ); export const RULE_HAS_SOFT_CONFLICTS_DESCRIPTION = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasSolvableConflictsDescription', + '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.', @@ -93,7 +93,7 @@ export const RULE_HAS_SOFT_CONFLICTS_DESCRIPTION = i18n.translate( ); export const RULE_HAS_HARD_CONFLICTS_DESCRIPTION = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.ruleHasNonSolvableConflictsDescription', + '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.', From 696ee63fb3c5a9a4203456f312a6a86bae02d088 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 6 Dec 2024 22:32:21 +0100 Subject: [PATCH 60/77] disallow rule type change upgrade in rule upgrades table --- .../use_prebuilt_rules_upgrade_state.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts index f19c1bb21d8f4..fcd3ef1bc40a6 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts @@ -63,7 +63,8 @@ export function usePrebuiltRulesUpgradeState( ...ruleUpgradeInfo, fieldsUpgradeState, hasUnresolvedConflicts: isPrebuiltRulesCustomizationEnabled - ? Object.values(fieldsUpgradeState).some( + ? Boolean(ruleUpgradeInfo.diff.fields.type) || + Object.values(fieldsUpgradeState).some( ({ state: fieldState }) => fieldState === FieldUpgradeState.SolvableConflict || fieldState === FieldUpgradeState.NonSolvableConflict From 0988d20764d894f322cb0e7ce6f747178d1521bf Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 6 Dec 2024 22:51:17 +0100 Subject: [PATCH 61/77] hide field updates for rule type change --- .../upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx index 99dfc1335858b..bab43e55c2e00 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_flyout_subheader.tsx @@ -57,7 +57,7 @@ export const UpgradeFlyoutSubHeader = memo(function UpgradeFlyoutSubHeader({ const fieldsNamesWithUpdates = Object.keys(ruleUpgradeState.fieldsUpgradeState).filter( (fieldName) => fieldsDiff[fieldName].has_update ); - const fieldUpdates = fieldsNamesWithUpdates.length > 0 && ( + const fieldUpdates = !fieldsDiff.type && fieldsNamesWithUpdates.length > 0 && ( {i18n.FIELD_UPDATES} From de9fc27a5b0549784f26134887b7631ef71ac0f2 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 6 Dec 2024 22:51:56 +0100 Subject: [PATCH 62/77] change rule type change callout for a case without customization --- .../rule_type_change_callout.tsx | 19 +++++++++++++++---- .../translations.tsx | 7 +++++++ .../upgrade_prebuilt_rules_table_context.tsx | 10 +++++++++- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/rule_type_change_callout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/rule_type_change_callout.tsx index f66fd92a685fe..0111ceb40d38f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/rule_type_change_callout.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/rule_type_change_callout.tsx @@ -5,17 +5,28 @@ * 2.0. */ -import { EuiCallOut } from '@elastic/eui'; import React from 'react'; +import { EuiCallOut } from '@elastic/eui'; import { RULE_TYPE_CHANGE_CALLOUT_DESCRIPTION, RULE_TYPE_CHANGE_CALLOUT_TITLE, + RULE_TYPE_CHANGE_WITH_CUSTOMIZATIONS_CALLOUT_DESCRIPTION, } from './translations'; -export const RuleTypeChangeCallout = () => { +interface RuleTypeChangeCalloutProps { + hasCustomizations: boolean; +} + +export function RuleTypeChangeCallout({ + hasCustomizations, +}: RuleTypeChangeCalloutProps): JSX.Element { return ( -

{RULE_TYPE_CHANGE_CALLOUT_DESCRIPTION}

+

+ {hasCustomizations + ? RULE_TYPE_CHANGE_WITH_CUSTOMIZATIONS_CALLOUT_DESCRIPTION + : RULE_TYPE_CHANGE_CALLOUT_DESCRIPTION} +

); -}; +} 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 24ac382c9f0cc..4b9f79e061ce9 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 @@ -91,6 +91,13 @@ 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.', + } +); + +export const RULE_TYPE_CHANGE_WITH_CUSTOMIZATIONS_CALLOUT_DESCRIPTION = i18n.translate( + '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.', diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx index 07912b7ca21ed..ce60bab9af4bf 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx @@ -310,11 +310,19 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ } const hasRuleTypeChange = ruleUpgradeState.diff.fields.type?.has_update ?? false; + const hasCustomizations = + ruleUpgradeState.current_rule.rule_source.type === 'external' && + ruleUpgradeState.current_rule.rule_source.is_customized; const shouldShowRuleTypeChangeCallout = hasRuleTypeChange && isPrebuiltRulesCustomizationEnabled; + let updateTabContent = ( : null} + header={ + shouldShowRuleTypeChangeCallout && ( + + ) + } ruleDiff={ruleUpgradeState.diff} /> ); From 86a453a432a6447ff56c3c898c53791ad49bc85b Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Sat, 7 Dec 2024 12:37:26 +0100 Subject: [PATCH 63/77] make hasUnresolvedConflicts calculation clearer --- .../use_prebuilt_rules_upgrade_state.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts index fcd3ef1bc40a6..1f193ff108f59 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts @@ -59,16 +59,18 @@ export function usePrebuiltRulesUpgradeState( rulesResolvedConflicts[ruleUpgradeInfo.rule_id] ?? {} ); + const hasRuleTypeChange = Boolean(ruleUpgradeInfo.diff.fields.type); + const hasFieldConflicts = Object.values(fieldsUpgradeState).some( + ({ state: fieldState }) => + fieldState === FieldUpgradeState.SolvableConflict || + fieldState === FieldUpgradeState.NonSolvableConflict + ); + state[ruleUpgradeInfo.rule_id] = { ...ruleUpgradeInfo, fieldsUpgradeState, hasUnresolvedConflicts: isPrebuiltRulesCustomizationEnabled - ? Boolean(ruleUpgradeInfo.diff.fields.type) || - Object.values(fieldsUpgradeState).some( - ({ state: fieldState }) => - fieldState === FieldUpgradeState.SolvableConflict || - fieldState === FieldUpgradeState.NonSolvableConflict - ) + ? hasRuleTypeChange || hasFieldConflicts : false, }; } From 93701fa091adbf569056a6d286f2ef7ff1e2d32f Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Sat, 7 Dec 2024 12:46:08 +0100 Subject: [PATCH 64/77] eliminate double hasConflict calculation --- .../components/field_final_side_header.tsx | 13 ++----------- .../three_way_diff/rule_upgrade/field_upgrade.tsx | 6 +----- .../rule_upgrade/field_upgrade_context.tsx | 7 +++++++ 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx index 2c3d57c48134f..0e70689b7c9db 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_header.tsx @@ -9,7 +9,6 @@ import type { PropsWithChildren } from 'react'; import React, { useCallback } from 'react'; import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; import type { DiffableAllFields } from '../../../../../../../../common/api/detection_engine'; -import { FieldUpgradeState } from '../../../../../model/prebuilt_rule_upgrade'; import { FieldUpgradeSideHeader } from '../../field_upgrade_side_header'; import { assertUnreachable } from '../../../../../../../../common/utility_types'; import { @@ -21,17 +20,9 @@ import { FieldFinalSideHelpInfo } from './field_final_side_help_info'; import * as i18n from './translations'; export function FieldFinalSideHeader(): JSX.Element { - const { - fieldName, - fieldUpgradeState, - rightSideMode, - finalDiffableRule, - setRuleFieldResolvedValue, - } = useFieldUpgradeContext(); + const { fieldName, hasConflict, rightSideMode, finalDiffableRule, setRuleFieldResolvedValue } = + useFieldUpgradeContext(); const { form } = useFieldEditFormContext(); - const hasConflict = - fieldUpgradeState === FieldUpgradeState.SolvableConflict || - fieldUpgradeState === FieldUpgradeState.NonSolvableConflict; const handleAccept = useCallback( () => 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 263a834a26a81..45776e28e3572 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 @@ -14,14 +14,10 @@ import { FieldComparisonSide } from '../comparison_side/field_comparison_side'; import { FieldFinalSide } from '../field_final_side'; import { FieldUpgradeHeader } from './field_upgrade_header'; import { useFieldUpgradeContext } from './field_upgrade_context'; -import { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; export function FieldUpgrade(): JSX.Element { const { euiTheme } = useEuiTheme(); - const { fieldName, fieldUpgradeState, fieldDiff } = useFieldUpgradeContext(); - const hasConflict = - fieldUpgradeState === FieldUpgradeState.SolvableConflict || - fieldUpgradeState === FieldUpgradeState.NonSolvableConflict; + const { fieldName, fieldUpgradeState, hasConflict, fieldDiff } = useFieldUpgradeContext(); const isFieldCustomized = useMemo( () => fieldDiff.has_base_version 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 2dec30772efb1..51acfb663e5f9 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 @@ -33,6 +33,10 @@ interface FieldUpgradeContextType { * Field's upgrade state */ fieldUpgradeState: FieldUpgradeState; + /** + * Whether rule has an unresolved conflict. This state is derived from `fieldUpgradeState`. + */ + hasConflict: boolean; /** * Field's three way diff */ @@ -93,6 +97,9 @@ export function FieldUpgradeContextProvider({ () => ({ fieldName, fieldUpgradeState, + hasConflict: + fieldUpgradeState === FieldUpgradeState.SolvableConflict || + fieldUpgradeState === FieldUpgradeState.NonSolvableConflict, fieldDiff, finalDiffableRule: calcFinalDiffableRule(ruleUpgradeState), rightSideMode: editing ? FieldFinalSideMode.Edit : FieldFinalSideMode.Readonly, From 1c24509a12207f858f33a0ee133c841aa3ad774f Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 10 Dec 2024 17:22:43 +0100 Subject: [PATCH 65/77] fix invariant's message --- .../components/rules_table/use_rule_preview_flyout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rule_preview_flyout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rule_preview_flyout.tsx index 2578871dec9b8..0c16a5c6ed165 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rule_preview_flyout.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rule_preview_flyout.tsx @@ -74,7 +74,7 @@ export function useRulePreviewFlyout({ (ruleId: RuleSignatureId) => { const ruleToShowInFlyout = rules.find((x) => x.rule_id === ruleId); - invariant(ruleToShowInFlyout, `Rule with id ${ruleId} not found`); + invariant(ruleToShowInFlyout, `Rule with rule_id ${ruleId} not found`); setRuleForPreview(ruleToShowInFlyout); }, [rules, setRuleForPreview] From 5a5bf49bc469f8df178eb9ed80a04c158836b673 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 10 Dec 2024 17:25:31 +0100 Subject: [PATCH 66/77] remove unnecessary added fragment --- .../field_upgrade_state_info.tsx | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx index 93e0dedb0afe5..7db88260d5605 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx @@ -65,21 +65,19 @@ export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JS }, [state]); return ( - <> - - - {badge} + + + {badge} + + {title} + + + {description && ( - {title} + {i18n.SEPARATOR} {description} - - {description && ( - - {i18n.SEPARATOR} {description} - - )} - - - + )} + + ); } From 831c8a56bb7f26da26392b543304724ad149953a Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 10 Dec 2024 17:26:30 +0100 Subject: [PATCH 67/77] use invariant instead of if condition --- .../three_way_diff/rule_upgrade/field_upgrade_context.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 51acfb663e5f9..f1031dfa62bc1 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 @@ -89,9 +89,7 @@ export function FieldUpgradeContextProvider({ initialRightSideMode === FieldFinalSideMode.Edit ); - if (!fieldDiff) { - throw new Error(`Field diff is not found for ${fieldName}.`); - } + invariant(fieldDiff, `Field diff is not found for ${fieldName}.`); const contextValue: FieldUpgradeContextType = useMemo( () => ({ From 3f30fdb5581468dc69de8a47d423dec5878e0810 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 10 Dec 2024 17:31:31 +0100 Subject: [PATCH 68/77] improve readability --- .../rule_upgrade/field_upgrade_context.tsx | 12 ++++++------ .../rule_upgrade/field_upgrade_header.tsx | 4 ++-- .../field_upgrade_state_info.tsx | 14 +++++++------- .../three_way_diff/rule_upgrade/rule_upgrade.tsx | 8 ++++---- ...rade_state.ts => field_upgrade_state_enum.ts} | 2 +- .../fields_upgrade_state.ts | 9 ++++++--- .../model/prebuilt_rule_upgrade/index.ts | 2 +- .../upgrade_prebuilt_rules_table_context.tsx | 4 ++-- .../use_prebuilt_rules_upgrade_state.ts | 16 +++++++++------- 9 files changed, 38 insertions(+), 33 deletions(-) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/{field_upgrade_state.ts => field_upgrade_state_enum.ts} (92%) 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 f1031dfa62bc1..f88c9fb3e0760 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 @@ -17,7 +17,7 @@ import { convertRuleToDiffable } from '../../../../../../../common/detection_eng import type { SetRuleFieldResolvedValueFn } from '../../../../model/prebuilt_rule_upgrade/set_rule_field_resolved_value'; import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; import type { RuleUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; -import { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; +import { FieldUpgradeStateEnum } from '../../../../model/prebuilt_rule_upgrade'; export enum FieldFinalSideMode { Readonly = 'readonly', @@ -32,7 +32,7 @@ interface FieldUpgradeContextType { /** * Field's upgrade state */ - fieldUpgradeState: FieldUpgradeState; + fieldUpgradeState: FieldUpgradeStateEnum; /** * Whether rule has an unresolved conflict. This state is derived from `fieldUpgradeState`. */ @@ -81,7 +81,7 @@ export function FieldUpgradeContextProvider({ const { state: fieldUpgradeState } = ruleUpgradeState.fieldsUpgradeState[fieldName]; const fieldDiff = ruleUpgradeState.diff.fields[fieldName]; const initialRightSideMode = - fieldUpgradeState === FieldUpgradeState.NonSolvableConflict + fieldUpgradeState === FieldUpgradeStateEnum.NonSolvableConflict ? FieldFinalSideMode.Edit : FieldFinalSideMode.Readonly; @@ -96,8 +96,8 @@ export function FieldUpgradeContextProvider({ fieldName, fieldUpgradeState, hasConflict: - fieldUpgradeState === FieldUpgradeState.SolvableConflict || - fieldUpgradeState === FieldUpgradeState.NonSolvableConflict, + fieldUpgradeState === FieldUpgradeStateEnum.SolvableConflict || + fieldUpgradeState === FieldUpgradeStateEnum.NonSolvableConflict, fieldDiff, finalDiffableRule: calcFinalDiffableRule(ruleUpgradeState), rightSideMode: editing ? FieldFinalSideMode.Edit : FieldFinalSideMode.Readonly, @@ -137,7 +137,7 @@ function calcFinalDiffableRule(ruleUpgradeState: RuleUpgradeState): DiffableRule const fieldsResolvedValues = Object.entries(ruleUpgradeState.fieldsUpgradeState).reduce< Record >((result, [fieldName, fieldState]) => { - if (fieldState.state === FieldUpgradeState.Accepted) { + if (fieldState.state === FieldUpgradeStateEnum.Accepted) { result[fieldName] = fieldState.resolvedValue; } 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 8829d13d05cb4..45b88f1eb24f5 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 @@ -9,14 +9,14 @@ import React from 'react'; import { camelCase, startCase } from 'lodash'; import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; import { fieldToDisplayNameMap } from '../../diff_components/translations'; -import type { FieldUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; +import type { FieldUpgradeStateEnum } from '../../../../model/prebuilt_rule_upgrade'; import { ModifiedBadge } from '../badges/modified_badge'; import { FieldUpgradeStateInfo } from './field_upgrade_state_info'; import * as i18n from './translations'; interface FieldUpgradeHeaderProps { fieldName: string; - fieldUpgradeState: FieldUpgradeState; + fieldUpgradeState: FieldUpgradeStateEnum; /** * Whether the field was customized by users (current and base versions differ) */ diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx index 7db88260d5605..a85cf96cc50d2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx @@ -8,27 +8,27 @@ import React, { useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; import { assertUnreachable } from '../../../../../../../../common/utility_types'; -import { FieldUpgradeState } from '../../../../../model/prebuilt_rule_upgrade'; +import { FieldUpgradeStateEnum } from '../../../../../model/prebuilt_rule_upgrade'; import { ReadyForUpgradeBadge } from '../../badges/ready_for_upgrade_badge'; import { ReviewRequiredBadge } from '../../badges/review_required_badge'; import { ActionRequiredBadge } from '../../badges/action_required'; import * as i18n from './translations'; interface FieldUpgradeStateInfoProps { - state: FieldUpgradeState; + state: FieldUpgradeStateEnum; } export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JSX.Element { const { color, badge, title, description } = useMemo(() => { switch (state) { - case FieldUpgradeState.NoUpdate: + case FieldUpgradeStateEnum.NoUpdate: return { color: 'success', title: i18n.NO_UPDATE, description: i18n.NO_UPDATE_DESCRIPTION, }; - case FieldUpgradeState.NoConflict: + case FieldUpgradeStateEnum.NoConflict: return { color: 'success', badge: , @@ -36,14 +36,14 @@ export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JS description: i18n.NO_CONFLICT_DESCRIPTION, }; - case FieldUpgradeState.Accepted: + case FieldUpgradeStateEnum.Accepted: return { color: 'success', badge: , title: i18n.REVIEWED_AND_ACCEPTED, }; - case FieldUpgradeState.SolvableConflict: + case FieldUpgradeStateEnum.SolvableConflict: return { color: 'warning', badge: , @@ -51,7 +51,7 @@ export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JS description: i18n.SOLVABLE_CONFLICT_DESCRIPTION, }; - case FieldUpgradeState.NonSolvableConflict: + case FieldUpgradeStateEnum.NonSolvableConflict: return { color: 'danger', badge: , diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx index ba069e0553930..73746f3c48211 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/rule_upgrade.tsx @@ -8,7 +8,7 @@ import React, { memo } from 'react'; import { EuiSpacer } from '@elastic/eui'; import { - FieldUpgradeState, + FieldUpgradeStateEnum, type RuleUpgradeState, type SetRuleFieldResolvedValueFn, } from '../../../../model/prebuilt_rule_upgrade'; @@ -69,18 +69,18 @@ function calcTotalNumOfFields(ruleUpgradeState: RuleUpgradeState): number { function calcNumOfFieldsWithUpdates(ruleUpgradeState: RuleUpgradeState): number { return Object.values(ruleUpgradeState.fieldsUpgradeState).filter( - ({ state }) => state !== FieldUpgradeState.NoUpdate + ({ state }) => state !== FieldUpgradeStateEnum.NoUpdate ).length; } function calcNumOfSolvableConflicts(ruleUpgradeState: RuleUpgradeState): number { return Object.values(ruleUpgradeState.fieldsUpgradeState).filter( - ({ state }) => state === FieldUpgradeState.SolvableConflict + ({ state }) => state === FieldUpgradeStateEnum.SolvableConflict ).length; } function calcNumOfNonSolvableConflicts(ruleUpgradeState: RuleUpgradeState): number { return Object.values(ruleUpgradeState.fieldsUpgradeState).filter( - ({ state }) => state === FieldUpgradeState.NonSolvableConflict + ({ state }) => state === FieldUpgradeStateEnum.NonSolvableConflict ).length; } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state_enum.ts similarity index 92% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state_enum.ts index 48d27409788a9..0fd522403edc6 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state_enum.ts @@ -5,7 +5,7 @@ * 2.0. */ -export enum FieldUpgradeState { +export enum FieldUpgradeStateEnum { NoUpdate = 'NO_UPDATE', NoConflict = 'NO_CONFLICT', Accepted = 'ACCEPTED', diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/fields_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/fields_upgrade_state.ts index 075585f59f84c..88522bf559050 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/fields_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/fields_upgrade_state.ts @@ -6,12 +6,15 @@ */ import type { DiffableAllFields } from '../../../../../common/api/detection_engine'; -import type { FieldUpgradeState } from './field_upgrade_state'; +import type { FieldUpgradeStateEnum } from './field_upgrade_state_enum'; export type FieldsUpgradeState = Record< string, | { - state: Exclude; + state: Exclude; + } + | { + state: FieldUpgradeStateEnum.Accepted; + resolvedValue: DiffableAllFields[keyof DiffableAllFields]; } - | { state: FieldUpgradeState.Accepted; resolvedValue: DiffableAllFields[keyof DiffableAllFields] } >; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/index.ts index 57ee30f308f08..0e5a631fde2e2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/index.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -export * from './field_upgrade_state'; +export * from './field_upgrade_state_enum'; export * from './fields_upgrade_state'; export * from './rule_upgrade_state'; export * from './rules_upgrade_state'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx index ce60bab9af4bf..751b24f865e61 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_context.tsx @@ -27,7 +27,7 @@ import { TabContentPadding } from '../../../../rule_management/components/rule_d import { usePerformUpgradeSpecificRules } from '../../../../rule_management/logic/prebuilt_rules/use_perform_rule_upgrade'; import { usePrebuiltRulesUpgradeReview } from '../../../../rule_management/logic/prebuilt_rules/use_prebuilt_rules_upgrade_review'; import { RuleDiffTab } from '../../../../rule_management/components/rule_details/rule_diff_tab'; -import { FieldUpgradeState } from '../../../../rule_management/model/prebuilt_rule_upgrade/field_upgrade_state'; +import { FieldUpgradeStateEnum } from '../../../../rule_management/model/prebuilt_rule_upgrade/field_upgrade_state_enum'; import { useRulePreviewFlyout } from '../use_rule_preview_flyout'; import type { UpgradePrebuiltRulesTableFilterOptions } from './use_filter_prebuilt_rules_to_upgrade'; import { useFilterPrebuiltRulesToUpgrade } from './use_filter_prebuilt_rules_to_upgrade'; @@ -458,7 +458,7 @@ function constructRuleFieldsToUpgrade(ruleUpgradeState: RuleUpgradeState): RuleF for (const [fieldName, fieldUpgradeState] of Object.entries( ruleUpgradeState.fieldsUpgradeState )) { - if (fieldUpgradeState.state === FieldUpgradeState.Accepted) { + if (fieldUpgradeState.state === FieldUpgradeStateEnum.Accepted) { ruleFieldsToUpgrade[fieldName] = { pick_version: 'RESOLVED', resolved_value: fieldUpgradeState.resolvedValue, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts index 1f193ff108f59..81d64b1b39945 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts @@ -12,7 +12,7 @@ import type { FieldsUpgradeState, SetRuleFieldResolvedValueFn, } from '../../../../rule_management/model/prebuilt_rule_upgrade'; -import { FieldUpgradeState } from '../../../../rule_management/model/prebuilt_rule_upgrade'; +import { FieldUpgradeStateEnum } from '../../../../rule_management/model/prebuilt_rule_upgrade'; import { type FieldsDiff, type DiffableAllFields, @@ -62,8 +62,8 @@ export function usePrebuiltRulesUpgradeState( const hasRuleTypeChange = Boolean(ruleUpgradeInfo.diff.fields.type); const hasFieldConflicts = Object.values(fieldsUpgradeState).some( ({ state: fieldState }) => - fieldState === FieldUpgradeState.SolvableConflict || - fieldState === FieldUpgradeState.NonSolvableConflict + fieldState === FieldUpgradeStateEnum.SolvableConflict || + fieldState === FieldUpgradeStateEnum.NonSolvableConflict ); state[ruleUpgradeInfo.rule_id] = { @@ -105,16 +105,18 @@ function calcFieldsState( switch (fieldDiff.conflict) { case ThreeWayDiffConflict.NONE: fieldsState[fieldName] = { - state: fieldDiff.has_update ? FieldUpgradeState.NoConflict : FieldUpgradeState.NoUpdate, + state: fieldDiff.has_update + ? FieldUpgradeStateEnum.NoConflict + : FieldUpgradeStateEnum.NoUpdate, }; break; case ThreeWayDiffConflict.SOLVABLE: - fieldsState[fieldName] = { state: FieldUpgradeState.SolvableConflict }; + fieldsState[fieldName] = { state: FieldUpgradeStateEnum.SolvableConflict }; break; case ThreeWayDiffConflict.NON_SOLVABLE: - fieldsState[fieldName] = { state: FieldUpgradeState.NonSolvableConflict }; + fieldsState[fieldName] = { state: FieldUpgradeStateEnum.NonSolvableConflict }; break; default: @@ -123,7 +125,7 @@ function calcFieldsState( } for (const [fieldName, resolvedValue] of Object.entries(ruleResolvedConflicts)) { - fieldsState[fieldName] = { state: FieldUpgradeState.Accepted, resolvedValue }; + fieldsState[fieldName] = { state: FieldUpgradeStateEnum.Accepted, resolvedValue }; } return fieldsState; From 137c404dfdee306596e64682de395f946164872c Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 10 Dec 2024 17:34:28 +0100 Subject: [PATCH 69/77] roll back useFilterPrebuiltRulesToUpgrade changes --- .../use_filter_prebuilt_rules_to_upgrade.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_filter_prebuilt_rules_to_upgrade.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_filter_prebuilt_rules_to_upgrade.ts index eadc9b3b46d51..e78e1f90f8502 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_filter_prebuilt_rules_to_upgrade.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_filter_prebuilt_rules_to_upgrade.ts @@ -14,15 +14,15 @@ export type UpgradePrebuiltRulesTableFilterOptions = Pick< 'filter' | 'tags' | 'ruleSource' >; -interface UseFilterPrebuiltRulesToUpgradeParams { - data: T[]; +interface UseFilterPrebuiltRulesToUpgradeParams { + data: RuleUpgradeInfoForReview[]; filterOptions: UpgradePrebuiltRulesTableFilterOptions; } -export const useFilterPrebuiltRulesToUpgrade = ({ +export const useFilterPrebuiltRulesToUpgrade = ({ data, filterOptions, -}: UseFilterPrebuiltRulesToUpgradeParams): T[] => { +}: UseFilterPrebuiltRulesToUpgradeParams): RuleUpgradeInfoForReview[] => { return useMemo(() => { const { filter, tags, ruleSource } = filterOptions; From e5d13cd59503b3dbdac022ec93534d17da2c0f99 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 10 Dec 2024 17:38:30 +0100 Subject: [PATCH 70/77] remove field's Modified badge --- .../rule_upgrade/field_upgrade.tsx | 20 +++---------------- .../rule_upgrade/field_upgrade_header.tsx | 14 +------------ 2 files changed, 4 insertions(+), 30 deletions(-) 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 45776e28e3572..d7e3e33fcb5f8 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 @@ -5,10 +5,9 @@ * 2.0. */ -import React, { useMemo } from 'react'; +import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer, useEuiTheme } from '@elastic/eui'; import { css } from '@emotion/css'; -import { isEqual } from 'lodash'; import { SplitAccordion } from '../../../../../../common/components/split_accordion'; import { FieldComparisonSide } from '../comparison_side/field_comparison_side'; import { FieldFinalSide } from '../field_final_side'; @@ -17,25 +16,12 @@ import { useFieldUpgradeContext } from './field_upgrade_context'; export function FieldUpgrade(): JSX.Element { const { euiTheme } = useEuiTheme(); - const { fieldName, fieldUpgradeState, hasConflict, fieldDiff } = useFieldUpgradeContext(); - const isFieldCustomized = useMemo( - () => - fieldDiff.has_base_version - ? !isEqual(fieldDiff.base_version, fieldDiff.current_version) - : false, - [fieldDiff] - ); + const { fieldName, fieldUpgradeState, hasConflict } = 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_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 45b88f1eb24f5..b401f702bd036 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 @@ -7,26 +7,19 @@ import React from 'react'; import { camelCase, startCase } from 'lodash'; -import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; +import { EuiFlexGroup, EuiTitle } from '@elastic/eui'; import { fieldToDisplayNameMap } from '../../diff_components/translations'; import type { FieldUpgradeStateEnum } from '../../../../model/prebuilt_rule_upgrade'; -import { ModifiedBadge } from '../badges/modified_badge'; import { FieldUpgradeStateInfo } from './field_upgrade_state_info'; -import * as i18n from './translations'; interface FieldUpgradeHeaderProps { fieldName: string; fieldUpgradeState: FieldUpgradeStateEnum; - /** - * Whether the field was customized by users (current and base versions differ) - */ - isCustomized: boolean; } export function FieldUpgradeHeader({ fieldName, fieldUpgradeState, - isCustomized, }: FieldUpgradeHeaderProps): JSX.Element { return ( @@ -35,11 +28,6 @@ export function FieldUpgradeHeader({ - {isCustomized && ( - - - - )} From 907218c5ded58517aebff1c9cbf06fd51ebacd6f Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 10 Dec 2024 20:02:27 +0100 Subject: [PATCH 71/77] fix a typing issue --- .../use_filter_prebuilt_rules_to_upgrade.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_filter_prebuilt_rules_to_upgrade.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_filter_prebuilt_rules_to_upgrade.ts index e78e1f90f8502..a3dd45f8fabc0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_filter_prebuilt_rules_to_upgrade.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_filter_prebuilt_rules_to_upgrade.ts @@ -6,7 +6,7 @@ */ import { useMemo } from 'react'; -import type { RuleUpgradeInfoForReview } from '../../../../../../common/api/detection_engine/prebuilt_rules'; +import type { RuleUpgradeState } from '../../../../rule_management/model/prebuilt_rule_upgrade'; import { RuleCustomizationEnum, type FilterOptions } from '../../../../rule_management/logic/types'; export type UpgradePrebuiltRulesTableFilterOptions = Pick< @@ -15,14 +15,14 @@ export type UpgradePrebuiltRulesTableFilterOptions = Pick< >; interface UseFilterPrebuiltRulesToUpgradeParams { - data: RuleUpgradeInfoForReview[]; + data: RuleUpgradeState[]; filterOptions: UpgradePrebuiltRulesTableFilterOptions; } export const useFilterPrebuiltRulesToUpgrade = ({ data, filterOptions, -}: UseFilterPrebuiltRulesToUpgradeParams): RuleUpgradeInfoForReview[] => { +}: UseFilterPrebuiltRulesToUpgradeParams): RuleUpgradeState[] => { return useMemo(() => { const { filter, tags, ruleSource } = filterOptions; From 5a455a9f0cf5d8bdf6ec0eada53243805b8b4971 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Tue, 10 Dec 2024 20:03:13 +0100 Subject: [PATCH 72/77] Reduce number of options, update tooltips --- .../comparison_side_help_info.tsx | 64 ++----- .../comparison_side/field_comparison_side.tsx | 13 +- .../comparison_side/translations.ts | 73 ++++++++ .../versions_picker/constants.ts | 158 ++++++++++++++---- .../versions_picker/versions_picker.tsx | 16 +- .../components/field_final_side_help_info.tsx | 8 +- .../field_upgrade_state_info.tsx | 33 ++-- .../field_upgrade_state_info/translations.tsx | 15 ++ .../field_upgrade_state_enum.ts | 1 + .../use_prebuilt_rules_upgrade_state.ts | 18 +- 10 files changed, 275 insertions(+), 124 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx index 47e5e537f3ab0..7e0f0ae68b07f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx @@ -9,14 +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 { i18n } from '@kbn/i18n'; import { TITLE } from './translations'; -import { - BASE_VERSION, - CURRENT_VERSION, - FINAL_VERSION, - TARGET_VERSION, -} from './versions_picker/translations'; /** * Theme doesn't expose width variables. Using provided size variables will require @@ -27,7 +20,11 @@ import { */ const POPOVER_WIDTH = 320; -export function ComparisonSideHelpInfo(): JSX.Element { +interface ComparisonSideHelpInfoProps { + options: Array<{ value: string; text: string; title: string }>; +} + +export function ComparisonSideHelpInfo({ options }: ComparisonSideHelpInfoProps): JSX.Element { const [isPopoverOpen, togglePopover] = useToggle(false); const button = ( @@ -43,25 +40,18 @@ export function ComparisonSideHelpInfo(): JSX.Element { {TITLE}
, versions: ( <>
    -
  • - {BASE_VERSION} {'-'} {BASE_VERSION_EXPLANATION} -
  • -
  • - {CURRENT_VERSION} {'-'} {CURRENT_VERSION_EXPLANATION} -
  • -
  • - {TARGET_VERSION} {'-'} {TARGET_VERSION_EXPLANATION} -
  • -
  • - {FINAL_VERSION} {'-'} {FINAL_VERSION_EXPLANATION} -
  • + {options.map((option) => ( +
  • + {option.text} {'-'} {option.title} +
  • + ))}
), @@ -71,35 +61,3 @@ export function ComparisonSideHelpInfo(): JSX.Element { ); } - -const BASE_VERSION_EXPLANATION = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.baseVersionExplanation', - { - defaultMessage: 'version originally installed from Elastic prebuilt rules package', - } -); - -const CURRENT_VERSION_EXPLANATION = ( - {BASE_VERSION}, - }} - /> -); - -const TARGET_VERSION_EXPLANATION = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.targetVersionExplanation', - { - defaultMessage: 'version coming from a new version of Elastic prebuilt rules package', - } -); - -const FINAL_VERSION_EXPLANATION = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.finalVersionExplanation', - { - defaultMessage: - 'version used to the update the rule. Initial value is suggested by the diff algorithm.', - } -); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx index 0b9b37c91e226..bbbc8c581282e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx @@ -8,8 +8,8 @@ import React, { useState } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; import { VersionsPicker } from './versions_picker/versions_picker'; -import type { Version } from './versions_picker/constants'; -import { SelectedVersions } from './versions_picker/constants'; +import type { Version, SelectedVersions } from './versions_picker/constants'; +import { getOptionsForDiffOutcome } from './versions_picker/constants'; import { FieldUpgradeSideHeader } from '../field_upgrade_side_header'; import { useFieldUpgradeContext } from '../rule_upgrade/field_upgrade_context'; import { pickFieldValueForVersion } from './utils'; @@ -22,9 +22,8 @@ export function FieldComparisonSide(): JSX.Element { const { fieldName, fieldDiff, finalDiffableRule } = useFieldUpgradeContext(); const resolvedValue = finalDiffableRule[fieldName]; - const [selectedVersions, setSelectedVersions] = useState( - SelectedVersions.CurrentFinal - ); + const options = getOptionsForDiffOutcome(fieldDiff, resolvedValue); + const [selectedVersions, setSelectedVersions] = useState(options[0].value); const [oldVersionType, newVersionType] = selectedVersions.split('_') as [Version, Version]; @@ -42,13 +41,13 @@ export function FieldComparisonSide(): JSX.Element {

{i18n.TITLE} - +

diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/translations.ts index 8208892ac298d..dadf5c0e572a2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/translations.ts @@ -6,6 +6,7 @@ */ import { i18n } from '@kbn/i18n'; +import { FINAL_UPDATE } from '../field_final_side/components/translations'; export const TITLE = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.comparisonSide.title', @@ -20,3 +21,75 @@ export const NO_CHANGES = i18n.translate( defaultMessage: 'No changes', } ); + +export const UPDATE_FROM_ELASTIC_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.updateFromElasticTitle', + { + defaultMessage: 'Update 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', + } +); + +export const MY_CHANGES_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myChangesTitle', + { + defaultMessage: 'My changes', + } +); + +export const MY_CHANGES_EXPLANATION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myChangesExplanation', + { + defaultMessage: `view what you have changed in your installed rule and in the {finalUpdateSectionLabel} section`, + values: { + finalUpdateSectionLabel: FINAL_UPDATE, + }, + } +); + +export const MY_CHANGES_FINAL_UPDATE_ONLY_EXPLANATION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myChangesFinalUpdateOnlyExplanation', + { + defaultMessage: `view the changes you made in the {finalUpdateSectionLabel} section`, + values: { + finalUpdateSectionLabel: FINAL_UPDATE, + }, + } +); + +export const MERGED_CHANGES_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.mergedChangesTitle', + { + 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', + } +); + +export const MY_CUSTOMIZATION_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myCustomizationTitle', + { + defaultMessage: 'My customization', + } +); + +export const MY_CUSTOMIZATION_EXPLANATION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myCustomizationExplanation', + { + defaultMessage: `view what you have changed in your installed rule. Doesn’t include changes made in the {finalUpdateSectionLabel} section.`, + values: { + finalUpdateSectionLabel: FINAL_UPDATE, + }, + } +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts index 04d38ed10dce2..3a5c7e818c7f3 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts @@ -5,8 +5,13 @@ * 2.0. */ -import type { EuiSelectOption } from '@elastic/eui'; -import * as i18n from './translations'; +import { isEqual } from 'lodash'; +import type { ThreeWayDiff } from '../../../../../../../../common/api/detection_engine'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, +} from '../../../../../../../../common/api/detection_engine'; +import * as i18n from '../translations'; export enum Version { Base = 'base', @@ -24,35 +29,120 @@ export enum SelectedVersions { TargetFinal = 'target_final', } -export const CURRENT_OPTIONS: EuiSelectOption[] = [ - { - value: SelectedVersions.CurrentFinal, - text: i18n.VERSION1_VS_VERSION2(i18n.CURRENT_VERSION, i18n.FINAL_VERSION), - }, - { - value: SelectedVersions.CurrentTarget, - text: i18n.VERSION1_VS_VERSION2(i18n.CURRENT_VERSION, i18n.TARGET_VERSION), - }, -]; - -export const TARGET_OPTIONS: EuiSelectOption[] = [ - { - value: SelectedVersions.TargetFinal, - text: i18n.VERSION1_VS_VERSION2(i18n.TARGET_VERSION, i18n.FINAL_VERSION), - }, -]; - -export const BASE_OPTIONS: EuiSelectOption[] = [ - { - value: SelectedVersions.BaseFinal, - text: i18n.VERSION1_VS_VERSION2(i18n.BASE_VERSION, i18n.FINAL_VERSION), - }, - { - value: SelectedVersions.BaseTarget, - text: i18n.VERSION1_VS_VERSION2(i18n.BASE_VERSION, i18n.TARGET_VERSION), - }, - { - value: SelectedVersions.BaseCurrent, - text: i18n.VERSION1_VS_VERSION2(i18n.BASE_VERSION, i18n.CURRENT_VERSION), - }, -]; +export const getOptionsForDiffOutcome = ( + fieldDiff: ThreeWayDiff, + resolvedValue: unknown +): Array<{ value: SelectedVersions; text: string; title: string }> => { + switch (fieldDiff.diff_outcome) { + case ThreeWayDiffOutcome.StockValueCanUpdate: { + const hasUserChangedResolvedValue = !isEqual(fieldDiff.merged_version, resolvedValue); + + const options = [ + { + value: SelectedVersions.CurrentTarget, + text: i18n.UPDATE_FROM_ELASTIC_TITLE, + title: i18n.UPDATE_FROM_ELASTIC_EXPLANATION, + }, + ]; + + if (hasUserChangedResolvedValue) { + options.push({ + value: SelectedVersions.CurrentFinal, + text: i18n.MY_CHANGES_TITLE, + title: i18n.MY_CHANGES_FINAL_UPDATE_ONLY_EXPLANATION, + }); + } + + return options; + } + case ThreeWayDiffOutcome.CustomizedValueNoUpdate: + return [ + { + value: SelectedVersions.BaseFinal, + text: i18n.MY_CHANGES_TITLE, + title: i18n.MY_CHANGES_EXPLANATION, + }, + ]; + case ThreeWayDiffOutcome.CustomizedValueSameUpdate: + return [ + { + value: SelectedVersions.BaseFinal, + text: i18n.MY_CHANGES_TITLE, + title: i18n.MY_CHANGES_EXPLANATION, + }, + { + value: SelectedVersions.BaseTarget, + text: i18n.UPDATE_FROM_ELASTIC_TITLE, + title: i18n.UPDATE_FROM_ELASTIC_EXPLANATION, + }, + ]; + case ThreeWayDiffOutcome.CustomizedValueCanUpdate: { + const hasUserChangedResolvedValue = !isEqual(fieldDiff.merged_version, resolvedValue); + + if (fieldDiff.conflict === ThreeWayDiffConflict.SOLVABLE) { + return [ + { + value: SelectedVersions.BaseFinal, + text: hasUserChangedResolvedValue ? i18n.MY_CHANGES_TITLE : i18n.MERGED_CHANGES_TITLE, + title: hasUserChangedResolvedValue + ? i18n.MY_CHANGES_FINAL_UPDATE_ONLY_EXPLANATION + : i18n.MERGED_CHANGES_EXPLANATION, + }, + { + value: SelectedVersions.BaseTarget, + text: i18n.UPDATE_FROM_ELASTIC_TITLE, + title: i18n.UPDATE_FROM_ELASTIC_EXPLANATION, + }, + { + value: SelectedVersions.BaseCurrent, + text: i18n.MY_CUSTOMIZATION_TITLE, + title: i18n.MY_CUSTOMIZATION_EXPLANATION, + }, + ]; + } + + if (fieldDiff.conflict === ThreeWayDiffConflict.NON_SOLVABLE) { + return [ + { + value: SelectedVersions.BaseFinal, + text: i18n.MY_CHANGES_TITLE, + title: i18n.MY_CHANGES_EXPLANATION, + }, + { + value: SelectedVersions.BaseTarget, + text: i18n.UPDATE_FROM_ELASTIC_TITLE, + title: i18n.UPDATE_FROM_ELASTIC_EXPLANATION, + }, + { + value: SelectedVersions.BaseCurrent, + text: i18n.MY_CUSTOMIZATION_TITLE, + title: i18n.MY_CUSTOMIZATION_EXPLANATION, + }, + ]; + } + } + case ThreeWayDiffOutcome.MissingBaseCanUpdate: { + const hasUserChangedResolvedValue = !isEqual(fieldDiff.merged_version, resolvedValue); + + const options = [ + { + value: SelectedVersions.CurrentTarget, + text: i18n.UPDATE_FROM_ELASTIC_TITLE, + title: i18n.UPDATE_FROM_ELASTIC_EXPLANATION, + }, + ]; + + if (hasUserChangedResolvedValue) { + options.push({ + value: SelectedVersions.CurrentFinal, + text: i18n.MY_CHANGES_TITLE, + title: i18n.MY_CHANGES_FINAL_UPDATE_ONLY_EXPLANATION, + }); + } + + return options; + } + default: + return []; + } +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx index 4710667e0b315..b31a8318c6d35 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx @@ -5,29 +5,23 @@ * 2.0. */ -import React, { useCallback, useMemo } from 'react'; +import React, { useCallback } from 'react'; import { css } from '@emotion/css'; import { EuiSelect } from '@elastic/eui'; -import type { EuiSelectOption } from '@elastic/eui'; -import { BASE_OPTIONS, CURRENT_OPTIONS, TARGET_OPTIONS, SelectedVersions } from './constants'; +import { SelectedVersions } from './constants'; import * as i18n from './translations'; interface VersionsPickerProps { - hasBaseVersion: boolean; + options: Array<{ value: SelectedVersions; text: string; title: string }>; selectedVersions: SelectedVersions; onChange: (pickedVersions: SelectedVersions) => void; } export function VersionsPicker({ - hasBaseVersion, + options, selectedVersions = SelectedVersions.CurrentFinal, onChange, }: VersionsPickerProps) { - const options: EuiSelectOption[] = useMemo( - () => [...CURRENT_OPTIONS, ...TARGET_OPTIONS, ...(hasBaseVersion ? BASE_OPTIONS : [])], - [hasBaseVersion] - ); - const handleChange = useCallback( (changeEvent: React.ChangeEvent) => { onChange(changeEvent.target.value as SelectedVersions); @@ -49,5 +43,5 @@ export function VersionsPicker({ const VERSIONS_PICKER_STYLES = css` // Set min-width a bit wider than default // to make English text in narrow screens readable - min-width: 220px; + min-width: 300px; `; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_help_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_help_info.tsx index e3e0b38da7d63..ef8cfc820535d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_help_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/field_final_side/components/field_final_side_help_info.tsx @@ -9,6 +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'; /** * Theme doesn't expose width variables. Using provided size variables will require @@ -34,8 +35,11 @@ export function FieldFinalSideHelpInfo(): JSX.Element { {i18n.UPDATE_BUTTON_LABEL}, + }} /> diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx index a85cf96cc50d2..e57ed41042e33 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/field_upgrade_state_info.tsx @@ -28,6 +28,13 @@ export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JS description: i18n.NO_UPDATE_DESCRIPTION, }; + case FieldUpgradeStateEnum.SameUpdate: + return { + color: 'success', + title: i18n.SAME_UPDATE, + description: i18n.SAME_UPDATE_DESCRIPTION, + }; + case FieldUpgradeStateEnum.NoConflict: return { color: 'success', @@ -65,19 +72,21 @@ export function FieldUpgradeStateInfo({ state }: FieldUpgradeStateInfoProps): JS }, [state]); return ( - - - {badge} - - {title} - - - {description && ( + <> + + + {badge} - {i18n.SEPARATOR} {description} + {title} - )} - - + + {description && ( + + {i18n.SEPARATOR} {description} + + )} + + + ); } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/translations.tsx index c3115c6ce0925..0b67f590d3f64 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/translations.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade/field_upgrade_state_info/translations.tsx @@ -22,6 +22,21 @@ export const NO_UPDATE_DESCRIPTION = i18n.translate( } ); +export const SAME_UPDATE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.sameUpdate', + { + defaultMessage: 'Matching update', + } +); + +export const SAME_UPDATE_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.sameUpdateDescription', + { + defaultMessage: + 'The field was modified after rule installation, and your changes are the same as the update from Elastic.', + } +); + export const NO_CONFLICT = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.fieldUpgradeState.noConflict', { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state_enum.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state_enum.ts index 0fd522403edc6..241bb1221a6f3 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state_enum.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/field_upgrade_state_enum.ts @@ -7,6 +7,7 @@ export enum FieldUpgradeStateEnum { NoUpdate = 'NO_UPDATE', + SameUpdate = 'SAME_UPDATE', NoConflict = 'NO_CONFLICT', Accepted = 'ACCEPTED', SolvableConflict = 'SOLVABLE_CONFLICT', diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts index 81d64b1b39945..3412947426301 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state.ts @@ -20,6 +20,7 @@ import { ThreeWayDiffConflict, type RuleSignatureId, NON_UPGRADEABLE_DIFFABLE_FIELDS, + ThreeWayDiffOutcome, } from '../../../../../../common/api/detection_engine'; import { assertUnreachable } from '../../../../../../common/utility_types'; @@ -104,11 +105,18 @@ function calcFieldsState( switch (fieldDiff.conflict) { case ThreeWayDiffConflict.NONE: - fieldsState[fieldName] = { - state: fieldDiff.has_update - ? FieldUpgradeStateEnum.NoConflict - : FieldUpgradeStateEnum.NoUpdate, - }; + if (fieldDiff.has_update) { + fieldsState[fieldName] = { + state: FieldUpgradeStateEnum.NoConflict, + }; + } else { + fieldsState[fieldName] = { + state: + fieldDiff.diff_outcome === ThreeWayDiffOutcome.CustomizedValueSameUpdate + ? FieldUpgradeStateEnum.SameUpdate + : FieldUpgradeStateEnum.NoUpdate, + }; + } break; case ThreeWayDiffConflict.SOLVABLE: From 3d335214db6b8b9beec5aba4c418467ba1628ee3 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Thu, 12 Dec 2024 16:43:14 +0100 Subject: [PATCH 73/77] Move `hasResolvedValueDifferentFromSuggested` calculation into a `FieldUpgradeContext` --- .../comparison_side/field_comparison_side.tsx | 5 ++-- .../versions_picker/constants.ts | 23 ++++++++----------- .../rule_upgrade/field_upgrade_context.tsx | 16 +++++++++++-- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx index bbbc8c581282e..3826b9c8009f7 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx @@ -19,10 +19,11 @@ import { ComparisonSideHelpInfo } from './comparison_side_help_info'; import * as i18n from './translations'; export function FieldComparisonSide(): JSX.Element { - const { fieldName, fieldDiff, finalDiffableRule } = useFieldUpgradeContext(); + const { fieldName, fieldDiff, finalDiffableRule, hasResolvedValueDifferentFromSuggested } = + useFieldUpgradeContext(); const resolvedValue = finalDiffableRule[fieldName]; - const options = getOptionsForDiffOutcome(fieldDiff, resolvedValue); + const options = getOptionsForDiffOutcome(fieldDiff, hasResolvedValueDifferentFromSuggested); const [selectedVersions, setSelectedVersions] = useState(options[0].value); const [oldVersionType, newVersionType] = selectedVersions.split('_') as [Version, Version]; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts index 3a5c7e818c7f3..616817a9ef78a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { isEqual } from 'lodash'; import type { ThreeWayDiff } from '../../../../../../../../common/api/detection_engine'; import { ThreeWayDiffConflict, @@ -31,23 +30,21 @@ export enum SelectedVersions { export const getOptionsForDiffOutcome = ( fieldDiff: ThreeWayDiff, - resolvedValue: unknown + hasResolvedValueDifferentFromSuggested: boolean ): Array<{ value: SelectedVersions; text: string; title: string }> => { switch (fieldDiff.diff_outcome) { case ThreeWayDiffOutcome.StockValueCanUpdate: { - const hasUserChangedResolvedValue = !isEqual(fieldDiff.merged_version, resolvedValue); - const options = [ { - value: SelectedVersions.CurrentTarget, + value: SelectedVersions.BaseTarget, text: i18n.UPDATE_FROM_ELASTIC_TITLE, title: i18n.UPDATE_FROM_ELASTIC_EXPLANATION, }, ]; - if (hasUserChangedResolvedValue) { + if (hasResolvedValueDifferentFromSuggested) { options.push({ - value: SelectedVersions.CurrentFinal, + value: SelectedVersions.BaseFinal, text: i18n.MY_CHANGES_TITLE, title: i18n.MY_CHANGES_FINAL_UPDATE_ONLY_EXPLANATION, }); @@ -77,14 +74,14 @@ export const getOptionsForDiffOutcome = ( }, ]; case ThreeWayDiffOutcome.CustomizedValueCanUpdate: { - const hasUserChangedResolvedValue = !isEqual(fieldDiff.merged_version, resolvedValue); - if (fieldDiff.conflict === ThreeWayDiffConflict.SOLVABLE) { return [ { value: SelectedVersions.BaseFinal, - text: hasUserChangedResolvedValue ? i18n.MY_CHANGES_TITLE : i18n.MERGED_CHANGES_TITLE, - title: hasUserChangedResolvedValue + text: hasResolvedValueDifferentFromSuggested + ? i18n.MY_CHANGES_TITLE + : i18n.MERGED_CHANGES_TITLE, + title: hasResolvedValueDifferentFromSuggested ? i18n.MY_CHANGES_FINAL_UPDATE_ONLY_EXPLANATION : i18n.MERGED_CHANGES_EXPLANATION, }, @@ -122,8 +119,6 @@ export const getOptionsForDiffOutcome = ( } } case ThreeWayDiffOutcome.MissingBaseCanUpdate: { - const hasUserChangedResolvedValue = !isEqual(fieldDiff.merged_version, resolvedValue); - const options = [ { value: SelectedVersions.CurrentTarget, @@ -132,7 +127,7 @@ export const getOptionsForDiffOutcome = ( }, ]; - if (hasUserChangedResolvedValue) { + if (hasResolvedValueDifferentFromSuggested) { options.push({ value: SelectedVersions.CurrentFinal, text: i18n.MY_CHANGES_TITLE, 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..5c87712bda945 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 @@ -6,6 +6,7 @@ */ import React, { createContext, useContext, useMemo } from 'react'; +import { isEqual } from 'lodash'; import { useBoolean } from '@kbn/react-hooks'; import type { DiffableRule, @@ -37,6 +38,11 @@ interface FieldUpgradeContextType { * Whether rule has an unresolved conflict. This state is derived from `fieldUpgradeState`. */ hasConflict: boolean; + /** + * Whether field value is different from Elastic's suggestion. + * It's true only if user has made changes to the suggested field value. + */ + hasResolvedValueDifferentFromSuggested: boolean; /** * Field's three way diff */ @@ -91,6 +97,8 @@ export function FieldUpgradeContextProvider({ invariant(fieldDiff, `Field diff is not found for ${fieldName}.`); + const finalDiffableRule = calcFinalDiffableRule(ruleUpgradeState); + const contextValue: FieldUpgradeContextType = useMemo( () => ({ fieldName, @@ -98,8 +106,12 @@ export function FieldUpgradeContextProvider({ hasConflict: fieldUpgradeState === FieldUpgradeStateEnum.SolvableConflict || fieldUpgradeState === FieldUpgradeStateEnum.NonSolvableConflict, + hasResolvedValueDifferentFromSuggested: !isEqual( + fieldDiff.merged_version, + finalDiffableRule[fieldName] + ), fieldDiff, - finalDiffableRule: calcFinalDiffableRule(ruleUpgradeState), + finalDiffableRule, rightSideMode: editing ? FieldFinalSideMode.Edit : FieldFinalSideMode.Readonly, setRuleFieldResolvedValue, setReadOnlyMode, @@ -109,7 +121,7 @@ export function FieldUpgradeContextProvider({ fieldName, fieldUpgradeState, fieldDiff, - ruleUpgradeState, + finalDiffableRule, editing, setRuleFieldResolvedValue, setReadOnlyMode, From 19ba5ec1fd4b38b787ffdfecafcd3a99907a3206 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Thu, 12 Dec 2024 16:48:11 +0100 Subject: [PATCH 74/77] Rename "My customization" -> "My original changes" --- .../three_way_diff/comparison_side/translations.ts | 8 ++++---- .../comparison_side/versions_picker/constants.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/translations.ts index dadf5c0e572a2..643661b192edb 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/translations.ts @@ -77,14 +77,14 @@ export const MERGED_CHANGES_EXPLANATION = i18n.translate( } ); -export const MY_CUSTOMIZATION_TITLE = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myCustomizationTitle', +export const MY_ORIGINAL_CHANGES_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myOriginalChangesTitle', { - defaultMessage: 'My customization', + defaultMessage: 'My original changes', } ); -export const MY_CUSTOMIZATION_EXPLANATION = i18n.translate( +export const MY_ORIGINAL_CHANGES_EXPLANATION = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myCustomizationExplanation', { defaultMessage: `view what you have changed in your installed rule. Doesn’t include changes made in the {finalUpdateSectionLabel} section.`, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts index 616817a9ef78a..c60e3b68651e3 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts @@ -92,8 +92,8 @@ export const getOptionsForDiffOutcome = ( }, { value: SelectedVersions.BaseCurrent, - text: i18n.MY_CUSTOMIZATION_TITLE, - title: i18n.MY_CUSTOMIZATION_EXPLANATION, + text: i18n.MY_ORIGINAL_CHANGES_TITLE, + title: i18n.MY_ORIGINAL_CHANGES_EXPLANATION, }, ]; } @@ -112,8 +112,8 @@ export const getOptionsForDiffOutcome = ( }, { value: SelectedVersions.BaseCurrent, - text: i18n.MY_CUSTOMIZATION_TITLE, - title: i18n.MY_CUSTOMIZATION_EXPLANATION, + text: i18n.MY_ORIGINAL_CHANGES_TITLE, + title: i18n.MY_ORIGINAL_CHANGES_EXPLANATION, }, ]; } From 5b852eed29f8c16b8581c39fa3da46b1236e8c96 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Thu, 12 Dec 2024 17:23:39 +0100 Subject: [PATCH 75/77] Add "My original changes" only in case ABC-NS --- .../comparison_side/versions_picker/constants.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts index c60e3b68651e3..445e7ece616a2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts @@ -99,7 +99,7 @@ export const getOptionsForDiffOutcome = ( } if (fieldDiff.conflict === ThreeWayDiffConflict.NON_SOLVABLE) { - return [ + const options = [ { value: SelectedVersions.BaseFinal, text: i18n.MY_CHANGES_TITLE, @@ -110,12 +110,17 @@ export const getOptionsForDiffOutcome = ( text: i18n.UPDATE_FROM_ELASTIC_TITLE, title: i18n.UPDATE_FROM_ELASTIC_EXPLANATION, }, - { + ]; + + if (hasResolvedValueDifferentFromSuggested) { + options.push({ value: SelectedVersions.BaseCurrent, text: i18n.MY_ORIGINAL_CHANGES_TITLE, title: i18n.MY_ORIGINAL_CHANGES_EXPLANATION, - }, - ]; + }); + } + + return options; } } case ThreeWayDiffOutcome.MissingBaseCanUpdate: { From 555c39a68633c4f3fceb75138f809a40e4e053d1 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Fri, 13 Dec 2024 13:48:19 +0100 Subject: [PATCH 76/77] Refactor `VersionsPicker` and related components --- .../comparison_side_help_info.tsx | 22 ++- .../comparison_side/field_comparison_side.tsx | 29 ++-- .../three_way_diff/comparison_side/utils.ts | 130 ++++++++++++++++- .../versions_picker/constants.ts | 135 ------------------ .../versions_picker.stories.tsx | 36 ++--- .../versions_picker/versions_picker.tsx | 61 ++++++-- 6 files changed, 226 insertions(+), 187 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx index 7e0f0ae68b07f..2c40b6fb1683e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx @@ -10,6 +10,9 @@ 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 type { VersionsPickerOption } from './versions_picker/versions_picker'; +import { useFieldUpgradeContext } from '../rule_upgrade/field_upgrade_context'; +import { getOptionDetails } from './utils'; /** * Theme doesn't expose width variables. Using provided size variables will require @@ -21,12 +24,17 @@ import { TITLE } from './translations'; const POPOVER_WIDTH = 320; interface ComparisonSideHelpInfoProps { - options: Array<{ value: string; text: string; title: string }>; + options: VersionsPickerOption[]; } export function ComparisonSideHelpInfo({ options }: ComparisonSideHelpInfoProps): JSX.Element { const [isPopoverOpen, togglePopover] = useToggle(false); + const { hasResolvedValueDifferentFromSuggested } = useFieldUpgradeContext(); + const optionsWithDescriptions = options.map((option) => + getOptionDetails(option, hasResolvedValueDifferentFromSuggested) + ); + const button = (
    - {options.map((option) => ( -
  • - {option.text} {'-'} {option.title} -
  • - ))} + {optionsWithDescriptions.map( + ({ title: displayName, description: explanation }) => ( +
  • + {displayName} {'-'} {explanation} +
  • + ) + )}
), diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx index 3826b9c8009f7..aa4e3f952d6b5 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx @@ -7,12 +7,15 @@ import React, { useState } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; +import type { VersionsPickerOption } from './versions_picker/versions_picker'; import { VersionsPicker } from './versions_picker/versions_picker'; -import type { Version, SelectedVersions } from './versions_picker/constants'; -import { getOptionsForDiffOutcome } from './versions_picker/constants'; import { FieldUpgradeSideHeader } from '../field_upgrade_side_header'; import { useFieldUpgradeContext } from '../rule_upgrade/field_upgrade_context'; -import { pickFieldValueForVersion } from './utils'; +import { + getComparisonOptionsForDiffOutcome, + getVersionsForComparison, + pickFieldValueForVersion, +} from './utils'; import { getSubfieldChanges } from './get_subfield_changes'; import { SubfieldChanges } from './subfield_changes'; import { ComparisonSideHelpInfo } from './comparison_side_help_info'; @@ -23,13 +26,19 @@ export function FieldComparisonSide(): JSX.Element { useFieldUpgradeContext(); const resolvedValue = finalDiffableRule[fieldName]; - const options = getOptionsForDiffOutcome(fieldDiff, hasResolvedValueDifferentFromSuggested); - const [selectedVersions, setSelectedVersions] = useState(options[0].value); + const options = getComparisonOptionsForDiffOutcome( + fieldDiff.diff_outcome, + fieldDiff.conflict, + hasResolvedValueDifferentFromSuggested + ); + const [selectedOption, setSelectedOption] = useState(options[0]); - const [oldVersionType, newVersionType] = selectedVersions.split('_') as [Version, Version]; + const [oldVersionType, newVersionType] = getVersionsForComparison( + selectedOption, + fieldDiff.has_base_version + ); const oldFieldValue = pickFieldValueForVersion(oldVersionType, fieldDiff, resolvedValue); - const newFieldValue = pickFieldValueForVersion(newVersionType, fieldDiff, resolvedValue); const subfieldChanges = getSubfieldChanges(fieldName, oldFieldValue, newFieldValue); @@ -49,8 +58,10 @@ export function FieldComparisonSide(): JSX.Element { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts index 8f97d3462d358..687cf9b6381e5 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts @@ -7,7 +7,14 @@ import stringify from 'json-stable-stringify'; import { Version } from './versions_picker/constants'; -import type { ThreeWayDiff } from '../../../../../../../common/api/detection_engine'; +import { + ThreeWayDiffOutcome, + type ThreeWayDiff, + ThreeWayDiffConflict, +} from '../../../../../../../common/api/detection_engine'; +import { VersionsPickerOption } from './versions_picker/versions_picker'; +import { assertUnreachable } from '../../../../../../../common/utility_types'; +import * as i18n from './translations'; /** * Picks the field value for a given version either from a three-way diff object or from a user-set resolved value. @@ -44,3 +51,124 @@ export const stringifyToSortedJson = (fieldValue: unknown): string => { return stringify(fieldValue, { space: 2 }); }; + +interface OptionDetails { + title: string; + description: string; +} + +/** + * Returns the title and description for a given versions picker option. + */ +export function getOptionDetails( + option: VersionsPickerOption, + hasResolvedValueDifferentFromSuggested: boolean +): OptionDetails { + switch (option) { + case VersionsPickerOption.MyChanges: + return hasResolvedValueDifferentFromSuggested + ? { + title: i18n.MY_CHANGES_TITLE, + description: i18n.MY_CHANGES_FINAL_UPDATE_ONLY_EXPLANATION, + } + : { + title: i18n.MY_CHANGES_TITLE, + description: i18n.MY_CHANGES_EXPLANATION, + }; + case VersionsPickerOption.MyOriginalChanges: + return { + title: i18n.MY_ORIGINAL_CHANGES_TITLE, + description: i18n.MY_ORIGINAL_CHANGES_EXPLANATION, + }; + case VersionsPickerOption.UpdateFromElastic: + return { + title: i18n.UPDATE_FROM_ELASTIC_TITLE, + description: i18n.UPDATE_FROM_ELASTIC_EXPLANATION, + }; + case VersionsPickerOption.Merged: + return { + title: i18n.MERGED_CHANGES_TITLE, + description: i18n.MERGED_CHANGES_EXPLANATION, + }; + default: + return assertUnreachable(option); + } +} + +/** + * Returns the versions to be compared based on the selected versions picker option. + */ +export function getVersionsForComparison( + selectedOption: VersionsPickerOption, + hasBaseVersion: boolean +): [Version, Version] { + switch (selectedOption) { + case VersionsPickerOption.MyChanges: + return hasBaseVersion ? [Version.Base, Version.Final] : [Version.Current, Version.Final]; + case VersionsPickerOption.MyOriginalChanges: + return [Version.Base, Version.Current]; + case VersionsPickerOption.UpdateFromElastic: + return hasBaseVersion ? [Version.Base, Version.Target] : [Version.Current, Version.Target]; + case VersionsPickerOption.Merged: + return [Version.Base, Version.Target]; + default: + return assertUnreachable(selectedOption); + } +} + +/** + * Returns the versions picker options available for a given field diff outcome. + */ +export const getComparisonOptionsForDiffOutcome = ( + diffOutcome: ThreeWayDiffOutcome, + conflict: ThreeWayDiffConflict, + hasResolvedValueDifferentFromSuggested: boolean +): VersionsPickerOption[] => { + switch (diffOutcome) { + case ThreeWayDiffOutcome.StockValueCanUpdate: { + const options = [VersionsPickerOption.UpdateFromElastic]; + + if (hasResolvedValueDifferentFromSuggested) { + options.push(VersionsPickerOption.MyChanges); + } + + return options; + } + case ThreeWayDiffOutcome.CustomizedValueNoUpdate: + return [VersionsPickerOption.MyChanges]; + case ThreeWayDiffOutcome.CustomizedValueSameUpdate: + return [VersionsPickerOption.MyChanges, VersionsPickerOption.UpdateFromElastic]; + case ThreeWayDiffOutcome.CustomizedValueCanUpdate: { + if (conflict === ThreeWayDiffConflict.SOLVABLE) { + return [ + hasResolvedValueDifferentFromSuggested + ? VersionsPickerOption.MyChanges + : VersionsPickerOption.Merged, + VersionsPickerOption.UpdateFromElastic, + VersionsPickerOption.MyOriginalChanges, + ]; + } + + if (conflict === ThreeWayDiffConflict.NON_SOLVABLE) { + const options = [VersionsPickerOption.MyChanges, VersionsPickerOption.UpdateFromElastic]; + + if (hasResolvedValueDifferentFromSuggested) { + options.push(VersionsPickerOption.MyOriginalChanges); + } + + return options; + } + } + case ThreeWayDiffOutcome.MissingBaseCanUpdate: { + const options = [VersionsPickerOption.UpdateFromElastic]; + + if (hasResolvedValueDifferentFromSuggested) { + options.push(VersionsPickerOption.MyChanges); + } + + return options; + } + default: + return []; + } +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts index 445e7ece616a2..9c6292451b47b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/constants.ts @@ -5,144 +5,9 @@ * 2.0. */ -import type { ThreeWayDiff } from '../../../../../../../../common/api/detection_engine'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, -} from '../../../../../../../../common/api/detection_engine'; -import * as i18n from '../translations'; - export enum Version { Base = 'base', Current = 'current', Target = 'target', Final = 'final', } - -export enum SelectedVersions { - BaseTarget = 'base_target', - BaseCurrent = 'base_current', - BaseFinal = 'base_final', - CurrentTarget = 'current_target', - CurrentFinal = 'current_final', - TargetFinal = 'target_final', -} - -export const getOptionsForDiffOutcome = ( - fieldDiff: ThreeWayDiff, - hasResolvedValueDifferentFromSuggested: boolean -): Array<{ value: SelectedVersions; text: string; title: string }> => { - switch (fieldDiff.diff_outcome) { - case ThreeWayDiffOutcome.StockValueCanUpdate: { - const options = [ - { - value: SelectedVersions.BaseTarget, - text: i18n.UPDATE_FROM_ELASTIC_TITLE, - title: i18n.UPDATE_FROM_ELASTIC_EXPLANATION, - }, - ]; - - if (hasResolvedValueDifferentFromSuggested) { - options.push({ - value: SelectedVersions.BaseFinal, - text: i18n.MY_CHANGES_TITLE, - title: i18n.MY_CHANGES_FINAL_UPDATE_ONLY_EXPLANATION, - }); - } - - return options; - } - case ThreeWayDiffOutcome.CustomizedValueNoUpdate: - return [ - { - value: SelectedVersions.BaseFinal, - text: i18n.MY_CHANGES_TITLE, - title: i18n.MY_CHANGES_EXPLANATION, - }, - ]; - case ThreeWayDiffOutcome.CustomizedValueSameUpdate: - return [ - { - value: SelectedVersions.BaseFinal, - text: i18n.MY_CHANGES_TITLE, - title: i18n.MY_CHANGES_EXPLANATION, - }, - { - value: SelectedVersions.BaseTarget, - text: i18n.UPDATE_FROM_ELASTIC_TITLE, - title: i18n.UPDATE_FROM_ELASTIC_EXPLANATION, - }, - ]; - case ThreeWayDiffOutcome.CustomizedValueCanUpdate: { - if (fieldDiff.conflict === ThreeWayDiffConflict.SOLVABLE) { - return [ - { - value: SelectedVersions.BaseFinal, - text: hasResolvedValueDifferentFromSuggested - ? i18n.MY_CHANGES_TITLE - : i18n.MERGED_CHANGES_TITLE, - title: hasResolvedValueDifferentFromSuggested - ? i18n.MY_CHANGES_FINAL_UPDATE_ONLY_EXPLANATION - : i18n.MERGED_CHANGES_EXPLANATION, - }, - { - value: SelectedVersions.BaseTarget, - text: i18n.UPDATE_FROM_ELASTIC_TITLE, - title: i18n.UPDATE_FROM_ELASTIC_EXPLANATION, - }, - { - value: SelectedVersions.BaseCurrent, - text: i18n.MY_ORIGINAL_CHANGES_TITLE, - title: i18n.MY_ORIGINAL_CHANGES_EXPLANATION, - }, - ]; - } - - if (fieldDiff.conflict === ThreeWayDiffConflict.NON_SOLVABLE) { - const options = [ - { - value: SelectedVersions.BaseFinal, - text: i18n.MY_CHANGES_TITLE, - title: i18n.MY_CHANGES_EXPLANATION, - }, - { - value: SelectedVersions.BaseTarget, - text: i18n.UPDATE_FROM_ELASTIC_TITLE, - title: i18n.UPDATE_FROM_ELASTIC_EXPLANATION, - }, - ]; - - if (hasResolvedValueDifferentFromSuggested) { - options.push({ - value: SelectedVersions.BaseCurrent, - text: i18n.MY_ORIGINAL_CHANGES_TITLE, - title: i18n.MY_ORIGINAL_CHANGES_EXPLANATION, - }); - } - - return options; - } - } - case ThreeWayDiffOutcome.MissingBaseCanUpdate: { - const options = [ - { - value: SelectedVersions.CurrentTarget, - text: i18n.UPDATE_FROM_ELASTIC_TITLE, - title: i18n.UPDATE_FROM_ELASTIC_EXPLANATION, - }, - ]; - - if (hasResolvedValueDifferentFromSuggested) { - options.push({ - value: SelectedVersions.CurrentFinal, - text: i18n.MY_CHANGES_TITLE, - title: i18n.MY_CHANGES_FINAL_UPDATE_ONLY_EXPLANATION, - }); - } - - return options; - } - default: - return []; - } -}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.stories.tsx index c9193e2c358ad..507a0108d63fe 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.stories.tsx @@ -6,42 +6,24 @@ */ import React, { useState } from 'react'; -import type { Story } from '@storybook/react'; -import { VersionsPicker } from './versions_picker'; -import { SelectedVersions } from './constants'; +import { VersionsPicker, VersionsPickerOption } from './versions_picker'; export default { component: VersionsPicker, title: 'Rule Management/Prebuilt Rules/Upgrade Flyout/ThreeWayDiff/VersionsPicker', - argTypes: { - hasBaseVersion: { - control: 'boolean', - description: 'Indicates whether the base version of a field is available', - defaultValue: true, - }, - }, }; -const Template: Story<{ hasBaseVersion: boolean }> = (args) => { - const [selectedVersions, setSelectedVersions] = useState( - SelectedVersions.CurrentFinal - ); +export const Default = () => { + const options = [VersionsPickerOption.UpdateFromElastic, VersionsPickerOption.MyChanges]; + const [selectedOption, setSelectedOption] = useState(options[0]); return ( ); }; - -export const Default = Template.bind({}); -Default.args = { - hasBaseVersion: true, -}; - -export const NoBaseVersion = Template.bind({}); -NoBaseVersion.args = { - hasBaseVersion: false, -}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx index b31a8318c6d35..0ddb4f037ff75 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx @@ -5,35 +5,78 @@ * 2.0. */ -import React, { useCallback } from 'react'; +import React, { useCallback, useEffect } from 'react'; +import { isEqual } from 'lodash'; +import usePrevious from 'react-use/lib/usePrevious'; import { css } from '@emotion/css'; import { EuiSelect } from '@elastic/eui'; -import { SelectedVersions } from './constants'; +import { getOptionDetails } from '../utils'; import * as i18n from './translations'; +export enum VersionsPickerOption { + MyChanges = 'MY_CHANGES', + MyOriginalChanges = 'MY_ORIGINAL_CHANGES', + UpdateFromElastic = 'UPDATE_FROM_ELASTIC', + Merged = 'MERGED', +} + interface VersionsPickerProps { - options: Array<{ value: SelectedVersions; text: string; title: string }>; - selectedVersions: SelectedVersions; - onChange: (pickedVersions: SelectedVersions) => void; + options: VersionsPickerOption[]; + selectedOption: VersionsPickerOption; + onChange: (selectedOption: VersionsPickerOption) => void; + resolvedValue: unknown; + hasResolvedValueDifferentFromSuggested: boolean; } export function VersionsPicker({ options, - selectedVersions = SelectedVersions.CurrentFinal, + selectedOption, onChange, + resolvedValue, + hasResolvedValueDifferentFromSuggested, }: VersionsPickerProps) { + const euiSelectOptions = options.map((option) => { + const { title: displayName, description: explanation } = getOptionDetails( + option, + hasResolvedValueDifferentFromSuggested + ); + + return { + value: option, + text: displayName, + title: explanation, + }; + }); + const handleChange = useCallback( (changeEvent: React.ChangeEvent) => { - onChange(changeEvent.target.value as SelectedVersions); + onChange(changeEvent.target.value as VersionsPickerOption); }, [onChange] ); + /* Change selected option to "My changes" if user has modified resolved value */ + const prevResolvedValue = usePrevious(resolvedValue); + useEffect(() => { + if ( + selectedOption !== VersionsPickerOption.MyChanges && + !isEqual(prevResolvedValue, resolvedValue) + ) { + onChange(VersionsPickerOption.MyChanges); + } + }, [ + hasResolvedValueDifferentFromSuggested, + onChange, + selectedOption, + prevResolvedValue, + resolvedValue, + ]); + return ( From 3eab22ac40622be4ba530606e2194cba3c24ad61 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Sat, 14 Dec 2024 11:03:59 +0100 Subject: [PATCH 77/77] Address last-minute feedback --- .../comparison_side_help_info.tsx | 4 +- .../comparison_side/field_comparison_side.tsx | 21 +++++-- .../comparison_side/translations.ts | 2 +- .../three_way_diff/comparison_side/utils.ts | 55 ++++++++++--------- .../versions_picker.stories.tsx | 7 +-- .../versions_picker/versions_picker.tsx | 33 ++--------- .../rule_upgrade/field_upgrade_context.tsx | 4 ++ 7 files changed, 62 insertions(+), 64 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx index 2c40b6fb1683e..37b23652bfcbe 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side_help_info.tsx @@ -10,7 +10,7 @@ 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 type { VersionsPickerOption } from './versions_picker/versions_picker'; +import type { VersionsPickerOptionEnum } from './versions_picker/versions_picker'; import { useFieldUpgradeContext } from '../rule_upgrade/field_upgrade_context'; import { getOptionDetails } from './utils'; @@ -24,7 +24,7 @@ import { getOptionDetails } from './utils'; const POPOVER_WIDTH = 320; interface ComparisonSideHelpInfoProps { - options: VersionsPickerOption[]; + options: VersionsPickerOptionEnum[]; } export function ComparisonSideHelpInfo({ options }: ComparisonSideHelpInfoProps): JSX.Element { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx index aa4e3f952d6b5..3f30ead78a73f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/field_comparison_side.tsx @@ -5,10 +5,11 @@ * 2.0. */ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; -import type { VersionsPickerOption } from './versions_picker/versions_picker'; -import { VersionsPicker } from './versions_picker/versions_picker'; +import { isEqual } from 'lodash'; +import usePrevious from 'react-use/lib/usePrevious'; +import { VersionsPicker, VersionsPickerOptionEnum } from './versions_picker/versions_picker'; import { FieldUpgradeSideHeader } from '../field_upgrade_side_header'; import { useFieldUpgradeContext } from '../rule_upgrade/field_upgrade_context'; import { @@ -31,7 +32,7 @@ export function FieldComparisonSide(): JSX.Element { fieldDiff.conflict, hasResolvedValueDifferentFromSuggested ); - const [selectedOption, setSelectedOption] = useState(options[0]); + const [selectedOption, setSelectedOption] = useState(options[0]); const [oldVersionType, newVersionType] = getVersionsForComparison( selectedOption, @@ -43,6 +44,17 @@ export function FieldComparisonSide(): JSX.Element { const subfieldChanges = getSubfieldChanges(fieldName, oldFieldValue, newFieldValue); + /* Change selected option to "My changes" if user has modified resolved value */ + const prevResolvedValue = usePrevious(resolvedValue); + useEffect(() => { + if ( + selectedOption !== VersionsPickerOptionEnum.MyChanges && + !isEqual(prevResolvedValue, resolvedValue) + ) { + setSelectedOption(VersionsPickerOptionEnum.MyChanges); + } + }, [hasResolvedValueDifferentFromSuggested, selectedOption, prevResolvedValue, resolvedValue]); + return ( <> @@ -60,7 +72,6 @@ export function FieldComparisonSide(): JSX.Element { options={options} selectedOption={selectedOption} onChange={setSelectedOption} - resolvedValue={resolvedValue} hasResolvedValueDifferentFromSuggested={hasResolvedValueDifferentFromSuggested} />
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/translations.ts index 643661b192edb..808ce32e7b88a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/translations.ts @@ -53,7 +53,7 @@ export const MY_CHANGES_EXPLANATION = i18n.translate( } ); -export const MY_CHANGES_FINAL_UPDATE_ONLY_EXPLANATION = i18n.translate( +export const MY_CHANGES_IN_RULE_UPGRADE_WORKFLOW_EXPLANATION = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.upgradeRules.versions.myChangesFinalUpdateOnlyExplanation', { defaultMessage: `view the changes you made in the {finalUpdateSectionLabel} section`, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts index 687cf9b6381e5..23bd893ba1e97 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts @@ -12,7 +12,7 @@ import { type ThreeWayDiff, ThreeWayDiffConflict, } from '../../../../../../../common/api/detection_engine'; -import { VersionsPickerOption } from './versions_picker/versions_picker'; +import { VersionsPickerOptionEnum } from './versions_picker/versions_picker'; import { assertUnreachable } from '../../../../../../../common/utility_types'; import * as i18n from './translations'; @@ -61,31 +61,31 @@ interface OptionDetails { * Returns the title and description for a given versions picker option. */ export function getOptionDetails( - option: VersionsPickerOption, + option: VersionsPickerOptionEnum, hasResolvedValueDifferentFromSuggested: boolean ): OptionDetails { switch (option) { - case VersionsPickerOption.MyChanges: + case VersionsPickerOptionEnum.MyChanges: return hasResolvedValueDifferentFromSuggested ? { title: i18n.MY_CHANGES_TITLE, - description: i18n.MY_CHANGES_FINAL_UPDATE_ONLY_EXPLANATION, + description: i18n.MY_CHANGES_IN_RULE_UPGRADE_WORKFLOW_EXPLANATION, } : { title: i18n.MY_CHANGES_TITLE, description: i18n.MY_CHANGES_EXPLANATION, }; - case VersionsPickerOption.MyOriginalChanges: + case VersionsPickerOptionEnum.MyOriginalChanges: return { title: i18n.MY_ORIGINAL_CHANGES_TITLE, description: i18n.MY_ORIGINAL_CHANGES_EXPLANATION, }; - case VersionsPickerOption.UpdateFromElastic: + case VersionsPickerOptionEnum.UpdateFromElastic: return { title: i18n.UPDATE_FROM_ELASTIC_TITLE, description: i18n.UPDATE_FROM_ELASTIC_EXPLANATION, }; - case VersionsPickerOption.Merged: + case VersionsPickerOptionEnum.Merged: return { title: i18n.MERGED_CHANGES_TITLE, description: i18n.MERGED_CHANGES_EXPLANATION, @@ -99,17 +99,17 @@ export function getOptionDetails( * Returns the versions to be compared based on the selected versions picker option. */ export function getVersionsForComparison( - selectedOption: VersionsPickerOption, + selectedOption: VersionsPickerOptionEnum, hasBaseVersion: boolean ): [Version, Version] { switch (selectedOption) { - case VersionsPickerOption.MyChanges: + case VersionsPickerOptionEnum.MyChanges: return hasBaseVersion ? [Version.Base, Version.Final] : [Version.Current, Version.Final]; - case VersionsPickerOption.MyOriginalChanges: + case VersionsPickerOptionEnum.MyOriginalChanges: return [Version.Base, Version.Current]; - case VersionsPickerOption.UpdateFromElastic: + case VersionsPickerOptionEnum.UpdateFromElastic: return hasBaseVersion ? [Version.Base, Version.Target] : [Version.Current, Version.Target]; - case VersionsPickerOption.Merged: + case VersionsPickerOptionEnum.Merged: return [Version.Base, Version.Target]; default: return assertUnreachable(selectedOption); @@ -123,48 +123,53 @@ export const getComparisonOptionsForDiffOutcome = ( diffOutcome: ThreeWayDiffOutcome, conflict: ThreeWayDiffConflict, hasResolvedValueDifferentFromSuggested: boolean -): VersionsPickerOption[] => { +): VersionsPickerOptionEnum[] => { switch (diffOutcome) { case ThreeWayDiffOutcome.StockValueCanUpdate: { - const options = [VersionsPickerOption.UpdateFromElastic]; + const options = []; if (hasResolvedValueDifferentFromSuggested) { - options.push(VersionsPickerOption.MyChanges); + options.push(VersionsPickerOptionEnum.MyChanges); } + options.push(VersionsPickerOptionEnum.UpdateFromElastic); return options; } case ThreeWayDiffOutcome.CustomizedValueNoUpdate: - return [VersionsPickerOption.MyChanges]; + return [VersionsPickerOptionEnum.MyChanges]; case ThreeWayDiffOutcome.CustomizedValueSameUpdate: - return [VersionsPickerOption.MyChanges, VersionsPickerOption.UpdateFromElastic]; + return [VersionsPickerOptionEnum.MyChanges, VersionsPickerOptionEnum.UpdateFromElastic]; case ThreeWayDiffOutcome.CustomizedValueCanUpdate: { if (conflict === ThreeWayDiffConflict.SOLVABLE) { return [ hasResolvedValueDifferentFromSuggested - ? VersionsPickerOption.MyChanges - : VersionsPickerOption.Merged, - VersionsPickerOption.UpdateFromElastic, - VersionsPickerOption.MyOriginalChanges, + ? VersionsPickerOptionEnum.MyChanges + : VersionsPickerOptionEnum.Merged, + VersionsPickerOptionEnum.UpdateFromElastic, + VersionsPickerOptionEnum.MyOriginalChanges, ]; } if (conflict === ThreeWayDiffConflict.NON_SOLVABLE) { - const options = [VersionsPickerOption.MyChanges, VersionsPickerOption.UpdateFromElastic]; + const options = [ + VersionsPickerOptionEnum.MyChanges, + VersionsPickerOptionEnum.UpdateFromElastic, + ]; if (hasResolvedValueDifferentFromSuggested) { - options.push(VersionsPickerOption.MyOriginalChanges); + options.push(VersionsPickerOptionEnum.MyOriginalChanges); } return options; } } case ThreeWayDiffOutcome.MissingBaseCanUpdate: { - const options = [VersionsPickerOption.UpdateFromElastic]; + const options = []; if (hasResolvedValueDifferentFromSuggested) { - options.push(VersionsPickerOption.MyChanges); + options.push(VersionsPickerOptionEnum.MyChanges); } + options.push(VersionsPickerOptionEnum.UpdateFromElastic); return options; } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.stories.tsx index 507a0108d63fe..75486d4176c82 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.stories.tsx @@ -6,7 +6,7 @@ */ import React, { useState } from 'react'; -import { VersionsPicker, VersionsPickerOption } from './versions_picker'; +import { VersionsPicker, VersionsPickerOptionEnum } from './versions_picker'; export default { component: VersionsPicker, @@ -14,15 +14,14 @@ export default { }; export const Default = () => { - const options = [VersionsPickerOption.UpdateFromElastic, VersionsPickerOption.MyChanges]; - const [selectedOption, setSelectedOption] = useState(options[0]); + const options = [VersionsPickerOptionEnum.MyChanges, VersionsPickerOptionEnum.UpdateFromElastic]; + const [selectedOption, setSelectedOption] = useState(options[0]); return ( ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx index 0ddb4f037ff75..6fb33113bc36d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/versions_picker/versions_picker.tsx @@ -5,15 +5,13 @@ * 2.0. */ -import React, { useCallback, useEffect } from 'react'; -import { isEqual } from 'lodash'; -import usePrevious from 'react-use/lib/usePrevious'; +import React, { useCallback } from 'react'; import { css } from '@emotion/css'; import { EuiSelect } from '@elastic/eui'; import { getOptionDetails } from '../utils'; import * as i18n from './translations'; -export enum VersionsPickerOption { +export enum VersionsPickerOptionEnum { MyChanges = 'MY_CHANGES', MyOriginalChanges = 'MY_ORIGINAL_CHANGES', UpdateFromElastic = 'UPDATE_FROM_ELASTIC', @@ -21,10 +19,9 @@ export enum VersionsPickerOption { } interface VersionsPickerProps { - options: VersionsPickerOption[]; - selectedOption: VersionsPickerOption; - onChange: (selectedOption: VersionsPickerOption) => void; - resolvedValue: unknown; + options: VersionsPickerOptionEnum[]; + selectedOption: VersionsPickerOptionEnum; + onChange: (selectedOption: VersionsPickerOptionEnum) => void; hasResolvedValueDifferentFromSuggested: boolean; } @@ -32,7 +29,6 @@ export function VersionsPicker({ options, selectedOption, onChange, - resolvedValue, hasResolvedValueDifferentFromSuggested, }: VersionsPickerProps) { const euiSelectOptions = options.map((option) => { @@ -50,28 +46,11 @@ export function VersionsPicker({ const handleChange = useCallback( (changeEvent: React.ChangeEvent) => { - onChange(changeEvent.target.value as VersionsPickerOption); + onChange(changeEvent.target.value as VersionsPickerOptionEnum); }, [onChange] ); - /* Change selected option to "My changes" if user has modified resolved value */ - const prevResolvedValue = usePrevious(resolvedValue); - useEffect(() => { - if ( - selectedOption !== VersionsPickerOption.MyChanges && - !isEqual(prevResolvedValue, resolvedValue) - ) { - onChange(VersionsPickerOption.MyChanges); - } - }, [ - hasResolvedValueDifferentFromSuggested, - onChange, - selectedOption, - prevResolvedValue, - resolvedValue, - ]); - return (