From 12bdeaeef50b312017dd882c92140e54b9bc866d Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 13 Sep 2024 07:46:38 +0200 Subject: [PATCH 01/40] integrate state and components --- .../comparison_side/comparison_side.tsx | 15 ++-- .../three_way_diff/components/side_header.tsx | 29 +++++++ .../three_way_diff/final_side/final_side.tsx | 41 ++++++++++ .../final_side/final_side_help_info.tsx | 63 +++++++++++++++ .../three_way_diff/final_side/translations.ts | 15 ++++ .../three_way_diff/rule_diff_field.tsx | 78 ++++++++++++++++++ .../three_way_diff/rule_diff_section.tsx | 37 +++++++++ .../three_way_diff/three_way_diff_tab.tsx | 34 ++++++++ .../three_way_diff/translations.tsx | 62 ++++++++++++++ .../three_way_diff/upgrade_info_bar.tsx | 47 +++++++++++ .../rule_details/three_way_diff_tab.tsx | 22 ----- .../components/rule_details/translations.ts | 7 -- .../upgrade_prebuilt_rules_table_context.tsx | 81 ++++++++++--------- 13 files changed, 456 insertions(+), 75 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/side_header.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side_help_info.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/translations.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_field.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/upgrade_info_bar.tsx delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff_tab.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side.tsx index 3a6f3e366d848..9ef207b0bb998 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side.tsx @@ -6,7 +6,6 @@ */ import React, { useState } from 'react'; -import { EuiSpacer } from '@elastic/eui'; import { VersionsPicker } from '../versions_picker/versions_picker'; import type { Version } from '../versions_picker/constants'; import { SelectedVersions } from '../versions_picker/constants'; @@ -17,6 +16,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'; interface ComparisonSideProps { fieldName: FieldName; @@ -42,12 +42,13 @@ export function ComparisonSide({ return ( <> - - + + + ); 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/components/side_header.tsx new file mode 100644 index 0000000000000..574e3f526f856 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/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} + + + + ); +} 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/final_side/final_side.tsx new file mode 100644 index 0000000000000..06aff8f244b41 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side.tsx @@ -0,0 +1,41 @@ +/* + * 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 { EuiTitle } from '@elastic/eui'; +import type { + DiffableAllFields, + DiffableRule, +} from '../../../../../../../common/api/detection_engine'; +import { FieldReadOnly } from '../final_readonly/field_readonly'; +import { SideHeader } from '../components/side_header'; +import { FinalSideHelpInfo } from './final_side_help_info'; +import * as i18n from './translations'; + +interface FinalSideProps { + fieldName: string; + finalDiffableRule: DiffableRule; +} + +export function FinalSide({ fieldName, finalDiffableRule }: FinalSideProps): JSX.Element { + return ( + <> + + +

+ {i18n.UPGRADED_VERSION} + +

+
+
+ + + ); +} 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/final_side/final_side_help_info.tsx new file mode 100644 index 0000000000000..647d9848750d3 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side_help_info.tsx @@ -0,0 +1,63 @@ +/* + * 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 { useToggle } from 'react-use'; +import { EuiPopover, EuiText, EuiButtonIcon } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useKibana } from '../../../../../../common/lib/kibana'; + +/** + * Theme doesn't expose width variables. Using provided size variables will require + * multiplying it by another magic constant. + * + * 320px width looks + * like a [commonly used width in EUI](https://github.com/search?q=repo%3Aelastic%2Feui%20320&type=code). + */ +const POPOVER_WIDTH = 320; + +export function FinalSideHelpInfo(): JSX.Element { + const [isPopoverOpen, togglePopover] = useToggle(false); + const { docLinks } = useKibana().services; + + const button = ( + + ); + + return ( + + + + // + // + // ), + // semverLink: ( + // + // + // + // ), + // }} + /> + + + ); +} 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/final_side/translations.ts new file mode 100644 index 0000000000000..aa9b4885a964d --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/translations.ts @@ -0,0 +1,15 @@ +/* + * 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 UPGRADED_VERSION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradedVersion', + { + defaultMessage: 'Upgraded version', + } +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_field.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_field.tsx new file mode 100644 index 0000000000000..56b85f0759274 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_field.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 from 'react'; +import { + EuiAccordion, + EuiFlexGroup, + EuiFlexItem, + EuiPanel, + EuiSpacer, + useEuiTheme, + useGeneratedHtmlId, +} from '@elastic/eui'; +import { css } from '@emotion/css'; +import type { + DiffableAllFields, + DiffableRule, + ThreeWayDiff, +} from '../../../../../../common/api/detection_engine'; +import { ThreeWayDiffConflict } from '../../../../../../common/api/detection_engine'; +import { ComparisonSide } from './comparison_side/comparison_side'; +import { FinalSide } from './final_side/final_side'; + +interface RuleDiffFieldProps { + fieldName: FieldName; + fieldThreeWayDiff: ThreeWayDiff; + finalDiffableRule: DiffableRule; + resolvedValue?: DiffableAllFields[FieldName]; +} + +export function RuleDiffField({ + fieldName, + fieldThreeWayDiff, + finalDiffableRule, + resolvedValue, +}: RuleDiffFieldProps): JSX.Element { + const { euiTheme } = useEuiTheme(); + const accordionId = useGeneratedHtmlId({ prefix: 'rule-diff-accordion' }); + const hasConflict = fieldThreeWayDiff.conflict !== ThreeWayDiffConflict.NONE; + + return ( + <> + + + + + + + + + + + + + + + + ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx new file mode 100644 index 0000000000000..73d81643fa23b --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx @@ -0,0 +1,37 @@ +/* + * 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 { + DiffableAllFields, + ThreeWayDiff, +} from '../../../../../../common/api/detection_engine'; +import type { RuleUpgradeState } from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; +import { RuleDiffField } from './rule_diff_field'; + +interface RuleDiffSectionProps { + ruleUpgradeState: RuleUpgradeState; +} + +export function RuleDiffSection({ ruleUpgradeState }: RuleDiffSectionProps): JSX.Element { + const fieldNames = Object.keys(ruleUpgradeState.diff.fields) as Array< + keyof typeof ruleUpgradeState.diff.fields + >; + const fields = fieldNames.map((fieldName) => ( + + } + finalDiffableRule={ruleUpgradeState.finalRule} + resolvedValue={ruleUpgradeState.finalRule[fieldName]} + /> + )); + + return <>{fields}; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx new file mode 100644 index 0000000000000..82be37b0c53bd --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx @@ -0,0 +1,34 @@ +/* + * 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, + SetFieldResolvedValueFn, +} from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; +import { UpgradeInfoBar } from './upgrade_info_bar'; +import { RuleDiffSection } from './rule_diff_section'; + +interface ThreeWayDiffTabProps { + ruleUpgradeState: RuleUpgradeState; + setFieldResolvedValue: SetFieldResolvedValueFn; +} + +export function ThreeWayDiffTab({ + ruleUpgradeState, + setFieldResolvedValue, +}: ThreeWayDiffTabProps): JSX.Element { + return ( + <> + + + + + + ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.tsx new file mode 100644 index 0000000000000..f054eec363121 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.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 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) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.fieldsWithUpdates', + { + values: { count }, + defaultMessage: 'Upgrade has {count} {count, plural, one {field} other {fields}}', + } + ); + +export const NUM_OF_CONFLICTS = (count: number) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.numOfConflicts', + { + values: { count }, + defaultMessage: '{count} {count, plural, one {conflict} other {conflicts}}', + } + ); + +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/upgrade_info_bar.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/upgrade_info_bar.tsx new file mode 100644 index 0000000000000..7be620e0a3f95 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/upgrade_info_bar.tsx @@ -0,0 +1,47 @@ +/* + * 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 } from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; +import { + UtilityBar, + UtilityBarGroup, + UtilityBarSection, + UtilityBarText, +} from '../../../../../common/components/utility_bar'; +import * as i18n from './translations'; + +interface UpgradeInfoBarProps { + ruleUpgradeState: RuleUpgradeState; +} + +export function UpgradeInfoBar({ ruleUpgradeState }: UpgradeInfoBarProps): JSX.Element { + const numOfFieldsWithUpdates = ruleUpgradeState.diff.num_fields_with_updates; + const numOfConflicts = ruleUpgradeState.diff.num_fields_with_conflicts; + + return ( + + + + + {i18n.NUM_OF_FIELDS_WITH_UPDATES(numOfFieldsWithUpdates)} + + + + + {i18n.NUM_OF_CONFLICTS(numOfConflicts)} + + + + + + + + + + ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff_tab.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff_tab.tsx deleted file mode 100644 index 5117fa2d7b93b..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff_tab.tsx +++ /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 React from 'react'; -import type { DiffableRule } from '../../../../../common/api/detection_engine'; -import type { SetFieldResolvedValueFn } from '../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; - -interface ThreeWayDiffTabProps { - finalDiffableRule: DiffableRule; - setFieldResolvedValue: SetFieldResolvedValueFn; -} - -export function ThreeWayDiffTab({ - finalDiffableRule, - setFieldResolvedValue, -}: ThreeWayDiffTabProps): JSX.Element { - return <>{JSON.stringify(finalDiffableRule)}; -} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/translations.ts index f0b96bad1aff5..89c22a285e327 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/translations.ts @@ -28,13 +28,6 @@ export const UPDATES_TAB_LABEL = i18n.translate( } ); -export const DIFF_TAB_LABEL = i18n.translate( - 'xpack.securitySolution.detectionEngine.ruleDetails.diffTabLabel', - { - defaultMessage: 'Diff', - } -); - export const JSON_VIEW_UPDATES_TAB_LABEL = i18n.translate( 'xpack.securitySolution.detectionEngine.ruleDetails.jsonViewUpdatesTabLabel', { 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 efd63e5da6872..b8ba10506a461 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 @@ -9,7 +9,7 @@ import type { Dispatch, SetStateAction } from 'react'; import React, { createContext, useCallback, useContext, useMemo, useState } from 'react'; import { EuiButton, EuiToolTip } from '@elastic/eui'; import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features'; -import { ThreeWayDiffTab } from '../../../../rule_management/components/rule_details/three_way_diff_tab'; +import { ThreeWayDiffTab } from '../../../../rule_management/components/rule_details/three_way_diff/three_way_diff_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 { useInstalledSecurityJobs } from '../../../../../common/components/ml/hooks/use_installed_security_jobs'; @@ -225,7 +225,46 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ return []; } - const extraTabs = [ + const jsonViewUpdates = { + id: 'jsonViewUpdates', + name: ( + + <>{ruleDetailsI18n.JSON_VIEW_UPDATES_TAB_LABEL} + + ), + content: ( + + + + ), + }; + + if (isPrebuiltRulesCustomizationEnabled) { + return [ + { + id: 'updates', + name: ( + + <>{ruleDetailsI18n.UPDATES_TAB_LABEL} + + ), + content: ( + + + + ), + }, + jsonViewUpdates, + ]; + } + + return [ { id: 'updates', name: ( @@ -239,44 +278,8 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ ), }, - { - id: 'jsonViewUpdates', - name: ( - - <>{ruleDetailsI18n.JSON_VIEW_UPDATES_TAB_LABEL} - - ), - content: ( - - - - ), - }, + jsonViewUpdates, ]; - - if (isPrebuiltRulesCustomizationEnabled) { - extraTabs.unshift({ - id: 'diff', - name: ( - - <>{ruleDetailsI18n.DIFF_TAB_LABEL} - - ), - content: ( - - - - ), - }); - } - - return extraTabs; }, [rulesUpgradeState, setFieldResolvedValue, isPrebuiltRulesCustomizationEnabled] ); From 8ecf7ae6ea784848744e009c127e9fb4b3559da8 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Wed, 25 Sep 2024 15:45:45 +0200 Subject: [PATCH 02/40] move tab related components to components folder --- .../three_way_diff/{ => components}/rule_diff_field.tsx | 8 ++++---- .../three_way_diff/{ => components}/rule_diff_section.tsx | 4 ++-- .../three_way_diff/{ => components}/translations.tsx | 2 +- .../three_way_diff/{ => components}/upgrade_info_bar.tsx | 4 ++-- .../rule_details/three_way_diff/three_way_diff_tab.tsx | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{ => components}/rule_diff_field.tsx (88%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{ => components}/rule_diff_section.tsx (83%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{ => components}/translations.tsx (95%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{ => components}/upgrade_info_bar.tsx (86%) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_field.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_diff_field.tsx similarity index 88% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_field.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_diff_field.tsx index 56b85f0759274..22606f74c9a18 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_field.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_diff_field.tsx @@ -20,10 +20,10 @@ import type { DiffableAllFields, DiffableRule, ThreeWayDiff, -} from '../../../../../../common/api/detection_engine'; -import { ThreeWayDiffConflict } from '../../../../../../common/api/detection_engine'; -import { ComparisonSide } from './comparison_side/comparison_side'; -import { FinalSide } from './final_side/final_side'; +} from '../../../../../../../common/api/detection_engine'; +import { ThreeWayDiffConflict } from '../../../../../../../common/api/detection_engine'; +import { ComparisonSide } from '../comparison_side/comparison_side'; +import { FinalSide } from '../final_side/final_side'; interface RuleDiffFieldProps { fieldName: FieldName; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_diff_section.tsx similarity index 83% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_diff_section.tsx index 73d81643fa23b..270589d487aeb 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_diff_section.tsx @@ -9,8 +9,8 @@ import React from 'react'; import type { DiffableAllFields, ThreeWayDiff, -} from '../../../../../../common/api/detection_engine'; -import type { RuleUpgradeState } from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; +} from '../../../../../../../common/api/detection_engine'; +import type { RuleUpgradeState } from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; import { RuleDiffField } from './rule_diff_field'; interface RuleDiffSectionProps { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/translations.tsx similarity index 95% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/translations.tsx index f054eec363121..620b3ac1c0ba8 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/translations.tsx @@ -9,7 +9,7 @@ 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'; +import { useKibana } from '../../../../../../common/lib/kibana/kibana_react'; export const NUM_OF_FIELDS_WITH_UPDATES = (count: number) => i18n.translate( diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/upgrade_info_bar.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/upgrade_info_bar.tsx similarity index 86% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/upgrade_info_bar.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/upgrade_info_bar.tsx index 7be620e0a3f95..1aa6ed330ccc5 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/upgrade_info_bar.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/upgrade_info_bar.tsx @@ -6,13 +6,13 @@ */ import React from 'react'; -import type { RuleUpgradeState } from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; +import type { RuleUpgradeState } from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; import { UtilityBar, UtilityBarGroup, UtilityBarSection, UtilityBarText, -} from '../../../../../common/components/utility_bar'; +} from '../../../../../../common/components/utility_bar'; import * as i18n from './translations'; interface UpgradeInfoBarProps { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx index 82be37b0c53bd..58003f4d821d2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx @@ -11,8 +11,8 @@ import type { RuleUpgradeState, SetFieldResolvedValueFn, } from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; -import { UpgradeInfoBar } from './upgrade_info_bar'; -import { RuleDiffSection } from './rule_diff_section'; +import { UpgradeInfoBar } from './components/upgrade_info_bar'; +import { RuleDiffSection } from './components/rule_diff_section'; interface ThreeWayDiffTabProps { ruleUpgradeState: RuleUpgradeState; From 2294396bf10425670e58595b0fc70cec14fec8ac Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Wed, 25 Sep 2024 19:42:54 +0200 Subject: [PATCH 03/40] adopt SplitAccordion --- .../components/split_accordion/index.ts | 8 +++ .../split_accordion/split_accordion.tsx | 47 +++++++++++++ .../diff_components/field_diff.tsx | 20 ++++-- .../rule_details/diff_components/index.ts | 1 - .../diff_components/panel_wrapper.tsx | 45 ------------ .../three_way_diff/comparison_side/utils.ts | 2 +- .../components/rule_diff_field.tsx | 69 +++++++++---------- 7 files changed, 103 insertions(+), 89 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/common/components/split_accordion/index.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/split_accordion/split_accordion.tsx delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/diff_components/panel_wrapper.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/split_accordion/index.ts b/x-pack/plugins/security_solution/public/common/components/split_accordion/index.ts new file mode 100644 index 0000000000000..6b05d7594e20a --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/split_accordion/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 './split_accordion'; diff --git a/x-pack/plugins/security_solution/public/common/components/split_accordion/split_accordion.tsx b/x-pack/plugins/security_solution/public/common/components/split_accordion/split_accordion.tsx new file mode 100644 index 0000000000000..668473919b97b --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/split_accordion/split_accordion.tsx @@ -0,0 +1,47 @@ +/* + * 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 { EuiAccordion, EuiSplitPanel, useEuiTheme, useGeneratedHtmlId } from '@elastic/eui'; +import { css } from '@emotion/css'; +import type { PropsWithChildren } from 'react'; + +interface SplitAccordionProps { + header: React.ReactNode; + initialIsOpen?: boolean; + 'data-test-subj'?: string; +} + +export const SplitAccordion = ({ + header, + initialIsOpen, + 'data-test-subj': dataTestSubj, + children, +}: PropsWithChildren) => { + const accordionId = useGeneratedHtmlId(); + const { euiTheme } = useEuiTheme(); + + return ( + + + + {children} + + + + ); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/diff_components/field_diff.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/diff_components/field_diff.tsx index 86c85b7b7a89b..149b7a813d55b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/diff_components/field_diff.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/diff_components/field_diff.tsx @@ -8,8 +8,8 @@ import { EuiFlexGroup, EuiHorizontalRule, EuiTitle } from '@elastic/eui'; import { camelCase, startCase } from 'lodash'; import React from 'react'; +import { SplitAccordion } from '../../../../../common/components/split_accordion'; import { DiffView } from '../json_diff/diff_view'; -import { RuleDiffPanelWrapper } from './panel_wrapper'; import type { FormattedFieldDiff, FieldDiff } from '../../../model/rule_details/rule_field_diff'; import { fieldToDisplayNameMap } from './translations'; @@ -46,14 +46,24 @@ export const FieldGroupDiffComponent = ({ fieldsGroupName, }: FieldDiffComponentProps) => { const { fieldDiffs, shouldShowSubtitles } = ruleDiffs; + return ( - + +
{fieldToDisplayNameMap[fieldsGroupName] ?? startCase(camelCase(fieldsGroupName))}
+ + } + initialIsOpen={true} + data-test-subj="ruleUpgradePerFieldDiff" + > {fieldDiffs.map(({ currentVersion, targetVersion, fieldName: specificFieldName }, index) => { - const shouldShowSeparator = index !== fieldDiffs.length - 1; + const isLast = index !== fieldDiffs.length - 1; + return ( ); })} -
+ ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/diff_components/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/diff_components/index.ts index 6effbcf3af931..cef0491a53e22 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/diff_components/index.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/diff_components/index.ts @@ -7,5 +7,4 @@ export * from './field_diff'; export * from './header_bar'; -export * from './panel_wrapper'; export * from './rule_diff_section'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/diff_components/panel_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/diff_components/panel_wrapper.tsx deleted file mode 100644 index f0c86a68cafaf..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/diff_components/panel_wrapper.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 { EuiAccordion, EuiSplitPanel, EuiTitle, useEuiTheme } from '@elastic/eui'; -import { camelCase, startCase } from 'lodash'; -import { css } from '@emotion/css'; -import React from 'react'; -import { fieldToDisplayNameMap } from './translations'; - -interface RuleDiffPanelWrapperProps { - fieldName: string; - children: React.ReactNode; -} - -export const RuleDiffPanelWrapper = ({ fieldName, children }: RuleDiffPanelWrapperProps) => { - const { euiTheme } = useEuiTheme(); - - return ( - - -
{fieldToDisplayNameMap[fieldName] ?? startCase(camelCase(fieldName))}
- - } - > - - {children} - -
-
- ); -}; 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 fd16366f1a76e..dd52da04982f3 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 @@ -26,7 +26,7 @@ export function pickFieldValueForVersion { fieldName: FieldName; @@ -39,39 +34,39 @@ export function RuleDiffField({ resolvedValue, }: RuleDiffFieldProps): JSX.Element { const { euiTheme } = useEuiTheme(); - const accordionId = useGeneratedHtmlId({ prefix: 'rule-diff-accordion' }); const hasConflict = fieldThreeWayDiff.conflict !== ThreeWayDiffConflict.NONE; return ( <> - - - - - - - +
{fieldToDisplayNameMap[fieldName] ?? startCase(camelCase(fieldName))}
+ + } + initialIsOpen={hasConflict} + data-test-subj="ruleUpgradePerFieldDiff" + > + + + - - - - -
-
+ + + + + + + ); From 204933f6aa2b05a8e3234f804b4352f12fb2a00a Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Thu, 26 Sep 2024 08:17:28 +0200 Subject: [PATCH 04/40] reduce type casting to bare minimum --- .../components/rule_diff_field.tsx | 13 ++++++------ .../components/rule_diff_section.tsx | 20 ++++++++----------- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_diff_field.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_diff_field.tsx index e1018722ce658..1d0f4c6b7951e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_diff_field.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_diff_field.tsx @@ -13,6 +13,7 @@ import { SplitAccordion } from '../../../../../../common/components/split_accord import type { DiffableAllFields, DiffableRule, + RuleFieldsDiff, ThreeWayDiff, } from '../../../../../../../common/api/detection_engine'; import { ThreeWayDiffConflict } from '../../../../../../../common/api/detection_engine'; @@ -20,18 +21,16 @@ import { ComparisonSide } from '../comparison_side/comparison_side'; import { FinalSide } from '../final_side/final_side'; import { fieldToDisplayNameMap } from '../../diff_components/translations'; -interface RuleDiffFieldProps { +interface RuleDiffFieldProps { fieldName: FieldName; - fieldThreeWayDiff: ThreeWayDiff; + fieldThreeWayDiff: RuleFieldsDiff[FieldName]; finalDiffableRule: DiffableRule; - resolvedValue?: DiffableAllFields[FieldName]; } -export function RuleDiffField({ +export function RuleDiffField({ fieldName, fieldThreeWayDiff, finalDiffableRule, - resolvedValue, }: RuleDiffFieldProps): JSX.Element { const { euiTheme } = useEuiTheme(); const hasConflict = fieldThreeWayDiff.conflict !== ThreeWayDiffConflict.NONE; @@ -51,8 +50,8 @@ export function RuleDiffField({ } + resolvedValue={finalDiffableRule[fieldName]} /> [keyof typeof ruleUpgradeState.diff.fields] + ] >; - const fields = fieldNames.map((fieldName) => ( + const fields = fieldDiffEntries.map(([fieldName, fieldDiff]) => ( - } + fieldThreeWayDiff={fieldDiff} finalDiffableRule={ruleUpgradeState.finalRule} - resolvedValue={ruleUpgradeState.finalRule[fieldName]} /> )); From 64ddaa79db2138e9dc5b88c1981e6e0273b36309 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Thu, 26 Sep 2024 09:36:29 +0200 Subject: [PATCH 05/40] improve component's naming --- ...x => field_upgrade_conflicts_resolver.tsx} | 19 ++++++-------- ...ield_upgrade_conflicts_resolver_header.tsx | 25 +++++++++++++++++++ ...sx => rule_upgrade_conflicts_resolver.tsx} | 17 +++++++++---- ...info_bar.tsx => rule_upgrade_info_bar.tsx} | 2 +- .../three_way_diff/final_side/final_side.tsx | 10 ++------ ...> rule_upgrade_conflicts_resolver_tab.tsx} | 17 +++++++------ .../upgrade_prebuilt_rules_table_context.tsx | 4 +-- 7 files changed, 59 insertions(+), 35 deletions(-) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/{rule_diff_field.tsx => field_upgrade_conflicts_resolver.tsx} (73%) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver_header.tsx rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/{rule_diff_section.tsx => rule_upgrade_conflicts_resolver.tsx} (59%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/{upgrade_info_bar.tsx => rule_upgrade_info_bar.tsx} (94%) rename x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/{three_way_diff_tab.tsx => rule_upgrade_conflicts_resolver_tab.tsx} (58%) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_diff_field.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx similarity index 73% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_diff_field.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx index 1d0f4c6b7951e..eeafddfc21f03 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_diff_field.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/field_upgrade_conflicts_resolver.tsx @@ -6,9 +6,8 @@ */ import React from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle, useEuiTheme } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiSpacer, useEuiTheme } from '@elastic/eui'; import { css } from '@emotion/css'; -import { camelCase, startCase } from 'lodash'; import { SplitAccordion } from '../../../../../../common/components/split_accordion'; import type { DiffableAllFields, @@ -19,30 +18,26 @@ import type { import { ThreeWayDiffConflict } from '../../../../../../../common/api/detection_engine'; import { ComparisonSide } from '../comparison_side/comparison_side'; import { FinalSide } from '../final_side/final_side'; -import { fieldToDisplayNameMap } from '../../diff_components/translations'; +import { FieldUpgradeConflictsResolverHeader } from './field_upgrade_conflicts_resolver_header'; -interface RuleDiffFieldProps { +interface FieldUpgradeConflictsResolverProps { fieldName: FieldName; fieldThreeWayDiff: RuleFieldsDiff[FieldName]; finalDiffableRule: DiffableRule; } -export function RuleDiffField({ +export function FieldUpgradeConflictsResolver({ fieldName, fieldThreeWayDiff, finalDiffableRule, -}: RuleDiffFieldProps): JSX.Element { +}: FieldUpgradeConflictsResolverProps): JSX.Element { const { euiTheme } = useEuiTheme(); const hasConflict = fieldThreeWayDiff.conflict !== ThreeWayDiffConflict.NONE; return ( <> -
{fieldToDisplayNameMap[fieldName] ?? startCase(camelCase(fieldName))}
- - } + header={} initialIsOpen={hasConflict} data-test-subj="ruleUpgradePerFieldDiff" > @@ -51,7 +46,7 @@ export function RuleDiffField({ } - resolvedValue={finalDiffableRule[fieldName]} + resolvedValue={finalDiffableRule[fieldName] as DiffableAllFields[FieldName]} />
+
{fieldToDisplayNameMap[fieldName] ?? startCase(camelCase(fieldName))}
+ + ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_diff_section.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_conflicts_resolver.tsx similarity index 59% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_diff_section.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_conflicts_resolver.tsx index 3b1a9a551cf17..ddbc1af9980c1 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_diff_section.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_conflicts_resolver.tsx @@ -6,14 +6,21 @@ */ import React from 'react'; -import type { RuleUpgradeState } from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; -import { RuleDiffField } from './rule_diff_field'; +import type { + RuleUpgradeState, + SetFieldResolvedValueFn, +} from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; +import { FieldUpgradeConflictsResolver } from './field_upgrade_conflicts_resolver'; -interface RuleDiffSectionProps { +interface RuleUpgradeConflictsResolverProps { ruleUpgradeState: RuleUpgradeState; + setFieldResolvedValue: SetFieldResolvedValueFn; } -export function RuleDiffSection({ ruleUpgradeState }: RuleDiffSectionProps): JSX.Element | null { +export function RuleUpgradeConflictsResolver({ + ruleUpgradeState, + setFieldResolvedValue, +}: RuleUpgradeConflictsResolverProps): JSX.Element | null { const fieldDiffEntries = Object.entries(ruleUpgradeState.diff.fields) as Array< [ keyof typeof ruleUpgradeState.diff.fields, @@ -21,7 +28,7 @@ export function RuleDiffSection({ ruleUpgradeState }: RuleDiffSectionProps): JSX ] >; const fields = fieldDiffEntries.map(([fieldName, fieldDiff]) => ( - - + ); } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_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 similarity index 58% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_upgrade_conflicts_resolver_tab.tsx index 58003f4d821d2..fbda0866a3203 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_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 @@ -11,24 +11,27 @@ import type { RuleUpgradeState, SetFieldResolvedValueFn, } from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; -import { UpgradeInfoBar } from './components/upgrade_info_bar'; -import { RuleDiffSection } from './components/rule_diff_section'; +import { RuleUpgradeInfoBar } from './components/rule_upgrade_info_bar'; +import { RuleUpgradeConflictsResolver } from './components/rule_upgrade_conflicts_resolver'; -interface ThreeWayDiffTabProps { +interface RuleUpgradeConflictsResolverTabProps { ruleUpgradeState: RuleUpgradeState; setFieldResolvedValue: SetFieldResolvedValueFn; } -export function ThreeWayDiffTab({ +export function RuleUpgradeConflictsResolverTab({ ruleUpgradeState, setFieldResolvedValue, -}: ThreeWayDiffTabProps): JSX.Element { +}: RuleUpgradeConflictsResolverTabProps): 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 b8ba10506a461..c22ba379e79f7 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 @@ -9,7 +9,7 @@ import type { Dispatch, SetStateAction } from 'react'; import React, { createContext, useCallback, useContext, useMemo, useState } from 'react'; import { EuiButton, EuiToolTip } from '@elastic/eui'; import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features'; -import { ThreeWayDiffTab } from '../../../../rule_management/components/rule_details/three_way_diff/three_way_diff_tab'; +import { RuleUpgradeConflictsResolverTab } from '../../../../rule_management/components/rule_details/three_way_diff/rule_upgrade_conflicts_resolver_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 { useInstalledSecurityJobs } from '../../../../../common/components/ml/hooks/use_installed_security_jobs'; @@ -253,7 +253,7 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ ), content: ( - From 6b51235b13ae9310aaec8470b34d61062a5d102b Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Thu, 26 Sep 2024 09:55:00 +0200 Subject: [PATCH 06/40] improve function naming --- .../rule_upgrade_conflicts_resolver.tsx | 8 +++--- .../rule_upgrade_conflicts_resolver_tab.tsx | 8 +++--- .../upgrade_prebuilt_rules_table_context.tsx | 6 ++--- .../use_prebuilt_rules_upgrade_state.ts | 27 ++++++++++--------- 4 files changed, 26 insertions(+), 23 deletions(-) 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/components/rule_upgrade_conflicts_resolver.tsx index ddbc1af9980c1..57af1b340c776 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/components/rule_upgrade_conflicts_resolver.tsx @@ -8,19 +8,19 @@ import React from 'react'; import type { RuleUpgradeState, - SetFieldResolvedValueFn, + SetRuleFieldResolvedValueFn, } from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; import { FieldUpgradeConflictsResolver } from './field_upgrade_conflicts_resolver'; interface RuleUpgradeConflictsResolverProps { ruleUpgradeState: RuleUpgradeState; - setFieldResolvedValue: SetFieldResolvedValueFn; + setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } export function RuleUpgradeConflictsResolver({ ruleUpgradeState, - setFieldResolvedValue, -}: RuleUpgradeConflictsResolverProps): JSX.Element | null { + setRuleFieldResolvedValue, +}: RuleUpgradeConflictsResolverProps): JSX.Element { const fieldDiffEntries = Object.entries(ruleUpgradeState.diff.fields) as Array< [ keyof typeof ruleUpgradeState.diff.fields, 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 index fbda0866a3203..10823b8045c96 100644 --- 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 @@ -9,19 +9,19 @@ import React from 'react'; import { EuiSpacer } from '@elastic/eui'; import type { RuleUpgradeState, - SetFieldResolvedValueFn, + SetRuleFieldResolvedValueFn, } from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; import { RuleUpgradeInfoBar } from './components/rule_upgrade_info_bar'; import { RuleUpgradeConflictsResolver } from './components/rule_upgrade_conflicts_resolver'; interface RuleUpgradeConflictsResolverTabProps { ruleUpgradeState: RuleUpgradeState; - setFieldResolvedValue: SetFieldResolvedValueFn; + setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } export function RuleUpgradeConflictsResolverTab({ ruleUpgradeState, - setFieldResolvedValue, + setRuleFieldResolvedValue, }: RuleUpgradeConflictsResolverTabProps): JSX.Element { return ( <> @@ -30,7 +30,7 @@ export function RuleUpgradeConflictsResolverTab({ ); 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 c22ba379e79f7..997f85d3ddce0 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 @@ -140,7 +140,7 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ filterOptions, rules: ruleUpgradeInfos, }); - const { rulesUpgradeState, setFieldResolvedValue } = + const { rulesUpgradeState, setRuleFieldResolvedValue } = usePrebuiltRulesUpgradeState(filteredRuleUpgradeInfos); // Wrapper to add confirmation modal for users who may be running older ML Jobs that would @@ -255,7 +255,7 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ ), @@ -281,7 +281,7 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ jsonViewUpdates, ]; }, - [rulesUpgradeState, setFieldResolvedValue, isPrebuiltRulesCustomizationEnabled] + [rulesUpgradeState, setRuleFieldResolvedValue, isPrebuiltRulesCustomizationEnabled] ); const filteredRules = useMemo( () => filteredRuleUpgradeInfos.map((rule) => rule.target_rule), 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 86f2293d312fa..feafc1a6948ab 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 @@ -28,7 +28,7 @@ export interface RuleUpgradeState extends RuleUpgradeInfoForReview { hasUnresolvedConflicts: boolean; } export type RulesUpgradeState = Record; -export type SetFieldResolvedValueFn< +export type SetRuleFieldResolvedValueFn< FieldName extends keyof DiffableAllFields = keyof DiffableAllFields > = (params: { ruleId: RuleObjectId; @@ -41,22 +41,25 @@ type RulesResolvedConflicts = Record; interface UseRulesUpgradeStateResult { rulesUpgradeState: RulesUpgradeState; - setFieldResolvedValue: SetFieldResolvedValueFn; + setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } export function usePrebuiltRulesUpgradeState( ruleUpgradeInfos: RuleUpgradeInfoForReview[] ): UseRulesUpgradeStateResult { const [rulesResolvedConflicts, setRulesResolvedConflicts] = useState({}); - const setFieldResolvedValue = useCallback((...[params]: Parameters) => { - setRulesResolvedConflicts((prevRulesResolvedConflicts) => ({ - ...prevRulesResolvedConflicts, - [params.ruleId]: { - ...(prevRulesResolvedConflicts[params.ruleId] ?? {}), - [params.fieldName]: params.resolvedValue, - }, - })); - }, []); + const setRuleFieldResolvedValue = useCallback( + (...[params]: Parameters) => { + setRulesResolvedConflicts((prevRulesResolvedConflicts) => ({ + ...prevRulesResolvedConflicts, + [params.ruleId]: { + ...(prevRulesResolvedConflicts[params.ruleId] ?? {}), + [params.fieldName]: params.resolvedValue, + }, + })); + }, + [] + ); const rulesUpgradeState = useMemo(() => { const state: RulesUpgradeState = {}; @@ -80,7 +83,7 @@ export function usePrebuiltRulesUpgradeState( return { rulesUpgradeState, - setFieldResolvedValue, + setRuleFieldResolvedValue, }; } From 1a0fa9a6670034dd03f2e892ed5e96deb95dec7e Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Thu, 26 Sep 2024 11:23:05 +0200 Subject: [PATCH 07/40] remove unused code --- .../final_side/final_side_help_info.tsx | 20 ------------------- 1 file changed, 20 deletions(-) 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/final_side/final_side_help_info.tsx index 647d9848750d3..766692e9efecd 100644 --- 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/final_side/final_side_help_info.tsx @@ -9,7 +9,6 @@ import React from 'react'; import { useToggle } from 'react-use'; import { EuiPopover, EuiText, EuiButtonIcon } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { useKibana } from '../../../../../../common/lib/kibana'; /** * Theme doesn't expose width variables. Using provided size variables will require @@ -22,7 +21,6 @@ const POPOVER_WIDTH = 320; export function FinalSideHelpInfo(): JSX.Element { const [isPopoverOpen, togglePopover] = useToggle(false); - const { docLinks } = useKibana().services; const button = ( - // - // - // ), - // semverLink: ( - // - // - // - // ), - // }} /> From c3bcaaec9fa0d81fc3f34a29f5ba414d56a6ab7e Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Fri, 13 Sep 2024 07:46:38 +0200 Subject: [PATCH 08/40] integrate state and components --- .../comparison_side/comparison_side.tsx | 15 ++-- .../three_way_diff/components/side_header.tsx | 29 +++++++ .../three_way_diff/final_side/final_side.tsx | 41 ++++++++++ .../final_side/final_side_help_info.tsx | 63 +++++++++++++++ .../three_way_diff/final_side/translations.ts | 15 ++++ .../three_way_diff/rule_diff_field.tsx | 78 ++++++++++++++++++ .../three_way_diff/rule_diff_section.tsx | 37 +++++++++ .../three_way_diff/three_way_diff_tab.tsx | 34 ++++++++ .../three_way_diff/translations.tsx | 62 ++++++++++++++ .../three_way_diff/upgrade_info_bar.tsx | 47 +++++++++++ .../rule_details/three_way_diff_tab.tsx | 22 ----- .../components/rule_details/translations.ts | 7 -- .../upgrade_prebuilt_rules_table_context.tsx | 81 ++++++++++--------- 13 files changed, 456 insertions(+), 75 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/side_header.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side_help_info.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/translations.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_field.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/upgrade_info_bar.tsx delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff_tab.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side.tsx index 3a6f3e366d848..9ef207b0bb998 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side.tsx @@ -6,7 +6,6 @@ */ import React, { useState } from 'react'; -import { EuiSpacer } from '@elastic/eui'; import { VersionsPicker } from '../versions_picker/versions_picker'; import type { Version } from '../versions_picker/constants'; import { SelectedVersions } from '../versions_picker/constants'; @@ -17,6 +16,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'; interface ComparisonSideProps { fieldName: FieldName; @@ -42,12 +42,13 @@ export function ComparisonSide({ return ( <> - - + + + ); 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/components/side_header.tsx new file mode 100644 index 0000000000000..574e3f526f856 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/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} + + + + ); +} 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/final_side/final_side.tsx new file mode 100644 index 0000000000000..06aff8f244b41 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side.tsx @@ -0,0 +1,41 @@ +/* + * 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 { EuiTitle } from '@elastic/eui'; +import type { + DiffableAllFields, + DiffableRule, +} from '../../../../../../../common/api/detection_engine'; +import { FieldReadOnly } from '../final_readonly/field_readonly'; +import { SideHeader } from '../components/side_header'; +import { FinalSideHelpInfo } from './final_side_help_info'; +import * as i18n from './translations'; + +interface FinalSideProps { + fieldName: string; + finalDiffableRule: DiffableRule; +} + +export function FinalSide({ fieldName, finalDiffableRule }: FinalSideProps): JSX.Element { + return ( + <> + + +

+ {i18n.UPGRADED_VERSION} + +

+
+
+ + + ); +} 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/final_side/final_side_help_info.tsx new file mode 100644 index 0000000000000..647d9848750d3 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side_help_info.tsx @@ -0,0 +1,63 @@ +/* + * 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 { useToggle } from 'react-use'; +import { EuiPopover, EuiText, EuiButtonIcon } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useKibana } from '../../../../../../common/lib/kibana'; + +/** + * Theme doesn't expose width variables. Using provided size variables will require + * multiplying it by another magic constant. + * + * 320px width looks + * like a [commonly used width in EUI](https://github.com/search?q=repo%3Aelastic%2Feui%20320&type=code). + */ +const POPOVER_WIDTH = 320; + +export function FinalSideHelpInfo(): JSX.Element { + const [isPopoverOpen, togglePopover] = useToggle(false); + const { docLinks } = useKibana().services; + + const button = ( + + ); + + return ( + + + + // + // + // ), + // semverLink: ( + // + // + // + // ), + // }} + /> + + + ); +} 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/final_side/translations.ts new file mode 100644 index 0000000000000..aa9b4885a964d --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/translations.ts @@ -0,0 +1,15 @@ +/* + * 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 UPGRADED_VERSION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.upgradedVersion', + { + defaultMessage: 'Upgraded version', + } +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_field.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_field.tsx new file mode 100644 index 0000000000000..56b85f0759274 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_field.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 from 'react'; +import { + EuiAccordion, + EuiFlexGroup, + EuiFlexItem, + EuiPanel, + EuiSpacer, + useEuiTheme, + useGeneratedHtmlId, +} from '@elastic/eui'; +import { css } from '@emotion/css'; +import type { + DiffableAllFields, + DiffableRule, + ThreeWayDiff, +} from '../../../../../../common/api/detection_engine'; +import { ThreeWayDiffConflict } from '../../../../../../common/api/detection_engine'; +import { ComparisonSide } from './comparison_side/comparison_side'; +import { FinalSide } from './final_side/final_side'; + +interface RuleDiffFieldProps { + fieldName: FieldName; + fieldThreeWayDiff: ThreeWayDiff; + finalDiffableRule: DiffableRule; + resolvedValue?: DiffableAllFields[FieldName]; +} + +export function RuleDiffField({ + fieldName, + fieldThreeWayDiff, + finalDiffableRule, + resolvedValue, +}: RuleDiffFieldProps): JSX.Element { + const { euiTheme } = useEuiTheme(); + const accordionId = useGeneratedHtmlId({ prefix: 'rule-diff-accordion' }); + const hasConflict = fieldThreeWayDiff.conflict !== ThreeWayDiffConflict.NONE; + + return ( + <> + + + + + + + + + + + + + + + + ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx new file mode 100644 index 0000000000000..73d81643fa23b --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx @@ -0,0 +1,37 @@ +/* + * 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 { + DiffableAllFields, + ThreeWayDiff, +} from '../../../../../../common/api/detection_engine'; +import type { RuleUpgradeState } from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; +import { RuleDiffField } from './rule_diff_field'; + +interface RuleDiffSectionProps { + ruleUpgradeState: RuleUpgradeState; +} + +export function RuleDiffSection({ ruleUpgradeState }: RuleDiffSectionProps): JSX.Element { + const fieldNames = Object.keys(ruleUpgradeState.diff.fields) as Array< + keyof typeof ruleUpgradeState.diff.fields + >; + const fields = fieldNames.map((fieldName) => ( + + } + finalDiffableRule={ruleUpgradeState.finalRule} + resolvedValue={ruleUpgradeState.finalRule[fieldName]} + /> + )); + + return <>{fields}; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx new file mode 100644 index 0000000000000..82be37b0c53bd --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx @@ -0,0 +1,34 @@ +/* + * 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, + SetFieldResolvedValueFn, +} from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; +import { UpgradeInfoBar } from './upgrade_info_bar'; +import { RuleDiffSection } from './rule_diff_section'; + +interface ThreeWayDiffTabProps { + ruleUpgradeState: RuleUpgradeState; + setFieldResolvedValue: SetFieldResolvedValueFn; +} + +export function ThreeWayDiffTab({ + ruleUpgradeState, + setFieldResolvedValue, +}: ThreeWayDiffTabProps): JSX.Element { + return ( + <> + + + + + + ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.tsx new file mode 100644 index 0000000000000..f054eec363121 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.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 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) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.fieldsWithUpdates', + { + values: { count }, + defaultMessage: 'Upgrade has {count} {count, plural, one {field} other {fields}}', + } + ); + +export const NUM_OF_CONFLICTS = (count: number) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.numOfConflicts', + { + values: { count }, + defaultMessage: '{count} {count, plural, one {conflict} other {conflicts}}', + } + ); + +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/upgrade_info_bar.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/upgrade_info_bar.tsx new file mode 100644 index 0000000000000..7be620e0a3f95 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/upgrade_info_bar.tsx @@ -0,0 +1,47 @@ +/* + * 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 } from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; +import { + UtilityBar, + UtilityBarGroup, + UtilityBarSection, + UtilityBarText, +} from '../../../../../common/components/utility_bar'; +import * as i18n from './translations'; + +interface UpgradeInfoBarProps { + ruleUpgradeState: RuleUpgradeState; +} + +export function UpgradeInfoBar({ ruleUpgradeState }: UpgradeInfoBarProps): JSX.Element { + const numOfFieldsWithUpdates = ruleUpgradeState.diff.num_fields_with_updates; + const numOfConflicts = ruleUpgradeState.diff.num_fields_with_conflicts; + + return ( + + + + + {i18n.NUM_OF_FIELDS_WITH_UPDATES(numOfFieldsWithUpdates)} + + + + + {i18n.NUM_OF_CONFLICTS(numOfConflicts)} + + + + + + + + + + ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff_tab.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff_tab.tsx deleted file mode 100644 index 5117fa2d7b93b..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff_tab.tsx +++ /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 React from 'react'; -import type { DiffableRule } from '../../../../../common/api/detection_engine'; -import type { SetFieldResolvedValueFn } from '../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; - -interface ThreeWayDiffTabProps { - finalDiffableRule: DiffableRule; - setFieldResolvedValue: SetFieldResolvedValueFn; -} - -export function ThreeWayDiffTab({ - finalDiffableRule, - setFieldResolvedValue, -}: ThreeWayDiffTabProps): JSX.Element { - return <>{JSON.stringify(finalDiffableRule)}; -} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/translations.ts index f0b96bad1aff5..89c22a285e327 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/translations.ts @@ -28,13 +28,6 @@ export const UPDATES_TAB_LABEL = i18n.translate( } ); -export const DIFF_TAB_LABEL = i18n.translate( - 'xpack.securitySolution.detectionEngine.ruleDetails.diffTabLabel', - { - defaultMessage: 'Diff', - } -); - export const JSON_VIEW_UPDATES_TAB_LABEL = i18n.translate( 'xpack.securitySolution.detectionEngine.ruleDetails.jsonViewUpdatesTabLabel', { 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 efd63e5da6872..b8ba10506a461 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 @@ -9,7 +9,7 @@ import type { Dispatch, SetStateAction } from 'react'; import React, { createContext, useCallback, useContext, useMemo, useState } from 'react'; import { EuiButton, EuiToolTip } from '@elastic/eui'; import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features'; -import { ThreeWayDiffTab } from '../../../../rule_management/components/rule_details/three_way_diff_tab'; +import { ThreeWayDiffTab } from '../../../../rule_management/components/rule_details/three_way_diff/three_way_diff_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 { useInstalledSecurityJobs } from '../../../../../common/components/ml/hooks/use_installed_security_jobs'; @@ -225,7 +225,46 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ return []; } - const extraTabs = [ + const jsonViewUpdates = { + id: 'jsonViewUpdates', + name: ( + + <>{ruleDetailsI18n.JSON_VIEW_UPDATES_TAB_LABEL} + + ), + content: ( + + + + ), + }; + + if (isPrebuiltRulesCustomizationEnabled) { + return [ + { + id: 'updates', + name: ( + + <>{ruleDetailsI18n.UPDATES_TAB_LABEL} + + ), + content: ( + + + + ), + }, + jsonViewUpdates, + ]; + } + + return [ { id: 'updates', name: ( @@ -239,44 +278,8 @@ export const UpgradePrebuiltRulesTableContextProvider = ({
), }, - { - id: 'jsonViewUpdates', - name: ( - - <>{ruleDetailsI18n.JSON_VIEW_UPDATES_TAB_LABEL} - - ), - content: ( - - - - ), - }, + jsonViewUpdates, ]; - - if (isPrebuiltRulesCustomizationEnabled) { - extraTabs.unshift({ - id: 'diff', - name: ( - - <>{ruleDetailsI18n.DIFF_TAB_LABEL} - - ), - content: ( - - - - ), - }); - } - - return extraTabs; }, [rulesUpgradeState, setFieldResolvedValue, isPrebuiltRulesCustomizationEnabled] ); From f9915665dbd9c83e734a9730423815f4bebc120d Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Tue, 24 Sep 2024 10:44:51 +0200 Subject: [PATCH 09/40] Set up data passage to make field forms work --- .../comparison_side/comparison_side.tsx | 17 ++++++-- .../three_way_diff/comparison_side/utils.ts | 6 +-- .../three_way_diff/final_side/final_side.tsx | 41 ++++++++++++++----- .../three_way_diff/rule_diff_field.tsx | 13 ++++-- .../three_way_diff/rule_diff_section.tsx | 13 ++++-- .../three_way_diff/three_way_diff_tab.tsx | 13 +++++- .../upgrade_prebuilt_rules_table_context.tsx | 1 + .../use_prebuilt_rules_upgrade_state.ts | 37 +++++++++-------- .../rules_table/use_rule_preview_flyout.tsx | 6 +-- 9 files changed, 99 insertions(+), 48 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side.tsx index 9ef207b0bb998..e384ef5e4e79d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/comparison_side.tsx @@ -21,13 +21,13 @@ import { SideHeader } from '../components/side_header'; interface ComparisonSideProps { fieldName: FieldName; fieldThreeWayDiff: ThreeWayDiff; - resolvedValue?: DiffableAllFields[FieldName]; + finalFieldValue: DiffableAllFields[FieldName]; } export function ComparisonSide({ fieldName, fieldThreeWayDiff, - resolvedValue, + finalFieldValue, }: ComparisonSideProps) { const [selectedVersions, setSelectedVersions] = useState( SelectedVersions.CurrentFinal @@ -35,8 +35,17 @@ export function ComparisonSide({ const [oldVersionType, newVersionType] = selectedVersions.split('_') as [Version, Version]; - const oldFieldValue = pickFieldValueForVersion(oldVersionType, fieldThreeWayDiff, resolvedValue); - const newFieldValue = pickFieldValueForVersion(newVersionType, fieldThreeWayDiff, resolvedValue); + const oldFieldValue = pickFieldValueForVersion( + oldVersionType, + fieldThreeWayDiff, + finalFieldValue + ); + + const newFieldValue = pickFieldValueForVersion( + newVersionType, + fieldThreeWayDiff, + finalFieldValue + ); const subfieldChanges = getSubfieldChanges(fieldName, oldFieldValue, newFieldValue); 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 fd16366f1a76e..b3a2e9040060c 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 @@ -17,16 +17,16 @@ import type { * * @param version - The version for which the field value is to be picked. * @param fieldThreeWayDiff - The three-way diff object containing the field values for different versions. - * @param resolvedValue - The user-set resolved value resolved value. Used if it is set and the version is final. + * @param finalFieldValue - Final field value: the value that the user expects to see in the upgraded rule. * @returns - The field value for the specified version */ export function pickFieldValueForVersion( version: Version, fieldThreeWayDiff: ThreeWayDiff, - resolvedValue?: DiffableAllFields[FieldName] + finalFieldValue: DiffableAllFields[FieldName] ): DiffableAllFields[FieldName] | undefined { if (version === Version.Final) { - return resolvedValue ?? fieldThreeWayDiff.merged_version; + return finalFieldValue; } const versionFieldToPick = `${version}_version` as const; 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/final_side/final_side.tsx index 06aff8f244b41..2b6ec374a7039 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/final_side/final_side.tsx @@ -5,23 +5,32 @@ * 2.0. */ -import React from 'react'; +import React, { useCallback } from 'react'; import { EuiTitle } from '@elastic/eui'; -import type { - DiffableAllFields, - DiffableRule, -} from '../../../../../../../common/api/detection_engine'; -import { FieldReadOnly } from '../final_readonly/field_readonly'; +import type { DiffableRule } from '../../../../../../../common/api/detection_engine'; 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 { FinalEdit } from '../final_edit/final_edit_2'; +import type { SetFieldResolvedValueFn } from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; interface FinalSideProps { fieldName: string; finalDiffableRule: DiffableRule; + setFieldResolvedValue: SetFieldResolvedValueFn; } -export function FinalSide({ fieldName, finalDiffableRule }: FinalSideProps): JSX.Element { +export function FinalSide({ + fieldName, + finalDiffableRule, + setFieldResolvedValue, +}: FinalSideProps): JSX.Element { + const [mode, setMode] = React.useState<'readonly' | 'edit'>('readonly'); // This is temporary, will be replaced with state from the context + const setReadOnlyMode = useCallback(() => setMode('readonly'), []); + const setEditMode = useCallback(() => setMode('edit'), []); + return ( <> @@ -32,10 +41,20 @@ export function FinalSide({ fieldName, finalDiffableRule }: FinalSideProps): JSX - + {mode === 'edit' ? ( + + ) : ( + + )} ); } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_field.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_field.tsx index 56b85f0759274..4a62f0494a580 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_field.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_field.tsx @@ -24,19 +24,20 @@ import type { import { ThreeWayDiffConflict } from '../../../../../../common/api/detection_engine'; import { ComparisonSide } from './comparison_side/comparison_side'; import { FinalSide } from './final_side/final_side'; +import type { SetFieldResolvedValueFn } from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; interface RuleDiffFieldProps { fieldName: FieldName; fieldThreeWayDiff: ThreeWayDiff; finalDiffableRule: DiffableRule; - resolvedValue?: DiffableAllFields[FieldName]; + setFieldResolvedValue: SetFieldResolvedValueFn; } export function RuleDiffField({ fieldName, fieldThreeWayDiff, finalDiffableRule, - resolvedValue, + setFieldResolvedValue, }: RuleDiffFieldProps): JSX.Element { const { euiTheme } = useEuiTheme(); const accordionId = useGeneratedHtmlId({ prefix: 'rule-diff-accordion' }); @@ -56,7 +57,7 @@ export function RuleDiffField({
({ `} /> - + diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx index 73d81643fa23b..f596f3c9b8ed3 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx @@ -10,14 +10,21 @@ import type { DiffableAllFields, ThreeWayDiff, } from '../../../../../../common/api/detection_engine'; -import type { RuleUpgradeState } from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; +import type { + RuleUpgradeState, + SetFieldResolvedValueFn, +} from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; import { RuleDiffField } from './rule_diff_field'; interface RuleDiffSectionProps { ruleUpgradeState: RuleUpgradeState; + setFieldResolvedValue: SetFieldResolvedValueFn; } -export function RuleDiffSection({ ruleUpgradeState }: RuleDiffSectionProps): JSX.Element { +export function RuleDiffSection({ + ruleUpgradeState, + setFieldResolvedValue, +}: RuleDiffSectionProps): JSX.Element { const fieldNames = Object.keys(ruleUpgradeState.diff.fields) as Array< keyof typeof ruleUpgradeState.diff.fields >; @@ -29,7 +36,7 @@ export function RuleDiffSection({ ruleUpgradeState }: RuleDiffSectionProps): JSX ruleUpgradeState.diff.fields[fieldName] as ThreeWayDiff } finalDiffableRule={ruleUpgradeState.finalRule} - resolvedValue={ruleUpgradeState.finalRule[fieldName]} + setFieldResolvedValue={setFieldResolvedValue} /> )); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx index 82be37b0c53bd..7e4df29563293 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx @@ -13,22 +13,31 @@ import type { } from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; import { UpgradeInfoBar } from './upgrade_info_bar'; import { RuleDiffSection } from './rule_diff_section'; +import type { RuleSignatureId } from '../../../../../../common/api/detection_engine'; interface ThreeWayDiffTabProps { + ruleId: RuleSignatureId; ruleUpgradeState: RuleUpgradeState; - setFieldResolvedValue: SetFieldResolvedValueFn; + setFieldResolvedValue: (ruleId: RuleSignatureId) => SetFieldResolvedValueFn; } export function ThreeWayDiffTab({ + ruleId, ruleUpgradeState, setFieldResolvedValue, }: ThreeWayDiffTabProps): JSX.Element { + // TODO: Find a better name for this function to avoid confusion with the one that is not ruleId-specific + const setFieldResolvedValueForRule = setFieldResolvedValue(ruleId); + 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 b8ba10506a461..307c49e2a1ac9 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 @@ -254,6 +254,7 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ content: ( 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 86f2293d312fa..20a87c10cf4bd 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,14 +6,13 @@ */ import { useCallback, useMemo, useState } from 'react'; -import type { FieldsDiff } from '../../../../../../common/api/detection_engine'; import { - ThreeWayDiffConflict, + type FieldsDiff, type DiffableAllFields, type DiffableRule, - type RuleObjectId, type RuleSignatureId, type RuleUpgradeInfoForReview, + ThreeWayDiffConflict, } from '../../../../../../common/api/detection_engine'; import { convertRuleToDiffable } from '../../../../../../common/detection_engine/prebuilt_rules/diff/convert_rule_to_diffable'; @@ -30,33 +29,35 @@ export interface RuleUpgradeState extends RuleUpgradeInfoForReview { export type RulesUpgradeState = Record; export type SetFieldResolvedValueFn< FieldName extends keyof DiffableAllFields = keyof DiffableAllFields -> = (params: { - ruleId: RuleObjectId; - fieldName: FieldName; - resolvedValue: DiffableAllFields[FieldName]; -}) => void; +> = (params: { fieldName: FieldName; resolvedValue: DiffableAllFields[FieldName] }) => void; type RuleResolvedConflicts = Partial; type RulesResolvedConflicts = Record; interface UseRulesUpgradeStateResult { rulesUpgradeState: RulesUpgradeState; - setFieldResolvedValue: SetFieldResolvedValueFn; + setFieldResolvedValue: (ruleId: RuleSignatureId) => SetFieldResolvedValueFn; } export function usePrebuiltRulesUpgradeState( ruleUpgradeInfos: RuleUpgradeInfoForReview[] ): UseRulesUpgradeStateResult { const [rulesResolvedConflicts, setRulesResolvedConflicts] = useState({}); - const setFieldResolvedValue = useCallback((...[params]: Parameters) => { - setRulesResolvedConflicts((prevRulesResolvedConflicts) => ({ - ...prevRulesResolvedConflicts, - [params.ruleId]: { - ...(prevRulesResolvedConflicts[params.ruleId] ?? {}), - [params.fieldName]: params.resolvedValue, + + const setFieldResolvedValue = useCallback( + (ruleId: RuleSignatureId) => + (...[params]: Parameters) => { + setRulesResolvedConflicts((prevRulesResolvedConflicts) => ({ + ...prevRulesResolvedConflicts, + [ruleId]: { + ...(prevRulesResolvedConflicts[ruleId] ?? {}), + [params.fieldName]: params.resolvedValue, + }, + })); }, - })); - }, []); + [] + ); + const rulesUpgradeState = useMemo(() => { const state: RulesUpgradeState = {}; @@ -96,7 +97,7 @@ function calcFinalDiffableRule( } /** - * Assembles a `DiffableRule` from rule fields diff `merge_value`s. + * Assembles a `DiffableRule` from rule fields diff `merged_version`s. */ function convertRuleFieldsDiffToDiffable( ruleFieldsDiff: FieldsDiff> 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 ccdfd5c39177e..d6dcdd0592b85 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 @@ -9,7 +9,7 @@ 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 { RuleObjectId } from '../../../../../common/api/detection_engine'; +import type { RuleSignatureId } from '../../../../../common/api/detection_engine'; import type { RuleResponse } from '../../../../../common/api/detection_engine/model/rule_schema'; import { RuleDetailsFlyout } from '../../../rule_management/components/rule_details/rule_details_flyout'; @@ -30,7 +30,7 @@ interface RulePreviewFlyoutProps { interface UseRulePreviewFlyoutResult { rulePreviewFlyout: ReactNode; - openRulePreview: (ruleId: RuleObjectId) => void; + openRulePreview: (ruleId: RuleSignatureId) => void; closeRulePreview: () => void; } @@ -64,7 +64,7 @@ export function useRulePreviewFlyout({ /> ), openRulePreview: useCallback( - (ruleId: RuleObjectId) => { + (ruleId: RuleSignatureId) => { const ruleToShowInFlyout = rules.find((x) => x.id === ruleId); invariant(ruleToShowInFlyout, `Rule with id ${ruleId} not found`); From ee92867a2b297935fdf1953eb961c99d88a4d49d Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Tue, 24 Sep 2024 12:43:54 +0200 Subject: [PATCH 10/40] Add `FieldFormWrapper` to encapsulate form setup --- .../final_edit/field_form_wrapper.tsx | 54 +++++++++++++++++++ .../three_way_diff/final_edit/fields/name.tsx | 28 ++++++++++ .../three_way_diff/final_edit/final_edit.tsx | 47 ++++++++++++++++ .../final_edit/final_edit_context.tsx | 37 +++++++++++++ .../final_readonly/final_readonly.tsx | 28 ++++++++++ .../three_way_diff/final_side/final_side.tsx | 3 +- 6 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/name.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/final_readonly.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx new file mode 100644 index 0000000000000..92000cc3b5635 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx @@ -0,0 +1,54 @@ +/* + * 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 { useForm, type FormSchema, Form } from '../../../../../../shared_imports'; +import type { DiffableAllFields } from '../../../../../../../common/api/detection_engine'; +import { useFinalEditContext } from './final_edit_context'; + +interface FieldFormWrapperProps { + component: React.ComponentType; + fieldFormSchema: FormSchema; +} + +export function FieldFormWrapper({ + component: FieldComponent, + fieldFormSchema, +}: FieldFormWrapperProps) { + const { fieldName, finalDiffableRule, setReadOnlyMode, setFieldResolvedValue } = + useFinalEditContext(); + + const { form } = useForm({ + schema: fieldFormSchema, + defaultValue: { [fieldName]: finalDiffableRule[fieldName] }, + serializer: (value) => value, + onSubmit: async (formData) => { + setFieldResolvedValue({ + fieldName: fieldName as keyof DiffableAllFields, // TODO: This is temporary until we decide which type to use + resolvedValue: formData[fieldName], + }); + setReadOnlyMode(); + }, + }); + + return ( + <> + + + {'Cancel'} + + + {'Save'} + + +
+ + + + ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/name.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/name.tsx new file mode 100644 index 0000000000000..a789c58574495 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/name.tsx @@ -0,0 +1,28 @@ +/* + * 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 { FormSchema } from '../../../../../../../shared_imports'; +import { Field, UseField } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_about_rule/schema'; +import type { RuleName } from '../../../../../../../../common/api/detection_engine'; + +export const nameSchema = { name: schema.name } as FormSchema<{ name: RuleName }>; + +export function NameEdit() { + return ( + + ); +} 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/final_edit.tsx new file mode 100644 index 0000000000000..3146dd5d95ae9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit.tsx @@ -0,0 +1,47 @@ +/* + * 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 { SetFieldResolvedValueFn } from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; +import { NameEdit, nameSchema } from './fields/name'; +import type { DiffableRule } from '../../../../../../../common/api/detection_engine'; +import { FieldFormWrapper } from './field_form_wrapper'; +import { FinalEditContextProvider } from './final_edit_context'; + +interface FinalEditProps { + fieldName: string; + finalDiffableRule: DiffableRule; + setReadOnlyMode: () => void; + setFieldResolvedValue: SetFieldResolvedValueFn; +} + +export function FinalEdit({ + fieldName, + finalDiffableRule, + setReadOnlyMode, + setFieldResolvedValue, +}: FinalEditProps) { + return ( + + + + ); +} + +interface FinalEditFieldProps { + fieldName: string; +} + +function FinalEditField({ fieldName }: FinalEditFieldProps) { + if (fieldName === 'name') { + return ; + } + + return {'Field not yet implemented'}; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx new file mode 100644 index 0000000000000..f57205f5de0ae --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx @@ -0,0 +1,37 @@ +/* + * 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 type { SetFieldResolvedValueFn } from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; +import { invariant } from '../../../../../../../common/utils/invariant'; + +interface FinalEditContextType { + fieldName: string; + finalDiffableRule: DiffableRule; + setReadOnlyMode: () => void; + setFieldResolvedValue: SetFieldResolvedValueFn; +} + +const FinalEditContext = createContext(null); + +interface FinalEditContextProviderProps { + children: React.ReactNode; + value: FinalEditContextType; +} + +export function FinalEditContextProvider({ children, value }: FinalEditContextProviderProps) { + return {children}; +} + +export function useFinalEditContext() { + const context = useContext(FinalEditContext); + + invariant(context !== null, 'useFinalEditContext must be used inside a FinalEditContextProvider'); + + return context; +} 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/final_readonly.tsx new file mode 100644 index 0000000000000..9dc2d01118e6c --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/final_readonly.tsx @@ -0,0 +1,28 @@ +/* + * 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 { EuiButtonEmpty } from '@elastic/eui'; +import React from 'react'; +import type { DiffableRule } from '../../../../../../../common/api/detection_engine'; +import { FieldReadOnly } from './field_readonly'; + +interface FinalReadOnlyProps { + fieldName: string; + finalDiffableRule: DiffableRule; + setEditMode: () => void; +} + +export function FinalReadOnly({ fieldName, finalDiffableRule, setEditMode }: FinalReadOnlyProps) { + return ( + <> + + {'Edit'} + + + + ); +} 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/final_side/final_side.tsx index 2b6ec374a7039..6a2551c9abe35 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/final_side/final_side.tsx @@ -12,9 +12,8 @@ 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 { FinalEdit } from '../final_edit/final_edit_2'; import type { SetFieldResolvedValueFn } from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; +import { FinalEdit } from '../final_edit/final_edit'; interface FinalSideProps { fieldName: string; From 2684b22b5e92f3ae7c105656c6fb121791bdec44 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Tue, 24 Sep 2024 13:15:00 +0200 Subject: [PATCH 11/40] Extract common fields into a separate component --- .../final_edit/common_rule_field_edit.tsx | 24 ++++++++++ .../three_way_diff/final_edit/final_edit.tsx | 47 +++++++++++++++---- 2 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/common_rule_field_edit.tsx 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 new file mode 100644 index 0000000000000..b0f163801c0b7 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/common_rule_field_edit.tsx @@ -0,0 +1,24 @@ +/* + * 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 { DiffableCommonFields } from '../../../../../../../common/api/detection_engine'; +import { NameEdit, nameSchema } from './fields/name'; +import { FieldFormWrapper } from './field_form_wrapper'; + +interface CommonRuleFieldEditProps { + fieldName: keyof DiffableCommonFields; +} + +export function CommonRuleFieldEdit({ fieldName }: CommonRuleFieldEditProps) { + switch (fieldName) { + case 'name': + return ; + default: + return null; // Will be replaced with `assertUnreachable(fieldName)` once all fields are implemented + } +} 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/final_edit.tsx index 3146dd5d95ae9..4d11eb1b46591 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/final_edit.tsx @@ -5,12 +5,16 @@ * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; import type { SetFieldResolvedValueFn } from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; -import { NameEdit, nameSchema } from './fields/name'; -import type { DiffableRule } from '../../../../../../../common/api/detection_engine'; -import { FieldFormWrapper } from './field_form_wrapper'; +import { DiffableCommonFields } from '../../../../../../../common/api/detection_engine'; +import type { + DiffableRule, + DiffableRuleTypes, +} from '../../../../../../../common/api/detection_engine'; import { FinalEditContextProvider } from './final_edit_context'; +import { CommonRuleFieldEdit } from './common_rule_field_edit'; +import { assertUnreachable } from '../../../../../../../common/utility_types'; interface FinalEditProps { fieldName: string; @@ -29,19 +33,44 @@ export function FinalEdit({ - + ); } interface FinalEditFieldProps { fieldName: string; + ruleType: DiffableRuleTypes; } -function FinalEditField({ fieldName }: FinalEditFieldProps) { - if (fieldName === 'name') { - return ; +function FieldEdit({ fieldName, ruleType }: FinalEditFieldProps) { + const { data: commonField } = useMemo( + () => DiffableCommonFields.keyof().safeParse(fieldName), + [fieldName] + ); + + if (commonField) { + return ; } - return {'Field not yet implemented'}; + switch (ruleType) { + case 'query': + return {'Rule type not yet implemented'}; + case 'saved_query': + return {'Rule type not yet implemented'}; + case 'eql': + return {'Rule type not yet implemented'}; + case 'esql': + return {'Rule type not yet implemented'}; + case 'threat_match': + return {'Rule type not yet implemented'}; + case 'threshold': + return {'Rule type not yet implemented'}; + case 'machine_learning': + return {'Rule type not yet implemented'}; + case 'new_terms': + return {'Rule type not yet implemented'}; + default: + return assertUnreachable(ruleType); + } } From d7537242802e080252f2c8e17f1ed4db611d0863 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Mon, 30 Sep 2024 15:36:59 +0200 Subject: [PATCH 12/40] Account for renames in Maxim's PR --- .../three_way_diff/comparison_side/utils.ts | 2 +- .../field_upgrade_conflicts_resolver.tsx | 9 +- .../rule_upgrade_conflicts_resolver.tsx | 1 + .../final_edit/field_form_wrapper.tsx | 4 +- .../three_way_diff/final_edit/final_edit.tsx | 6 +- .../final_edit/final_edit_context.tsx | 2 +- .../three_way_diff/final_side/final_side.tsx | 6 +- .../three_way_diff/rule_diff_field.tsx | 83 ------------------- .../three_way_diff/rule_diff_section.tsx | 44 ---------- .../rule_upgrade_conflicts_resolver_tab.tsx | 10 ++- .../three_way_diff/three_way_diff_tab.tsx | 43 ---------- .../upgrade_prebuilt_rules_table_context.tsx | 1 + 12 files changed, 28 insertions(+), 183 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_field.tsx delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx 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 82dc66754447b..fa2560e64655c 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 @@ -17,7 +17,7 @@ import type { * * @param version - The version for which the field value is to be picked. * @param fieldThreeWayDiff - The three-way diff object containing the field values for different versions. - * @param finalFieldValue - Final field value: the value that the user expects to see in the upgraded rule. + * @param resolvedValue - Field value that the upgraded rule will have. * @returns - The field value for the specified version */ export function pickFieldValueForVersion( 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 eeafddfc21f03..e261d7d9b7e84 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 @@ -19,17 +19,20 @@ import { ThreeWayDiffConflict } from '../../../../../../../common/api/detection_ import { ComparisonSide } from '../comparison_side/comparison_side'; import { FinalSide } from '../final_side/final_side'; import { FieldUpgradeConflictsResolverHeader } from './field_upgrade_conflicts_resolver_header'; +import { type SetRuleFieldResolvedValueFn } from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; interface FieldUpgradeConflictsResolverProps { fieldName: FieldName; fieldThreeWayDiff: RuleFieldsDiff[FieldName]; finalDiffableRule: DiffableRule; + setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } export function FieldUpgradeConflictsResolver({ fieldName, fieldThreeWayDiff, finalDiffableRule, + setRuleFieldResolvedValue, }: FieldUpgradeConflictsResolverProps): JSX.Element { const { euiTheme } = useEuiTheme(); const hasConflict = fieldThreeWayDiff.conflict !== ThreeWayDiffConflict.NONE; @@ -57,7 +60,11 @@ 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_conflicts_resolver.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_conflicts_resolver.tsx index 57af1b340c776..c0f46a53b024e 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/components/rule_upgrade_conflicts_resolver.tsx @@ -33,6 +33,7 @@ export function RuleUpgradeConflictsResolver({ fieldName={fieldName} fieldThreeWayDiff={fieldDiff} finalDiffableRule={ruleUpgradeState.finalRule} + setRuleFieldResolvedValue={setRuleFieldResolvedValue} /> )); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx index 92000cc3b5635..a9c7c7ea6a83a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx @@ -20,7 +20,7 @@ export function FieldFormWrapper({ component: FieldComponent, fieldFormSchema, }: FieldFormWrapperProps) { - const { fieldName, finalDiffableRule, setReadOnlyMode, setFieldResolvedValue } = + const { fieldName, finalDiffableRule, setReadOnlyMode, setRuleFieldResolvedValue } = useFinalEditContext(); const { form } = useForm({ @@ -28,7 +28,7 @@ export function FieldFormWrapper({ defaultValue: { [fieldName]: finalDiffableRule[fieldName] }, serializer: (value) => value, onSubmit: async (formData) => { - setFieldResolvedValue({ + setRuleFieldResolvedValue({ fieldName: fieldName as keyof DiffableAllFields, // TODO: This is temporary until we decide which type to use resolvedValue: formData[fieldName], }); 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/final_edit.tsx index a4c79489aeea8..ea55f8dc254eb 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/final_edit.tsx @@ -20,18 +20,18 @@ interface FinalEditProps { fieldName: string; finalDiffableRule: DiffableRule; setReadOnlyMode: () => void; - setFieldResolvedValue: SetRuleFieldResolvedValueFn; + setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } export function FinalEdit({ fieldName, finalDiffableRule, setReadOnlyMode, - setFieldResolvedValue, + setRuleFieldResolvedValue, }: FinalEditProps) { return ( diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx index 50fe09649ad35..a03c51b023f83 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx @@ -14,7 +14,7 @@ interface FinalEditContextType { fieldName: string; finalDiffableRule: DiffableRule; setReadOnlyMode: () => void; - setFieldResolvedValue: SetRuleFieldResolvedValueFn; + setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } const FinalEditContext = createContext(null); 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/final_side/final_side.tsx index 23b0f6e4c34f7..c8df3e90d7a76 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/final_side/final_side.tsx @@ -18,13 +18,13 @@ import { FinalEdit } from '../final_edit/final_edit'; interface FinalSideProps { fieldName: string; finalDiffableRule: DiffableRule; - setFieldResolvedValue: SetRuleFieldResolvedValueFn; + setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } export function FinalSide({ fieldName, finalDiffableRule, - setFieldResolvedValue, + setRuleFieldResolvedValue, }: FinalSideProps): JSX.Element { const [mode, setMode] = React.useState<'readonly' | 'edit'>('readonly'); // This is temporary, will be replaced with state from the context const setReadOnlyMode = useCallback(() => setMode('readonly'), []); @@ -45,7 +45,7 @@ export function FinalSide({ fieldName={fieldName} finalDiffableRule={finalDiffableRule} setReadOnlyMode={setReadOnlyMode} - setFieldResolvedValue={setFieldResolvedValue} + setRuleFieldResolvedValue={setRuleFieldResolvedValue} /> ) : ( { - fieldName: FieldName; - fieldThreeWayDiff: ThreeWayDiff; - finalDiffableRule: DiffableRule; - setFieldResolvedValue: SetRuleFieldResolvedValueFn; -} - -export function RuleDiffField({ - fieldName, - fieldThreeWayDiff, - finalDiffableRule, - setFieldResolvedValue, -}: RuleDiffFieldProps): JSX.Element { - const { euiTheme } = useEuiTheme(); - const accordionId = useGeneratedHtmlId({ prefix: 'rule-diff-accordion' }); - const hasConflict = fieldThreeWayDiff.conflict !== ThreeWayDiffConflict.NONE; - - return ( - <> - - - - - - - - - - - - - - - - ); -} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx deleted file mode 100644 index 6b33e2cb732b9..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/rule_diff_section.tsx +++ /dev/null @@ -1,44 +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 { - DiffableAllFields, - ThreeWayDiff, -} from '../../../../../../common/api/detection_engine'; -import type { - RuleUpgradeState, - SetRuleFieldResolvedValueFn, -} from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; -import { RuleDiffField } from './rule_diff_field'; - -interface RuleDiffSectionProps { - ruleUpgradeState: RuleUpgradeState; - setFieldResolvedValue: SetRuleFieldResolvedValueFn; -} - -export function RuleDiffSection({ - ruleUpgradeState, - setFieldResolvedValue, -}: RuleDiffSectionProps): JSX.Element { - const fieldNames = Object.keys(ruleUpgradeState.diff.fields) as Array< - keyof typeof ruleUpgradeState.diff.fields - >; - const fields = fieldNames.map((fieldName) => ( - - } - finalDiffableRule={ruleUpgradeState.finalRule} - setFieldResolvedValue={setFieldResolvedValue} - /> - )); - - return <>{fields}; -} 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 index 10823b8045c96..b32835e0fac5d 100644 --- 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 @@ -13,16 +13,22 @@ import type { } from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; import { RuleUpgradeInfoBar } from './components/rule_upgrade_info_bar'; import { RuleUpgradeConflictsResolver } from './components/rule_upgrade_conflicts_resolver'; +import type { RuleSignatureId } from '../../../../../../common/api/detection_engine'; interface RuleUpgradeConflictsResolverTabProps { + ruleId: RuleSignatureId; ruleUpgradeState: RuleUpgradeState; - setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; + setRuleFieldResolvedValue: (ruleId: RuleSignatureId) => SetRuleFieldResolvedValueFn; } export function RuleUpgradeConflictsResolverTab({ + ruleId, ruleUpgradeState, setRuleFieldResolvedValue, }: RuleUpgradeConflictsResolverTabProps): JSX.Element { + // TODO: Find a better name for this function to avoid confusion with the one that is not ruleId-specific + const setFieldResolvedValueForRule = setRuleFieldResolvedValue(ruleId); + return ( <> @@ -30,7 +36,7 @@ export function RuleUpgradeConflictsResolverTab({ ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx deleted file mode 100644 index df484e99fe564..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/three_way_diff_tab.tsx +++ /dev/null @@ -1,43 +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 '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; -import { UpgradeInfoBar } from './upgrade_info_bar'; -import { RuleDiffSection } from './rule_diff_section'; -import type { RuleSignatureId } from '../../../../../../common/api/detection_engine'; - -interface ThreeWayDiffTabProps { - ruleId: RuleSignatureId; - ruleUpgradeState: RuleUpgradeState; - setFieldResolvedValue: (ruleId: RuleSignatureId) => SetRuleFieldResolvedValueFn; -} - -export function ThreeWayDiffTab({ - ruleId, - ruleUpgradeState, - setFieldResolvedValue, -}: ThreeWayDiffTabProps): JSX.Element { - // TODO: Find a better name for this function to avoid confusion with the one that is not ruleId-specific - const setFieldResolvedValueForRule = setFieldResolvedValue(ruleId); - - 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 997f85d3ddce0..695fc2dcb9b90 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 @@ -254,6 +254,7 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ content: ( From 076c7a0a9315a1ee88e2141b0f2505ae6e4996bb Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Mon, 30 Sep 2024 15:47:09 +0200 Subject: [PATCH 13/40] Account for more renames --- .../three_way_diff/translations.tsx | 62 ------------------- .../three_way_diff/upgrade_info_bar.tsx | 47 -------------- 2 files changed, 109 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.tsx delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/upgrade_info_bar.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.tsx deleted file mode 100644 index f054eec363121..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/translations.tsx +++ /dev/null @@ -1,62 +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) => - i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.fieldsWithUpdates', - { - values: { count }, - defaultMessage: 'Upgrade has {count} {count, plural, one {field} other {fields}}', - } - ); - -export const NUM_OF_CONFLICTS = (count: number) => - i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.upgradeRules.diffTab.numOfConflicts', - { - values: { count }, - defaultMessage: '{count} {count, plural, one {conflict} other {conflicts}}', - } - ); - -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/upgrade_info_bar.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/upgrade_info_bar.tsx deleted file mode 100644 index 7be620e0a3f95..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/upgrade_info_bar.tsx +++ /dev/null @@ -1,47 +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 } from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; -import { - UtilityBar, - UtilityBarGroup, - UtilityBarSection, - UtilityBarText, -} from '../../../../../common/components/utility_bar'; -import * as i18n from './translations'; - -interface UpgradeInfoBarProps { - ruleUpgradeState: RuleUpgradeState; -} - -export function UpgradeInfoBar({ ruleUpgradeState }: UpgradeInfoBarProps): JSX.Element { - const numOfFieldsWithUpdates = ruleUpgradeState.diff.num_fields_with_updates; - const numOfConflicts = ruleUpgradeState.diff.num_fields_with_conflicts; - - return ( - - - - - {i18n.NUM_OF_FIELDS_WITH_UPDATES(numOfFieldsWithUpdates)} - - - - - {i18n.NUM_OF_CONFLICTS(numOfConflicts)} - - - - - - - - - - ); -} From 718c0883a0ea095a2c8715405259fd086ef4c972 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Tue, 1 Oct 2024 14:05:57 +0200 Subject: [PATCH 14/40] Pass `diffableRule` and field value setter via context --- .../field_upgrade_conflicts_resolver.tsx | 15 ++--- .../rule_upgrade_conflicts_resolver.tsx | 9 +-- .../three_way_diff/diffable_rule_context.tsx | 59 +++++++++++++++++++ .../final_edit/field_form_wrapper.tsx | 10 +++- .../three_way_diff/final_edit/final_edit.tsx | 22 ++----- .../final_edit/final_edit_context.tsx | 4 -- .../final_readonly/field_readonly.tsx | 7 ++- .../final_readonly/final_readonly.tsx | 6 +- .../three_way_diff/final_side/final_side.tsx | 23 +------- .../rule_upgrade_conflicts_resolver_tab.tsx | 21 +++---- .../upgrade_prebuilt_rules_table_context.tsx | 1 - .../use_prebuilt_rules_upgrade_state.ts | 27 +++++---- 12 files changed, 109 insertions(+), 95 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/diffable_rule_context.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 e261d7d9b7e84..b293815d1c0eb 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 @@ -11,7 +11,6 @@ import { css } from '@emotion/css'; import { SplitAccordion } from '../../../../../../common/components/split_accordion'; import type { DiffableAllFields, - DiffableRule, RuleFieldsDiff, ThreeWayDiff, } from '../../../../../../../common/api/detection_engine'; @@ -19,24 +18,22 @@ import { ThreeWayDiffConflict } from '../../../../../../../common/api/detection_ import { ComparisonSide } from '../comparison_side/comparison_side'; import { FinalSide } from '../final_side/final_side'; import { FieldUpgradeConflictsResolverHeader } from './field_upgrade_conflicts_resolver_header'; -import { type SetRuleFieldResolvedValueFn } from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; +import { useDiffableRuleContext } from '../diffable_rule_context'; interface FieldUpgradeConflictsResolverProps { fieldName: FieldName; fieldThreeWayDiff: RuleFieldsDiff[FieldName]; - finalDiffableRule: DiffableRule; - setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } export function FieldUpgradeConflictsResolver({ fieldName, fieldThreeWayDiff, - finalDiffableRule, - setRuleFieldResolvedValue, }: FieldUpgradeConflictsResolverProps): JSX.Element { const { euiTheme } = useEuiTheme(); const hasConflict = fieldThreeWayDiff.conflict !== ThreeWayDiffConflict.NONE; + const { finalDiffableRule } = useDiffableRuleContext(); + return ( <> - + 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/components/rule_upgrade_conflicts_resolver.tsx index c0f46a53b024e..b13366d32fca6 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/components/rule_upgrade_conflicts_resolver.tsx @@ -6,20 +6,15 @@ */ import React from 'react'; -import type { - RuleUpgradeState, - SetRuleFieldResolvedValueFn, -} from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; +import type { RuleUpgradeState } from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; import { FieldUpgradeConflictsResolver } from './field_upgrade_conflicts_resolver'; interface RuleUpgradeConflictsResolverProps { ruleUpgradeState: RuleUpgradeState; - setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } export function RuleUpgradeConflictsResolver({ ruleUpgradeState, - setRuleFieldResolvedValue, }: RuleUpgradeConflictsResolverProps): JSX.Element { const fieldDiffEntries = Object.entries(ruleUpgradeState.diff.fields) as Array< [ @@ -32,8 +27,6 @@ export function RuleUpgradeConflictsResolver({ key={fieldName} fieldName={fieldName} fieldThreeWayDiff={fieldDiff} - finalDiffableRule={ruleUpgradeState.finalRule} - setRuleFieldResolvedValue={setRuleFieldResolvedValue} /> )); 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/diffable_rule_context.tsx new file mode 100644 index 0000000000000..aef020173b2aa --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/diffable_rule_context.tsx @@ -0,0 +1,59 @@ +/* + * 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 '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; + +type ParamsWithoutRuleId = Omit[0], 'ruleId'>; + +interface DiffableRuleContextType { + finalDiffableRule: DiffableRule; + setRuleFieldResolvedValue: (paramsWithoutRuleId: ParamsWithoutRuleId) => void; +} + +const DiffableRuleContext = createContext(null); + +interface DiffableRuleContextProviderProps { + finalDiffableRule: DiffableRule; + setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; + children: React.ReactNode; +} + +export function DiffableRuleContextProvider({ + finalDiffableRule, + setRuleFieldResolvedValue, + children, +}: DiffableRuleContextProviderProps) { + const setRuleFieldResolvedValueWithRuleId = ({ + fieldName, + resolvedValue, + }: ParamsWithoutRuleId) => { + setRuleFieldResolvedValue({ ruleId: finalDiffableRule.rule_id, fieldName, resolvedValue }); + }; + + const contextValue = { + finalDiffableRule, + setRuleFieldResolvedValue: setRuleFieldResolvedValueWithRuleId, + }; + + return ( + {children} + ); +} + +export function useDiffableRuleContext() { + const context = useContext(DiffableRuleContext); + + invariant( + context !== null, + 'useDiffableRuleContext must be used inside a DiffableRuleContextProvider' + ); + + return context; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx index a9c7c7ea6a83a..b2abd8fcf14d5 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx @@ -10,6 +10,7 @@ import { EuiButtonEmpty, EuiFlexGroup } from '@elastic/eui'; import { useForm, type FormSchema, Form } from '../../../../../../shared_imports'; import type { DiffableAllFields } from '../../../../../../../common/api/detection_engine'; import { useFinalEditContext } from './final_edit_context'; +import { useDiffableRuleContext } from '../diffable_rule_context'; interface FieldFormWrapperProps { component: React.ComponentType; @@ -20,12 +21,15 @@ export function FieldFormWrapper({ component: FieldComponent, fieldFormSchema, }: FieldFormWrapperProps) { - const { fieldName, finalDiffableRule, setReadOnlyMode, setRuleFieldResolvedValue } = - useFinalEditContext(); + const { fieldName, setReadOnlyMode } = useFinalEditContext(); + + const { finalDiffableRule, setRuleFieldResolvedValue } = useDiffableRuleContext(); const { form } = useForm({ schema: fieldFormSchema, - defaultValue: { [fieldName]: finalDiffableRule[fieldName] }, + defaultValue: { + [fieldName]: finalDiffableRule[fieldName], + }, serializer: (value) => value, onSubmit: async (formData) => { setRuleFieldResolvedValue({ 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/final_edit.tsx index ea55f8dc254eb..d6c176c9c7f99 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/final_edit.tsx @@ -6,33 +6,23 @@ */ import React, { useMemo } from 'react'; -import type { SetRuleFieldResolvedValueFn } from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; import { DiffableCommonFields } from '../../../../../../../common/api/detection_engine'; -import type { - DiffableRule, - DiffableRuleTypes, -} from '../../../../../../../common/api/detection_engine'; +import type { DiffableRuleTypes } from '../../../../../../../common/api/detection_engine'; import { FinalEditContextProvider } from './final_edit_context'; import { CommonRuleFieldEdit } from './common_rule_field_edit'; import { assertUnreachable } from '../../../../../../../common/utility_types'; +import { useDiffableRuleContext } from '../diffable_rule_context'; interface FinalEditProps { fieldName: string; - finalDiffableRule: DiffableRule; setReadOnlyMode: () => void; - setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } -export function FinalEdit({ - fieldName, - finalDiffableRule, - setReadOnlyMode, - setRuleFieldResolvedValue, -}: FinalEditProps) { +export function FinalEdit({ fieldName, setReadOnlyMode }: FinalEditProps) { + const { finalDiffableRule } = useDiffableRuleContext(); + return ( - + ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx index a03c51b023f83..b6ba7868a99b6 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx @@ -6,15 +6,11 @@ */ import React, { createContext, useContext } from 'react'; -import type { DiffableRule } from '../../../../../../../common/api/detection_engine'; -import type { SetRuleFieldResolvedValueFn } from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; import { invariant } from '../../../../../../../common/utils/invariant'; interface FinalEditContextType { fieldName: string; - finalDiffableRule: DiffableRule; setReadOnlyMode: () => void; - setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } const FinalEditContext = createContext(null); 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 index d8d31e343278b..ecaec5af0f54a 100644 --- 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 @@ -8,7 +8,6 @@ import React, { useMemo } from 'react'; import { DiffableCommonFields } from '../../../../../../../common/api/detection_engine'; import type { - DiffableRule, DiffableCustomQueryFields, DiffableSavedQueryFields, DiffableEqlFields, @@ -28,13 +27,15 @@ 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; - finalDiffableRule: DiffableRule; } -export function FieldReadOnly({ fieldName, finalDiffableRule }: FieldReadOnlyProps) { +export function FieldReadOnly({ fieldName }: FieldReadOnlyProps) { + const { finalDiffableRule } = useDiffableRuleContext(); + const { data: commonField } = useMemo( () => DiffableCommonFields.keyof().safeParse(fieldName), [fieldName] 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/final_readonly.tsx index 9dc2d01118e6c..d083d8991c8a5 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/final_readonly.tsx @@ -7,22 +7,20 @@ import { EuiButtonEmpty } from '@elastic/eui'; import React from 'react'; -import type { DiffableRule } from '../../../../../../../common/api/detection_engine'; import { FieldReadOnly } from './field_readonly'; interface FinalReadOnlyProps { fieldName: string; - finalDiffableRule: DiffableRule; setEditMode: () => void; } -export function FinalReadOnly({ fieldName, finalDiffableRule, setEditMode }: FinalReadOnlyProps) { +export function FinalReadOnly({ fieldName, setEditMode }: FinalReadOnlyProps) { return ( <> {'Edit'} - + ); } 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/final_side/final_side.tsx index c8df3e90d7a76..983ec8e638fe8 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/final_side/final_side.tsx @@ -7,25 +7,17 @@ import React, { useCallback } from 'react'; import { EuiTitle } from '@elastic/eui'; -import type { DiffableRule } from '../../../../../../../common/api/detection_engine'; 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 type { SetRuleFieldResolvedValueFn } from '../../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; import { FinalEdit } from '../final_edit/final_edit'; interface FinalSideProps { fieldName: string; - finalDiffableRule: DiffableRule; - setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } -export function FinalSide({ - fieldName, - finalDiffableRule, - setRuleFieldResolvedValue, -}: FinalSideProps): JSX.Element { +export function FinalSide({ fieldName }: FinalSideProps): JSX.Element { const [mode, setMode] = React.useState<'readonly' | 'edit'>('readonly'); // This is temporary, will be replaced with state from the context const setReadOnlyMode = useCallback(() => setMode('readonly'), []); const setEditMode = useCallback(() => setMode('edit'), []); @@ -41,18 +33,9 @@ export function FinalSide({ {mode === 'edit' ? ( - + ) : ( - + )} ); 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 index b32835e0fac5d..62a4f0dd437ec 100644 --- 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 @@ -13,31 +13,26 @@ import type { } from '../../../../rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_prebuilt_rules_upgrade_state'; import { RuleUpgradeInfoBar } from './components/rule_upgrade_info_bar'; import { RuleUpgradeConflictsResolver } from './components/rule_upgrade_conflicts_resolver'; -import type { RuleSignatureId } from '../../../../../../common/api/detection_engine'; +import { DiffableRuleContextProvider } from './diffable_rule_context'; interface RuleUpgradeConflictsResolverTabProps { - ruleId: RuleSignatureId; ruleUpgradeState: RuleUpgradeState; - setRuleFieldResolvedValue: (ruleId: RuleSignatureId) => SetRuleFieldResolvedValueFn; + setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } export function RuleUpgradeConflictsResolverTab({ - ruleId, ruleUpgradeState, setRuleFieldResolvedValue, }: RuleUpgradeConflictsResolverTabProps): JSX.Element { - // TODO: Find a better name for this function to avoid confusion with the one that is not ruleId-specific - const setFieldResolvedValueForRule = setRuleFieldResolvedValue(ruleId); - 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 695fc2dcb9b90..997f85d3ddce0 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 @@ -254,7 +254,6 @@ export const UpgradePrebuiltRulesTableContextProvider = ({ content: ( 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 308248ea8fb97..d8d8f74e897e8 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 @@ -29,14 +29,18 @@ export interface RuleUpgradeState extends RuleUpgradeInfoForReview { export type RulesUpgradeState = Record; export type SetRuleFieldResolvedValueFn< FieldName extends keyof DiffableAllFields = keyof DiffableAllFields -> = (params: { fieldName: FieldName; resolvedValue: DiffableAllFields[FieldName] }) => void; +> = (params: { + ruleId: RuleSignatureId; + fieldName: FieldName; + resolvedValue: DiffableAllFields[FieldName]; +}) => void; type RuleResolvedConflicts = Partial; type RulesResolvedConflicts = Record; interface UseRulesUpgradeStateResult { rulesUpgradeState: RulesUpgradeState; - setRuleFieldResolvedValue: (ruleId: RuleSignatureId) => SetRuleFieldResolvedValueFn; + setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } export function usePrebuiltRulesUpgradeState( @@ -45,16 +49,15 @@ export function usePrebuiltRulesUpgradeState( const [rulesResolvedConflicts, setRulesResolvedConflicts] = useState({}); const setRuleFieldResolvedValue = useCallback( - (ruleId: RuleSignatureId) => - (...[params]: Parameters) => { - setRulesResolvedConflicts((prevRulesResolvedConflicts) => ({ - ...prevRulesResolvedConflicts, - [ruleId]: { - ...(prevRulesResolvedConflicts[ruleId] ?? {}), - [params.fieldName]: params.resolvedValue, - }, - })); - }, + (...[params]: Parameters) => { + setRulesResolvedConflicts((prevRulesResolvedConflicts) => ({ + ...prevRulesResolvedConflicts, + [params.ruleId]: { + ...(prevRulesResolvedConflicts[params.ruleId] ?? {}), + [params.fieldName]: params.resolvedValue, + }, + })); + }, [] ); From 0407cbebd8511c2d2a539bf57f1ae9987d13d4b8 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Fri, 4 Oct 2024 17:14:46 +0200 Subject: [PATCH 15/40] Make `kql_query` work --- .../rule_upgrade_conflicts_resolver.tsx | 19 +- .../final_edit/common_rule_field_edit.tsx | 5 +- .../custom_query_rule_field_edit.tsx | 36 +++ .../final_edit/field_form_wrapper.tsx | 78 ++++-- .../final_edit/fields/kql_query.tsx | 227 ++++++++++++++++++ .../three_way_diff/final_edit/final_edit.tsx | 25 +- .../final_edit/new_terms_rule_field_edit.tsx | 36 +++ .../saved_query_rule_field_edit.tsx | 36 +++ .../threat_match_rule_field_edit.tsx | 36 +++ .../final_edit/threshold_rule_field_edit.tsx | 36 +++ .../fields/kql_query/saved_kql_query.tsx | 8 +- 11 files changed, 508 insertions(+), 34 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/custom_query_rule_field_edit.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/new_terms_rule_field_edit.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/saved_query_rule_field_edit.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threat_match_rule_field_edit.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threshold_rule_field_edit.tsx 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/components/rule_upgrade_conflicts_resolver.tsx index b13366d32fca6..754d6dbff2069 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/components/rule_upgrade_conflicts_resolver.tsx @@ -22,13 +22,18 @@ export function RuleUpgradeConflictsResolver({ Required[keyof typeof ruleUpgradeState.diff.fields] ] >; - const fields = fieldDiffEntries.map(([fieldName, fieldDiff]) => ( - - )); + const fields = fieldDiffEntries + .filter(([fieldName]) => { + /* Do not show "version" field among changes */ + return fieldName !== 'version'; + }) + .map(([fieldName, fieldDiff]) => ( + + )); return <>{fields}; } 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 b0f163801c0b7..6fa20d865b81f 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 @@ -7,8 +7,8 @@ import React from 'react'; import type { DiffableCommonFields } from '../../../../../../../common/api/detection_engine'; -import { NameEdit, nameSchema } from './fields/name'; import { FieldFormWrapper } from './field_form_wrapper'; +import { NameEdit, nameSchema } from './fields/name'; interface CommonRuleFieldEditProps { fieldName: keyof DiffableCommonFields; @@ -18,6 +18,9 @@ export function CommonRuleFieldEdit({ fieldName }: CommonRuleFieldEditProps) { switch (fieldName) { case 'name': return ; + case 'version': + /* "version" is not editable */ + return null; default: return null; // Will be replaced with `assertUnreachable(fieldName)` once all fields are implemented } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/custom_query_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/custom_query_rule_field_edit.tsx new file mode 100644 index 0000000000000..9fcf41a62e35d --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/custom_query_rule_field_edit.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 type { DiffableCustomQueryFields } from '../../../../../../../common/api/detection_engine'; +import { FieldFormWrapper } from './field_form_wrapper'; +import { + KqlQueryEdit, + kqlQuerySchema, + kqlQuerySerializer, + kqlQueryDeserializer, +} from './fields/kql_query'; + +interface CustomQueryRuleFieldEditProps { + fieldName: keyof DiffableCustomQueryFields; +} + +export function CustomQueryRuleFieldEdit({ fieldName }: CustomQueryRuleFieldEditProps) { + switch (fieldName) { + case 'kql_query': + return ( + + ); + default: + return null; // Will be replaced with `assertUnreachable(fieldName)` once all fields are implemented + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx index b2abd8fcf14d5..8513e99fe452a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx @@ -5,54 +5,100 @@ * 2.0. */ -import React from 'react'; +import React, { useState } from 'react'; import { EuiButtonEmpty, EuiFlexGroup } from '@elastic/eui'; -import { useForm, type FormSchema, Form } from '../../../../../../shared_imports'; -import type { DiffableAllFields } from '../../../../../../../common/api/detection_engine'; +import { useForm, Form } from '../../../../../../shared_imports'; +import type { FormSchema, FormData } from '../../../../../../shared_imports'; +import type { + DiffableAllFields, + DiffableRule, +} from '../../../../../../../common/api/detection_engine'; import { useFinalEditContext } from './final_edit_context'; import { useDiffableRuleContext } from '../diffable_rule_context'; interface FieldFormWrapperProps { - component: React.ComponentType; + component: React.ComponentType<{ + finalDiffableRule: DiffableRule; + setValidity: (isValid: boolean) => void; + setFieldValue: (fieldName: string, fieldValue: unknown) => void; + }>; fieldFormSchema: FormSchema; + deserializer: (fieldValue: FormData, finalDiffableRule: DiffableRule) => FormData; + serializer: (formData: FormData) => FormData; } +/** + * FieldFormWrapper component manages form state and renders "Save" and "Cancel" buttons. + * + * @param {Object} props - Component props. + * @param {React.ComponentType} props.component - Field component to be wrapped. + * @param {FormSchema} props.fieldFormSchema - Configuration schema for the field. + * @param {Function} props.deserializer - Deserializer prepares initial form data. It converts field value from a DiffableRule format to a format used by the form. + * @param {Function} props.serializer - Serializer prepares form data for submission. It converts form data back to a DiffableRule format. + */ export function FieldFormWrapper({ component: FieldComponent, fieldFormSchema, + deserializer, + serializer, }: FieldFormWrapperProps) { const { fieldName, setReadOnlyMode } = useFinalEditContext(); const { finalDiffableRule, setRuleFieldResolvedValue } = useDiffableRuleContext(); + const deserialize = (defaultValue: FormData): FormData => { + if (deserializer) { + const rule = finalDiffableRule as Record; + const fieldValue = rule[fieldName] as FormData; + return deserializer(fieldValue, finalDiffableRule); + } + + return defaultValue; + }; + const { form } = useForm({ schema: fieldFormSchema, - defaultValue: { - [fieldName]: finalDiffableRule[fieldName], - }, - serializer: (value) => value, - onSubmit: async (formData) => { - setRuleFieldResolvedValue({ - fieldName: fieldName as keyof DiffableAllFields, // TODO: This is temporary until we decide which type to use - resolvedValue: formData[fieldName], - }); - setReadOnlyMode(); + defaultValue: getDefaultValue(fieldName, finalDiffableRule), + deserializer: deserialize, + serializer, + onSubmit: async (formData, isValid) => { + if (isValid) { + setRuleFieldResolvedValue({ + fieldName: fieldName as keyof DiffableAllFields, + resolvedValue: formData[fieldName], + }); + setReadOnlyMode(); + } }, }); + const [validity, setValidity] = useState(undefined); + + const isValid = validity === undefined ? form.isValid : validity; + return ( <> {'Cancel'} - + {'Save'}
- + ); } + +function getDefaultValue(fieldName: string, finalDiffableRule: DiffableRule): FormData { + const rule = finalDiffableRule as Record; + + return { [fieldName]: rule[fieldName] }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx new file mode 100644 index 0000000000000..dd7e1b790d9aa --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx @@ -0,0 +1,227 @@ +/* + * 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, { useState, useCallback } from 'react'; +import { css } from '@emotion/css'; +import { EuiButtonEmpty } from '@elastic/eui'; +import type { Type } from '@kbn/securitysolution-io-ts-alerting-types'; +import type { FormSchema, FormData } from '../../../../../../../shared_imports'; +import { HiddenField, UseField } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_define_rule/schema'; +import { QueryBarDefineRule } from '../../../../../../rule_creation_ui/components/query_bar'; +import type { FieldValueQueryBar } from '../../../../../../rule_creation_ui/components/query_bar'; +import * as stepDefineRuleI18n from '../../../../../../rule_creation_ui/components/step_define_rule/translations'; +import { useRuleIndexPattern } from '../../../../../../rule_creation_ui/pages/form'; +import { + DataSourceType as DataSourceTypeSnakeCase, + KqlQueryLanguage, + KqlQueryType, + RuleQuery, + SavedQueryId, + RuleKqlQuery, +} from '../../../../../../../../common/api/detection_engine'; +import type { + DiffableRule, + DiffableRuleTypes, + InlineKqlQuery, + SavedKqlQuery, +} from '../../../../../../../../common/api/detection_engine'; +import { useDefaultIndexPattern } from '../../../use_default_index_pattern'; +import { DataSourceType } from '../../../../../../../detections/pages/detection_engine/rules/types'; +import { isFilters } from '../../../helpers'; +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'; + +export const kqlQuerySchema = { + ruleType: schema.ruleType, + queryBar: schema.queryBar, +} as FormSchema<{ + ruleType: DiffableRuleTypes; + queryBar: FieldValueQueryBar; +}>; + +interface KqlQueryEditProps { + finalDiffableRule: DiffableRule; + setValidity: (isValid: boolean) => void; + setFieldValue: (fieldName: string, fieldValue: unknown) => void; +} + +export function KqlQueryEdit({ finalDiffableRule, setValidity, setFieldValue }: KqlQueryEditProps) { + const defaultIndexPattern = useDefaultIndexPattern(); + + let indexPatternParams: Parameters[0] = { + dataSourceType: DataSourceType.IndexPatterns, + index: defaultIndexPattern, + dataViewId: undefined, + }; + + if ('data_source' in finalDiffableRule && finalDiffableRule.data_source) { + if (finalDiffableRule.data_source.type === DataSourceTypeSnakeCase.data_view) { + indexPatternParams = { + dataSourceType: DataSourceType.DataView, + index: [], + dataViewId: finalDiffableRule.data_source.data_view_id, + }; + } else { + indexPatternParams = { + dataSourceType: DataSourceType.IndexPatterns, + index: finalDiffableRule.data_source.index_patterns, + dataViewId: undefined, + }; + } + } + + const isSavedQueryRule = finalDiffableRule.type === 'saved_query'; + + const { indexPattern, isIndexPatternLoading } = useRuleIndexPattern(indexPatternParams); + + const [isTimelineSearchOpen, setIsTimelineSearchOpen] = useState(false); + + const handleOpenTimelineSearch = useCallback(() => { + setIsTimelineSearchOpen(true); + }, []); + + const handleCloseTimelineSearch = useCallback(() => { + setIsTimelineSearchOpen(false); + }, []); + + const handleSetRuleFromTimeline = useCallback( + ({ queryBar: timelineQueryBar }) => { + setFieldValue('queryBar', timelineQueryBar); + }, + [setFieldValue] + ); + + const { onOpenTimeline } = useRuleFromTimeline(handleSetRuleFromTimeline); + + const savedQueryId = + isSavedQueryRule && 'saved_query_id' in finalDiffableRule.kql_query + ? finalDiffableRule.kql_query.saved_query_id + : undefined; + + const { savedQuery } = useGetSavedQuery({ + savedQueryId, + ruleType: finalDiffableRule.type, + }); + + return ( + <> + + + ), + }} + component={QueryBarDefineRule} + componentProps={{ + indexPattern, + isLoading: isIndexPatternLoading, + openTimelineSearch: isTimelineSearchOpen, + onCloseTimelineSearch: handleCloseTimelineSearch, + onValidityChange: setValidity, + onOpenTimeline, + isDisabled: isSavedQueryRule, + defaultSavedQuery: savedQuery, + resetToSavedQuery: isSavedQueryRule, + }} + /> + + ); +} + +const timelineButtonClassName = css` + height: 18px; + font-size: 12px; +`; + +function ImportTimelineQueryButton({ + handleOpenTimelineSearch, +}: { + handleOpenTimelineSearch: () => void; +}) { + return ( + + {stepDefineRuleI18n.IMPORT_TIMELINE_QUERY} + + ); +} + +export function kqlQuerySerializer(formData: FormData): { + kql_query: RuleKqlQuery; +} { + const formValue = formData as { ruleType: Type; queryBar: FieldValueQueryBar }; + + if (formValue.ruleType === 'saved_query') { + const savedQueryId = SavedQueryId.parse(formValue.queryBar.saved_id); + + const savedKqlQuery: SavedKqlQuery = { + type: KqlQueryType.saved_query, + saved_query_id: savedQueryId, + }; + + return { + kql_query: savedKqlQuery, + }; + } + + const query = RuleQuery.parse(formValue.queryBar.query.query); + const language = KqlQueryLanguage.parse(formValue.queryBar.query.language); + + const inlineKqlQuery: InlineKqlQuery = { + type: KqlQueryType.inline_query, + query, + language, + filters: formValue.queryBar.filters, + }; + + return { kql_query: inlineKqlQuery }; +} + +export function kqlQueryDeserializer( + fieldValue: FormData, + finalDiffableRule: DiffableRule +): { + ruleType: Type; + queryBar: FieldValueQueryBar; +} { + const parsedFieldValue = RuleKqlQuery.parse(fieldValue); + + if (parsedFieldValue.type === KqlQueryType.inline_query) { + const returnValue = { + ruleType: finalDiffableRule.type, + queryBar: { + query: { + query: parsedFieldValue.query, + language: parsedFieldValue.language, + }, + filters: isFilters(parsedFieldValue.filters) ? parsedFieldValue.filters : [], + saved_id: null, + }, + }; + + return returnValue; + } + + const returnValue = { + ruleType: finalDiffableRule.type, + queryBar: { + query: { + query: '', + language: '', + }, + filters: [], + saved_id: parsedFieldValue.saved_query_id, + }, + }; + + return returnValue; +} 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/final_edit.tsx index d6c176c9c7f99..4f7f3f0ad8461 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/final_edit.tsx @@ -7,11 +7,22 @@ import React, { useMemo } from 'react'; import { DiffableCommonFields } from '../../../../../../../common/api/detection_engine'; -import type { DiffableRuleTypes } from '../../../../../../../common/api/detection_engine'; +import type { + DiffableThreatMatchFields, + DiffableCustomQueryFields, + DiffableRuleTypes, + DiffableThresholdFields, + DiffableNewTermsFields, +} from '../../../../../../../common/api/detection_engine'; import { FinalEditContextProvider } from './final_edit_context'; -import { CommonRuleFieldEdit } from './common_rule_field_edit'; 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'; interface FinalEditProps { fieldName: string; @@ -45,21 +56,21 @@ function FieldEdit({ fieldName, ruleType }: FinalEditFieldProps) { switch (ruleType) { case 'query': - return {'Rule type not yet implemented'}; + return ; case 'saved_query': - return {'Rule type not yet implemented'}; + return ; case 'eql': return {'Rule type not yet implemented'}; case 'esql': return {'Rule type not yet implemented'}; case 'threat_match': - return {'Rule type not yet implemented'}; + return ; case 'threshold': - return {'Rule type not yet implemented'}; + return ; case 'machine_learning': return {'Rule type not yet implemented'}; case 'new_terms': - return {'Rule type not yet implemented'}; + return ; default: return assertUnreachable(ruleType); } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/new_terms_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/new_terms_rule_field_edit.tsx new file mode 100644 index 0000000000000..4f0e8da4909bb --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/new_terms_rule_field_edit.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 type { DiffableNewTermsFields } from '../../../../../../../common/api/detection_engine'; +import { FieldFormWrapper } from './field_form_wrapper'; +import { + KqlQueryEdit, + kqlQuerySchema, + kqlQuerySerializer, + kqlQueryDeserializer, +} from './fields/kql_query'; + +interface NewTermsRuleFieldEditProps { + fieldName: keyof DiffableNewTermsFields; +} + +export function NewTermsRuleFieldEdit({ fieldName }: NewTermsRuleFieldEditProps) { + switch (fieldName) { + case 'kql_query': + return ( + + ); + default: + return null; // Will be replaced with `assertUnreachable(fieldName)` once all fields are implemented + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/saved_query_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/saved_query_rule_field_edit.tsx new file mode 100644 index 0000000000000..61a97e691f0c5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/saved_query_rule_field_edit.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 type { DiffableSavedQueryFields } from '../../../../../../../common/api/detection_engine'; +import { FieldFormWrapper } from './field_form_wrapper'; +import { + KqlQueryEdit, + kqlQuerySchema, + kqlQuerySerializer, + kqlQueryDeserializer, +} from './fields/kql_query'; + +interface SavedQueryRuleFieldEditProps { + fieldName: keyof DiffableSavedQueryFields; +} + +export function SavedQueryRuleFieldEdit({ fieldName }: SavedQueryRuleFieldEditProps) { + switch (fieldName) { + case 'kql_query': + return ( + + ); + default: + return null; // Will be replaced with `assertUnreachable(fieldName)` once all fields are implemented + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threat_match_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threat_match_rule_field_edit.tsx new file mode 100644 index 0000000000000..c98b44ae74ccd --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threat_match_rule_field_edit.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 type { DiffableThreatMatchFields } from '../../../../../../../common/api/detection_engine'; +import { FieldFormWrapper } from './field_form_wrapper'; +import { + KqlQueryEdit, + kqlQuerySchema, + kqlQuerySerializer, + kqlQueryDeserializer, +} from './fields/kql_query'; + +interface ThreatMatchRuleFieldEditProps { + fieldName: keyof DiffableThreatMatchFields; +} + +export function ThreatMatchRuleFieldEdit({ fieldName }: ThreatMatchRuleFieldEditProps) { + switch (fieldName) { + case 'kql_query': + return ( + + ); + default: + return null; // Will be replaced with `assertUnreachable(fieldName)` once all fields are implemented + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threshold_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threshold_rule_field_edit.tsx new file mode 100644 index 0000000000000..870164d730dc8 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threshold_rule_field_edit.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 type { DiffableThresholdFields } from '../../../../../../../common/api/detection_engine'; +import { FieldFormWrapper } from './field_form_wrapper'; +import { + KqlQueryEdit, + kqlQuerySchema, + kqlQuerySerializer, + kqlQueryDeserializer, +} from './fields/kql_query'; + +interface ThresholdRuleFieldEditProps { + fieldName: keyof DiffableThresholdFields; +} + +export function ThresholdRuleFieldEdit({ fieldName }: ThresholdRuleFieldEditProps) { + switch (fieldName) { + case 'kql_query': + return ( + + ); + default: + return null; // Will be replaced with `assertUnreachable(fieldName)` once all fields are implemented + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/saved_kql_query.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/saved_kql_query.tsx index 5f50a9c1b9eae..6db78a20082d9 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/saved_kql_query.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/saved_kql_query.tsx @@ -17,7 +17,7 @@ import { Query, SavedQueryName, Filters } from '../../../../rule_definition_sect import * as ruleDetailsI18n from '../../../../translations'; import * as descriptionStepI18n from '../../../../../../../rule_creation_ui/components/description_step/translations'; import { useGetSavedQuery } from '../../../../../../../../detections/pages/detection_engine/rules/use_get_saved_query'; -import { getDataSourceProps, getQueryLanguageLabel } from '../../../../helpers'; +import { getDataSourceProps, getQueryLanguageLabel, isFilters } from '../../../../helpers'; interface SavedQueryProps { kqlQuery: SavedKqlQuery; @@ -53,12 +53,14 @@ export function SavedKqlQueryReadOnly({ kqlQuery, dataSource, ruleType }: SavedQ }); } - if (savedQuery.attributes.filters) { + const filters = savedQuery.attributes.filters ?? []; + + if (isFilters(filters) && filters.length > 0) { const dataSourceProps = getDataSourceProps(dataSource); listItems.push({ title: descriptionStepI18n.SAVED_QUERY_FILTERS_LABEL, - description: , + description: , }); } From 95094110d18b3a8b12d0ca4f9b67000874804806 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Thu, 10 Oct 2024 15:11:48 +0200 Subject: [PATCH 16/40] Add a spacer to the callout and add plurals to callout copy --- .../components/rule_upgrade_callout/translations.tsx | 4 ++-- .../three_way_diff/rule_upgrade_conflicts_resolver_tab.tsx | 1 + 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/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 be9ee761388d0..319884746dbc2 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 @@ -13,7 +13,7 @@ export const RULE_HAS_NON_SOLVABLE_CONFLICTS = (count: number) => { values: { count }, defaultMessage: - '{count} of the fields has a unsolved conflict. Please review and modify accordingly.', + '{count} of the fields {count, plural, one {has} other {have}} an unsolved conflict. Please review and modify accordingly.', } ); @@ -31,7 +31,7 @@ export const RULE_HAS_SOLVABLE_CONFLICTS = (count: number) => { values: { count }, defaultMessage: - '{count} of the fields has an update conflict, please review the suggested update being updating.', + '{count} of the fields {count, plural, one {has} other {have}} an update conflict, please review the suggested update being updating.', } ); 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 index ef69f5d019d19..95fa407fb7ca2 100644 --- 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 @@ -32,6 +32,7 @@ export function RuleUpgradeConflictsResolverTab({ > + From 51637f47a4ca51e6e5580f1d3fd705ec156bba67 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Thu, 10 Oct 2024 15:12:24 +0200 Subject: [PATCH 17/40] Extract hidden fields into a separate variable --- .../three_way_diff/components/constants.ts | 19 +++++++++++++++++++ .../rule_upgrade_callout.tsx | 7 ++++++- .../rule_upgrade_conflicts_resolver.tsx | 6 ++++-- 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/constants.ts diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/constants.ts new file mode 100644 index 0000000000000..ad348c85148b2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/constants.ts @@ -0,0 +1,19 @@ +/* + * 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 { DiffableAllFields } from '../../../../../../../common/api/detection_engine'; + +type NonEditableFields = Readonly>; + +/* These fields are not visible in the comparison UI and are not editable */ +export const HIDDEN_FIELDS: NonEditableFields = new Set([ + 'alert_suppression', + 'author', + 'rule_id', + 'license', + 'version', +]); 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 852ab0c91c58e..8ab2674524952 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 @@ -64,7 +64,12 @@ export function RuleUpgradeCallout({ ruleUpgradeState }: RuleUpgradeCalloutProps } return ( - +

{i18n.RULE_IS_READY_FOR_UPGRADE_DESCRIPTION}

); 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/components/rule_upgrade_conflicts_resolver.tsx index b92e2f554193c..1ab8500d967d0 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/components/rule_upgrade_conflicts_resolver.tsx @@ -8,6 +8,7 @@ import React from 'react'; import type { RuleUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { FieldUpgradeConflictsResolver } from './field_upgrade_conflicts_resolver'; +import { HIDDEN_FIELDS } from './constants'; interface RuleUpgradeConflictsResolverProps { ruleUpgradeState: RuleUpgradeState; @@ -22,10 +23,11 @@ export function RuleUpgradeConflictsResolver({ Required[keyof typeof ruleUpgradeState.diff.fields] ] >; + const fields = fieldDiffEntries .filter(([fieldName]) => { - /* Do not show "version" field among changes */ - return fieldName !== 'version'; + /* Remove fields that aren't supposed to be displayed */ + return HIDDEN_FIELDS.has(fieldName) === false; }) .map(([fieldName, fieldDiff]) => ( Date: Thu, 10 Oct 2024 15:39:30 +0200 Subject: [PATCH 18/40] Simplify setting resolved value --- .../three_way_diff/diffable_rule_context.tsx | 13 ++----------- .../final_edit/field_form_wrapper.tsx | 5 +++-- 2 files changed, 5 insertions(+), 13 deletions(-) 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/diffable_rule_context.tsx index 7afc71494c15d..4210b394c7618 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/diffable_rule_context.tsx @@ -10,11 +10,9 @@ 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'; -type ParamsWithoutRuleId = Omit[0], 'ruleId'>; - interface DiffableRuleContextType { finalDiffableRule: DiffableRule; - setRuleFieldResolvedValue: (paramsWithoutRuleId: ParamsWithoutRuleId) => void; + setRuleFieldResolvedValue: SetRuleFieldResolvedValueFn; } const DiffableRuleContext = createContext(null); @@ -30,16 +28,9 @@ export function DiffableRuleContextProvider({ setRuleFieldResolvedValue, children, }: DiffableRuleContextProviderProps) { - const setRuleFieldResolvedValueWithRuleId = ({ - fieldName, - resolvedValue, - }: ParamsWithoutRuleId) => { - setRuleFieldResolvedValue({ ruleId: finalDiffableRule.rule_id, fieldName, resolvedValue }); - }; - const contextValue = { finalDiffableRule, - setRuleFieldResolvedValue: setRuleFieldResolvedValueWithRuleId, + setRuleFieldResolvedValue, }; return ( diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx index 8513e99fe452a..2064afa9db73a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx @@ -23,8 +23,8 @@ interface FieldFormWrapperProps { setFieldValue: (fieldName: string, fieldValue: unknown) => void; }>; fieldFormSchema: FormSchema; - deserializer: (fieldValue: FormData, finalDiffableRule: DiffableRule) => FormData; - serializer: (formData: FormData) => FormData; + deserializer?: (fieldValue: FormData, finalDiffableRule: DiffableRule) => FormData; + serializer?: (formData: FormData) => FormData; } /** @@ -64,6 +64,7 @@ export function FieldFormWrapper({ onSubmit: async (formData, isValid) => { if (isValid) { setRuleFieldResolvedValue({ + ruleId: finalDiffableRule.rule_id, fieldName: fieldName as keyof DiffableAllFields, resolvedValue: formData[fieldName], }); From e45796eb8945c4a3ea74c57274dc7fd970830715 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Thu, 10 Oct 2024 16:22:58 +0200 Subject: [PATCH 19/40] Refactor deserializtion code --- .../three_way_diff/final_edit/field_form_wrapper.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx index 2064afa9db73a..6e09cd48234ee 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx @@ -47,13 +47,13 @@ export function FieldFormWrapper({ const { finalDiffableRule, setRuleFieldResolvedValue } = useDiffableRuleContext(); const deserialize = (defaultValue: FormData): FormData => { - if (deserializer) { - const rule = finalDiffableRule as Record; - const fieldValue = rule[fieldName] as FormData; - return deserializer(fieldValue, finalDiffableRule); + if (!deserializer) { + return defaultValue; } - return defaultValue; + const rule = finalDiffableRule as Record; + const fieldValue = rule[fieldName] as FormData; + return deserializer(fieldValue, finalDiffableRule); }; const { form } = useForm({ From 022ef9871f4591cad0289d96314bed619e65a922 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Thu, 10 Oct 2024 16:24:39 +0200 Subject: [PATCH 20/40] Refactor `onSubmit` validation handling --- .../final_edit/field_form_wrapper.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx index 6e09cd48234ee..c19e53b7558a4 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx @@ -62,14 +62,16 @@ export function FieldFormWrapper({ deserializer: deserialize, serializer, onSubmit: async (formData, isValid) => { - if (isValid) { - setRuleFieldResolvedValue({ - ruleId: finalDiffableRule.rule_id, - fieldName: fieldName as keyof DiffableAllFields, - resolvedValue: formData[fieldName], - }); - setReadOnlyMode(); + if (!isValid) { + return; } + + setRuleFieldResolvedValue({ + ruleId: finalDiffableRule.rule_id, + fieldName: fieldName as keyof DiffableAllFields, + resolvedValue: formData[fieldName], + }); + setReadOnlyMode(); }, }); From f92d27328fe86f0409a2072debaa931469dddc8c Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Thu, 10 Oct 2024 16:26:31 +0200 Subject: [PATCH 21/40] Refactor `getDefaultValue` --- .../three_way_diff/final_edit/field_form_wrapper.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx index c19e53b7558a4..f6327c2f33f63 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx @@ -100,8 +100,6 @@ export function FieldFormWrapper({ ); } -function getDefaultValue(fieldName: string, finalDiffableRule: DiffableRule): FormData { - const rule = finalDiffableRule as Record; - - return { [fieldName]: rule[fieldName] }; +function getDefaultValue(fieldName: string, finalDiffableRule: Record): FormData { + return { [fieldName]: finalDiffableRule[fieldName] }; } From caa30644709304c5efa3ade20aff9737a4041350 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Thu, 10 Oct 2024 16:41:37 +0200 Subject: [PATCH 22/40] Use `i18n` for button labels --- .../final_edit/field_form_wrapper.tsx | 5 ++-- .../final_readonly/final_readonly.tsx | 3 +- .../three_way_diff/translations.ts | 29 +++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) create 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/final_edit/field_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx index f6327c2f33f63..d2fa6a4779b21 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx @@ -15,6 +15,7 @@ import type { } from '../../../../../../../common/api/detection_engine'; import { useFinalEditContext } from './final_edit_context'; import { useDiffableRuleContext } from '../diffable_rule_context'; +import * as i18n from '../translations'; interface FieldFormWrapperProps { component: React.ComponentType<{ @@ -83,10 +84,10 @@ export function FieldFormWrapper({ <> - {'Cancel'} + {i18n.CANCEL_BUTTON_LABEL} - {'Save'} + {i18n.SAVE_BUTTON_LABEL}
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/final_readonly.tsx index d083d8991c8a5..909663b4e8390 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/final_readonly.tsx @@ -8,6 +8,7 @@ import { EuiButtonEmpty } from '@elastic/eui'; import React from 'react'; import { FieldReadOnly } from './field_readonly'; +import * as i18n from '../translations'; interface FinalReadOnlyProps { fieldName: string; @@ -18,7 +19,7 @@ export function FinalReadOnly({ fieldName, setEditMode }: FinalReadOnlyProps) { return ( <> - {'Edit'} + {i18n.EDIT_BUTTON_LABEL} 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 new file mode 100644 index 0000000000000..ced733d87ff6e --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/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 CANCEL_BUTTON_LABEL = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.upgradeRules.cancelButtonLabel', + { + defaultMessage: 'Cancel', + } +); + +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', + { + defaultMessage: 'Edit', + } +); From e491ad781a03fc256c63c2b8687c7269c704fa80 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Thu, 10 Oct 2024 16:51:09 +0200 Subject: [PATCH 23/40] Wrap form handlers in `useCallback` --- .../final_edit/field_form_wrapper.tsx | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx index d2fa6a4779b21..51c9c5397dd38 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useState } from 'react'; +import React, { useCallback, useState } from 'react'; import { EuiButtonEmpty, EuiFlexGroup } from '@elastic/eui'; import { useForm, Form } from '../../../../../../shared_imports'; import type { FormSchema, FormData } from '../../../../../../shared_imports'; @@ -47,22 +47,21 @@ export function FieldFormWrapper({ const { finalDiffableRule, setRuleFieldResolvedValue } = useDiffableRuleContext(); - const deserialize = (defaultValue: FormData): FormData => { - if (!deserializer) { - return defaultValue; - } + const deserialize = useCallback( + (defaultValue: FormData): FormData => { + if (!deserializer) { + return defaultValue; + } - const rule = finalDiffableRule as Record; - const fieldValue = rule[fieldName] as FormData; - return deserializer(fieldValue, finalDiffableRule); - }; + const rule = finalDiffableRule as Record; + const fieldValue = rule[fieldName] as FormData; + return deserializer(fieldValue, finalDiffableRule); + }, + [deserializer, fieldName, finalDiffableRule] + ); - const { form } = useForm({ - schema: fieldFormSchema, - defaultValue: getDefaultValue(fieldName, finalDiffableRule), - deserializer: deserialize, - serializer, - onSubmit: async (formData, isValid) => { + const handleSubmit = useCallback( + async (formData: FormData, isValid: boolean) => { if (!isValid) { return; } @@ -74,6 +73,15 @@ export function FieldFormWrapper({ }); setReadOnlyMode(); }, + [fieldName, finalDiffableRule.rule_id, setReadOnlyMode, setRuleFieldResolvedValue] + ); + + const { form } = useForm({ + schema: fieldFormSchema, + defaultValue: getDefaultValue(fieldName, finalDiffableRule), + deserializer: deserialize, + serializer, + onSubmit: handleSubmit, }); const [validity, setValidity] = useState(undefined); From bdd493726dbfa47b7aa2b5fb18076ee55015ff2f Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Thu, 10 Oct 2024 16:59:03 +0200 Subject: [PATCH 24/40] Move calculation of `useRuleIndexPattern` parameters into a separate function --- .../final_edit/fields/kql_query.tsx | 62 ++++++++++++------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx index dd7e1b790d9aa..c8f381bbd8648 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx @@ -54,31 +54,14 @@ interface KqlQueryEditProps { export function KqlQueryEdit({ finalDiffableRule, setValidity, setFieldValue }: KqlQueryEditProps) { const defaultIndexPattern = useDefaultIndexPattern(); - let indexPatternParams: Parameters[0] = { - dataSourceType: DataSourceType.IndexPatterns, - index: defaultIndexPattern, - dataViewId: undefined, - }; - - if ('data_source' in finalDiffableRule && finalDiffableRule.data_source) { - if (finalDiffableRule.data_source.type === DataSourceTypeSnakeCase.data_view) { - indexPatternParams = { - dataSourceType: DataSourceType.DataView, - index: [], - dataViewId: finalDiffableRule.data_source.data_view_id, - }; - } else { - indexPatternParams = { - dataSourceType: DataSourceType.IndexPatterns, - index: finalDiffableRule.data_source.index_patterns, - dataViewId: undefined, - }; - } - } + const indexPatternParameters = getUseRuleIndexPatternParameters( + finalDiffableRule, + defaultIndexPattern + ); const isSavedQueryRule = finalDiffableRule.type === 'saved_query'; - const { indexPattern, isIndexPatternLoading } = useRuleIndexPattern(indexPatternParams); + const { indexPattern, isIndexPatternLoading } = useRuleIndexPattern(indexPatternParameters); const [isTimelineSearchOpen, setIsTimelineSearchOpen] = useState(false); @@ -225,3 +208,38 @@ export function kqlQueryDeserializer( return returnValue; } + +interface UseRuleIndexPatternParameters { + dataSourceType: DataSourceType; + index: string[]; + dataViewId: string | undefined; +} + +function getUseRuleIndexPatternParameters( + finalDiffableRule: DiffableRule, + defaultIndexPattern: string[] +): UseRuleIndexPatternParameters { + let indexPatternParams: UseRuleIndexPatternParameters = { + dataSourceType: DataSourceType.IndexPatterns, + index: defaultIndexPattern, + dataViewId: undefined, + }; + + if ('data_source' in finalDiffableRule && finalDiffableRule.data_source) { + if (finalDiffableRule.data_source.type === DataSourceTypeSnakeCase.data_view) { + indexPatternParams = { + dataSourceType: DataSourceType.DataView, + index: [], + dataViewId: finalDiffableRule.data_source.data_view_id, + }; + } else { + indexPatternParams = { + dataSourceType: DataSourceType.IndexPatterns, + index: finalDiffableRule.data_source.index_patterns, + dataViewId: undefined, + }; + } + } + + return indexPatternParams; +} From f9a6ba1756117a38483e2023d1accbfada249424 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Thu, 10 Oct 2024 17:01:14 +0200 Subject: [PATCH 25/40] Remove braces --- .../three_way_diff/final_edit/fields/kql_query.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx index c8f381bbd8648..4f34ecc996247 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx @@ -65,13 +65,9 @@ export function KqlQueryEdit({ finalDiffableRule, setValidity, setFieldValue }: const [isTimelineSearchOpen, setIsTimelineSearchOpen] = useState(false); - const handleOpenTimelineSearch = useCallback(() => { - setIsTimelineSearchOpen(true); - }, []); + const handleOpenTimelineSearch = useCallback(() => setIsTimelineSearchOpen(true), []); - const handleCloseTimelineSearch = useCallback(() => { - setIsTimelineSearchOpen(false); - }, []); + const handleCloseTimelineSearch = useCallback(() => setIsTimelineSearchOpen(false), []); const handleSetRuleFromTimeline = useCallback( ({ queryBar: timelineQueryBar }) => { From 265c8c8acdfd83a9c5f644fb04518ccadfd2e470 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Thu, 10 Oct 2024 17:09:53 +0200 Subject: [PATCH 26/40] Extract `FinalSide` mode values into an enum --- .../three_way_diff/final_side/constants.ts | 11 +++++++++++ .../three_way_diff/final_side/final_side.tsx | 9 +++++---- 2 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/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/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/constants.ts new file mode 100644 index 0000000000000..6316abcae48a3 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/constants.ts @@ -0,0 +1,11 @@ +/* + * 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 enum FinalSideMode { + READONLY = 'readonly', + EDIT = 'edit', +} 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/final_side/final_side.tsx index c78bb94661079..b17d518a3d92b 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/final_side/final_side.tsx @@ -12,15 +12,16 @@ 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 { FinalSideMode } from './constants'; interface FinalSideProps { fieldName: string; } export function FinalSide({ fieldName }: FinalSideProps): JSX.Element { - const [mode, setMode] = React.useState<'readonly' | 'edit'>('readonly'); // This is temporary, will be replaced with state from the context - const setReadOnlyMode = useCallback(() => setMode('readonly'), []); - const setEditMode = useCallback(() => setMode('edit'), []); + const [mode, setMode] = React.useState(FinalSideMode.READONLY); // TODO: Replace with state from context + const setReadOnlyMode = useCallback(() => setMode(FinalSideMode.READONLY), []); + const setEditMode = useCallback(() => setMode(FinalSideMode.EDIT), []); return ( <> @@ -32,7 +33,7 @@ export function FinalSide({ fieldName }: FinalSideProps): JSX.Element { - {mode === 'edit' ? ( + {mode === FinalSideMode.EDIT ? ( ) : ( From db496792e730f61ed14eb89860a8fc0385050d3b Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Thu, 10 Oct 2024 17:12:15 +0200 Subject: [PATCH 27/40] Refactor `FinalEditContextProvider` to accept children as `PropsWithChildren` --- .../three_way_diff/final_edit/final_edit_context.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx index b6ba7868a99b6..f3505235e1332 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { createContext, useContext } from 'react'; +import React, { createContext, useContext, type PropsWithChildren } from 'react'; import { invariant } from '../../../../../../../common/utils/invariant'; interface FinalEditContextType { @@ -16,11 +16,13 @@ interface FinalEditContextType { const FinalEditContext = createContext(null); interface FinalEditContextProviderProps { - children: React.ReactNode; value: FinalEditContextType; } -export function FinalEditContextProvider({ children, value }: FinalEditContextProviderProps) { +export function FinalEditContextProvider({ + children, + value, +}: PropsWithChildren) { return {children}; } From 3d185d1de06982c2596791f9d7094599cc344a49 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Fri, 11 Oct 2024 11:34:13 +0200 Subject: [PATCH 28/40] Fix Storybook types --- .../alert_suppression.stories.tsx | 4 ++-- .../anomaly_threshold.stories.tsx | 7 ++++++- .../fields/author/author.stories.tsx | 7 ++++++- .../building_block/building_block.stories.tsx | 7 ++++++- .../fields/data_source/data_source.stories.tsx | 7 +++++-- .../fields/description/description.stories.tsx | 7 ++++++- .../fields/eql_query/eql_query.stories.tsx | 7 +++++-- .../fields/esql_query/esql_query.stories.tsx | 7 ++++++- .../event_category_override.stories.tsx | 5 ++++- .../false_positives/false_positives.stories.tsx | 7 ++++++- .../history_window_start.stories.tsx | 5 ++++- .../investigation_fields.stories.tsx | 5 ++++- .../fields/kql_query/kql_query.stories.tsx | 7 +++++-- .../fields/license/license.stories.tsx | 7 ++++++- .../machine_learning_job_id.stories.tsx | 7 ++----- .../fields/max_signals/max_signals.stories.tsx | 7 ++++++- .../final_readonly/fields/name/name.stories.tsx | 7 ++++++- .../new_terms_fields.stories.tsx | 7 ++++++- .../final_readonly/fields/note/note.stories.tsx | 7 ++++++- .../fields/references/references.stories.tsx | 7 ++++++- .../related_integrations.stories.tsx | 7 ++----- .../required_fields/required_fields.stories.tsx | 7 ++++++- .../fields/risk_score/risk_score.stories.tsx | 7 ++++++- .../risk_score_mapping.stories.tsx | 5 ++++- .../rule_name_override.stories.tsx | 5 ++++- .../rule_schedule/rule_schedule.stories.tsx | 7 ++++++- .../fields/setup/setup.stories.tsx | 7 ++++++- .../fields/severity/severity.stories.tsx | 7 ++++++- .../severity_mapping.stories.tsx | 7 ++++++- .../final_readonly/fields/tags/tags.stories.tsx | 7 ++++++- .../fields/threat/threat.stories.tsx | 7 ++++++- .../fields/threat_index/threat_index.stories.tsx | 7 ++++++- .../threat_indicator_path.stories.tsx | 5 ++++- .../threat_language/threat_language.stories.tsx | 7 ++++++- .../threat_mapping/threat_mapping.stories.tsx | 7 ++++++- .../fields/threat_query/threat_query.stories.tsx | 7 +++++-- .../fields/threshold/threshold.stories.tsx | 7 ++++++- .../tiebreaker_field.stories.tsx | 7 ++++++- .../timeline_template.stories.tsx | 7 ++++++- .../timestamp_field/timestamp_field.stories.tsx | 7 ++++++- .../timestamp_override.stories.tsx | 5 ++++- .../final_readonly/fields/type/type.stories.tsx | 7 ++++++- .../final_readonly/storybook/mocks.ts | 16 ++++++++-------- .../three_way_diff_storybook_providers.tsx | 14 +++++++++++++- 44 files changed, 243 insertions(+), 64 deletions(-) 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 4f6739a3af481..9aeeee25983d3 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 @@ -25,8 +25,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/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 8203e015d11db..392187941046c 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 @@ -11,6 +11,7 @@ import { AnomalyThresholdReadOnly } from './anomaly_threshold'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockMachineLearningRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: AnomalyThresholdReadOnly, @@ -23,7 +24,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/author/author.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/author/author.stories.tsx index 2700517c1c3ec..97526ec0290b9 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/author/author.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/author/author.stories.tsx @@ -11,6 +11,7 @@ import { AuthorReadOnly } from './author'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: AuthorReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 f927b753c17ab..6bace209f283b 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 @@ -11,6 +11,7 @@ import { BuildingBlockReadOnly } from './building_block'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: BuildingBlockReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 091a874385156..d7bf26bc7d9ba 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 @@ -29,8 +29,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/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 ba094ecfe54f9..079c327fb29ef 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 @@ -11,6 +11,7 @@ import { DescriptionReadOnly } from './description'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: DescriptionReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 84ea98047bcee..8ee0ac1511784 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 @@ -31,8 +31,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/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 664294dbe768c..70f37106842e1 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 @@ -10,6 +10,7 @@ import type { Story } from '@storybook/react'; import { FieldReadOnly } from '../../field_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, @@ -21,7 +22,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/event_category_override/event_category_override.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/event_category_override/event_category_override.stories.tsx index 1eb29ef1084d9..1f5987287f665 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/event_category_override/event_category_override.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/event_category_override/event_category_override.stories.tsx @@ -11,6 +11,7 @@ import { EventCategoryOverrideReadOnly } from './event_category_override'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockEqlRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: EventCategoryOverrideReadOnly, @@ -24,7 +25,9 @@ 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 60d8a34616652..a5884b340e32b 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 @@ -11,6 +11,7 @@ import { FalsePositivesReadOnly } from './false_positives'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: FalsePositivesReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 c84868e97ee0c..12e0f086ecec9 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 @@ -11,6 +11,7 @@ import { HistoryWindowStartReadOnly } from './history_window_start'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockNewTermsRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: HistoryWindowStartReadOnly, @@ -24,7 +25,9 @@ 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 e73b01a719f8a..a32c79076a03d 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 @@ -11,6 +11,7 @@ import { InvestigationFieldsReadOnly } from './investigation_fields'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: InvestigationFieldsReadOnly, @@ -24,7 +25,9 @@ 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 4fd102fc0627f..16731ec498162 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 @@ -33,8 +33,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/license/license.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/license/license.stories.tsx index 044564acd91d8..666f4b6507798 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/license/license.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/license/license.stories.tsx @@ -11,6 +11,7 @@ import { LicenseReadOnly } from './license'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: LicenseReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 8dc504b737e00..ea23aa5984106 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 @@ -64,12 +64,9 @@ 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 d6f369ff47ce6..3c7945366a174 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 @@ -11,6 +11,7 @@ import { MaxSignalsReadOnly } from './max_signals'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: MaxSignalsReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 1451d3b70ef8b..d97f71b4df0ac 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 @@ -11,6 +11,7 @@ import { NameReadOnly } from './name'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: NameReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 8f77a747fa06c..f3dc5a1e3da9b 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 @@ -11,6 +11,7 @@ import { NewTermsFieldsReadOnly } from './new_terms_fields'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockNewTermsRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: NewTermsFieldsReadOnly, @@ -23,7 +24,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 501faeb1cfbad..4a62c5e58dc28 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 @@ -11,6 +11,7 @@ import { NoteReadOnly } from './note'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: NoteReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 561d5b36cf4f3..ea8ee856099dd 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 @@ -11,6 +11,7 @@ import { ReferencesReadOnly } from './references'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: ReferencesReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 4657b21b0c64e..b810eaa1fbb8f 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 @@ -45,12 +45,9 @@ 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 44d3383ae8227..ee926fc7ed561 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 @@ -10,6 +10,7 @@ import { RequiredFieldsReadOnly } from './required_fields'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: RequiredFieldsReadOnly, @@ -21,7 +22,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 c0be0fb6190f6..cb640e31090cc 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 @@ -11,6 +11,7 @@ import { RiskScoreReadOnly } from './risk_score'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: RiskScoreReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 40c8644ffd3ea..90dbe7f981f64 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 @@ -11,6 +11,7 @@ import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { RiskScoreMappingReadOnly } from './risk_score_mapping'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: RiskScoreMappingReadOnly, @@ -24,7 +25,9 @@ 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 fa46e313fd664..d0d596f15af42 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 @@ -11,6 +11,7 @@ import { RuleNameOverrideReadOnly } from './rule_name_override'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: RuleNameOverrideReadOnly, @@ -24,7 +25,9 @@ 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 9e6be8a3cbe82..30f2170a30f31 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 @@ -11,6 +11,7 @@ import { RuleScheduleReadOnly } from './rule_schedule'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: RuleScheduleReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 f610cbf9eafbb..34410c7c6f638 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 @@ -11,6 +11,7 @@ import { SetupReadOnly } from './setup'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: SetupReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 51956bb27fa0e..b51547d1655e0 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 @@ -11,6 +11,7 @@ import { SeverityReadOnly } from './severity'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: SeverityReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 6a4b365a86db5..b4ecb70ce66cd 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 @@ -11,6 +11,7 @@ import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { SeverityMappingReadOnly } from './severity_mapping'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: SeverityMappingReadOnly, @@ -23,7 +24,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 b2c483cbc8c97..c8129dd989d24 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 @@ -11,6 +11,7 @@ import { TagsReadOnly } from './tags'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: TagsReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 aa95633349260..de8c15f29e0cc 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 @@ -11,6 +11,7 @@ import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreatReadOnly } from './threat'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: ThreatReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 4f10cb8932ab1..aeb1b6491bba6 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 @@ -11,6 +11,7 @@ import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreatIndexReadOnly } from './threat_index'; import { mockThreatMatchRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: ThreatIndexReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 be8906d76eb6b..bb91b29fffe11 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 @@ -11,6 +11,7 @@ import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreatIndicatorPathReadOnly } from './threat_indicator_path'; import { mockThreatMatchRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: ThreatIndicatorPathReadOnly, @@ -24,7 +25,9 @@ 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_language/threat_language.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_language/threat_language.stories.tsx index 0e3408aae043e..bae9f596de750 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_language/threat_language.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_language/threat_language.stories.tsx @@ -11,6 +11,7 @@ import { ThreatLanguageReadOnly } from './threat_language'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockThreatMatchRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: ThreatLanguageReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 4f5b8f608c4bf..35c4bba4544a7 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 @@ -11,6 +11,7 @@ import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreatMappingReadOnly } from './threat_mapping'; import { mockThreatMatchRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: ThreatMappingReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 bbc5b19d7e66a..625226ab4f9f5 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 @@ -31,8 +31,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/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 8dfee48ba7d23..0541d5f9a9b47 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 @@ -11,6 +11,7 @@ import { ThresholdReadOnly } from './threshold'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockThresholdRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: ThresholdReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tiebreaker_field/tiebreaker_field.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tiebreaker_field/tiebreaker_field.stories.tsx index 2a41b6c928963..3e73afda8f4eb 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tiebreaker_field/tiebreaker_field.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tiebreaker_field/tiebreaker_field.stories.tsx @@ -11,6 +11,7 @@ import { TiebreakerFieldReadOnly } from './tiebreaker_field'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockEqlRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: TiebreakerFieldReadOnly, @@ -23,7 +24,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 e8646a562dadd..e4c3a2043ff24 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 @@ -11,6 +11,7 @@ import { TimelineTemplateReadOnly } from './timeline_template'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: TimelineTemplateReadOnly, @@ -23,7 +24,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/timestamp_field/timestamp_field.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/timestamp_field/timestamp_field.stories.tsx index 5d6b6c0a7bc3a..9b3977c3deeb2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/timestamp_field/timestamp_field.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/timestamp_field/timestamp_field.stories.tsx @@ -11,6 +11,7 @@ import { TimestampFieldReadOnly } from './timestamp_field'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockEqlRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: TimestampFieldReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); 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 eaba3bda0c2e7..5828ba156d9d2 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 @@ -11,6 +11,7 @@ import { TimestampOverrideReadOnly } from './timestamp_override'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: TimestampOverrideReadOnly, @@ -24,7 +25,9 @@ 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 e3f901c958788..ba252a8a80b88 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 @@ -11,6 +11,7 @@ import { TypeReadOnly } from './type'; import { FieldReadOnly } from '../../field_readonly'; import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { mockCustomQueryRule } from '../../storybook/mocks'; +import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; export default { component: TypeReadOnly, @@ -22,7 +23,11 @@ interface TemplateProps { } const Template: Story = (args) => { - return ; + return ( + + + + ); }; export const Default = Template.bind({}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/mocks.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/mocks.ts index 4612852c0ff7e..e940f1ba52a40 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/mocks.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/mocks.ts @@ -159,7 +159,7 @@ const customQueryDiffableRuleFields: DiffableCustomQueryFields = { }; export function mockCustomQueryRule( - overrides: Partial + overrides: Partial = {} ): DiffableRule { return { ...commonDiffableRuleFields, @@ -177,7 +177,7 @@ const savedQueryDiffableRuleFields: DiffableSavedQueryFields = { }; export function mockSavedQueryRule( - overrides: Partial + overrides: Partial = {} ): DiffableRule { return { ...commonDiffableRuleFields, @@ -196,7 +196,7 @@ const eqlDiffableRuleFields: DiffableEqlFields = { }; export function mockEqlRule( - overrides: Partial + overrides: Partial = {} ): DiffableRule { return { ...commonDiffableRuleFields, @@ -214,7 +214,7 @@ const esqlDiffableRuleFields: DiffableEsqlFields = { }; export function mockEsqlRule( - overrides: Partial + overrides: Partial = {} ): DiffableRule { return { ...commonDiffableRuleFields, @@ -230,7 +230,7 @@ const machineLearningDiffableRuleFields: DiffableMachineLearningFields = { }; export function mockMachineLearningRule( - overrides: Partial + overrides: Partial = {} ): DiffableRule { return { ...commonDiffableRuleFields, @@ -268,7 +268,7 @@ const threatMatchDiffableRuleFields: DiffableThreatMatchFields = { }; export function mockThreatMatchRule( - overrides: Partial + overrides: Partial = {} ): DiffableRule { return { ...commonDiffableRuleFields, @@ -290,7 +290,7 @@ const newTermsDiffableRuleFields: DiffableNewTermsFields = { }; export function mockNewTermsRule( - overrides: Partial + overrides: Partial = {} ): DiffableRule { return { ...commonDiffableRuleFields, @@ -314,7 +314,7 @@ export const thresholdDiffableRuleFields: DiffableThresholdFields = { }; export function mockThresholdRule( - overrides: Partial + overrides: Partial = {} ): DiffableRule { return { ...commonDiffableRuleFields, 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 4eb14440c056c..722f5ac9f6ada 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 @@ -15,6 +15,9 @@ import type { UpsellingService } from '@kbn/security-solution-upselling/service' import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; 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 { mockCustomQueryRule } from './mocks'; function createKibanaServicesMock(overrides?: Partial) { const baseMock = { @@ -69,14 +72,18 @@ function createMockStore() { return store; } +const setRuleFieldResolvedValueMock = () => {}; + interface StorybookProvidersProps { children: React.ReactNode; kibanaServicesOverrides?: Record; + finalDiffableRule?: DiffableRule; } export function ThreeWayDiffStorybookProviders({ children, kibanaServicesOverrides, + finalDiffableRule = mockCustomQueryRule(), }: StorybookProvidersProps) { const kibanaServicesMock = createKibanaServicesMock(kibanaServicesOverrides); const KibanaReactContext = createKibanaReactContext(kibanaServicesMock); @@ -88,7 +95,12 @@ export function ThreeWayDiffStorybookProviders({ - {children} + + {children} + From 233fb28980d39e0a2a90c6663ce046a889c00f08 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Fri, 11 Oct 2024 15:15:16 +0200 Subject: [PATCH 29/40] Make TS happy --- .../field_upgrade_conflicts_resolver.tsx | 5 +- .../rule_upgrade_conflicts_resolver.tsx | 42 +++++++------ .../final_edit/common_rule_field_edit.tsx | 8 +-- .../custom_query_rule_field_edit.tsx | 4 +- .../three_way_diff/final_edit/final_edit.tsx | 43 ++++++------- .../final_edit/new_terms_rule_field_edit.tsx | 4 +- .../saved_query_rule_field_edit.tsx | 4 +- .../threat_match_rule_field_edit.tsx | 4 +- .../final_edit/threshold_rule_field_edit.tsx | 4 +- .../three_way_diff/final_side/final_side.tsx | 3 +- .../model/prebuilt_rule_upgrade/constants.ts | 29 +++++++++ .../model/prebuilt_rule_upgrade/types.ts | 63 +++++++++++++++++++ 12 files changed, 152 insertions(+), 61 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/constants.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/types.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 617d3a4252124..57b095ac2b3db 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 @@ -20,14 +20,15 @@ import { ComparisonSide } from '../comparison_side/comparison_side'; import { FinalSide } from '../final_side/final_side'; import { FieldUpgradeConflictsResolverHeader } from './field_upgrade_conflicts_resolver_header'; import { useDiffableRuleContext } from '../diffable_rule_context'; +import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/types'; -interface FieldUpgradeConflictsResolverProps { +interface FieldUpgradeConflictsResolverProps { fieldName: FieldName; fieldUpgradeState: FieldUpgradeState; fieldThreeWayDiff: RuleFieldsDiff[FieldName]; } -export function FieldUpgradeConflictsResolver({ +export function FieldUpgradeConflictsResolver({ fieldName, fieldUpgradeState, fieldThreeWayDiff, 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/components/rule_upgrade_conflicts_resolver.tsx index 1ab8500d967d0..d178bf7acb503 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/components/rule_upgrade_conflicts_resolver.tsx @@ -8,7 +8,15 @@ import React from 'react'; import type { RuleUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { FieldUpgradeConflictsResolver } from './field_upgrade_conflicts_resolver'; -import { HIDDEN_FIELDS } from './constants'; +import type { NonUpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/types'; +import { inNonUpgradeableFieldName } from '../../../../model/prebuilt_rule_upgrade/constants'; + +type FieldDiffEntries = Array< + [ + Exclude, + Required[Exclude] + ] +>; interface RuleUpgradeConflictsResolverProps { ruleUpgradeState: RuleUpgradeState; @@ -17,26 +25,22 @@ interface RuleUpgradeConflictsResolverProps { export function RuleUpgradeConflictsResolver({ ruleUpgradeState, }: RuleUpgradeConflictsResolverProps): JSX.Element { - const fieldDiffEntries = Object.entries(ruleUpgradeState.diff.fields) as Array< - [ - keyof typeof ruleUpgradeState.diff.fields, - Required[keyof typeof ruleUpgradeState.diff.fields] - ] + const fieldDiffEntries = Object.entries(ruleUpgradeState.diff.fields) as FieldDiffEntries< + typeof ruleUpgradeState.diff.fields >; - const fields = fieldDiffEntries - .filter(([fieldName]) => { - /* Remove fields that aren't supposed to be displayed */ - return HIDDEN_FIELDS.has(fieldName) === false; - }) - .map(([fieldName, fieldDiff]) => ( - - )); + const fields = fieldDiffEntries.filter(([fieldName]) => { + return inNonUpgradeableFieldName(fieldName) === false; + }) as FieldDiffEntries; + + fields.map(([fieldName, fieldDiff]) => ( + + )); return <>{fields}; } 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 6fa20d865b81f..44a5ac40e5dc5 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,21 +6,17 @@ */ import React from 'react'; -import type { DiffableCommonFields } from '../../../../../../../common/api/detection_engine'; import { FieldFormWrapper } from './field_form_wrapper'; import { NameEdit, nameSchema } from './fields/name'; - +import type { UpgradeableCommonFields } from '../../../../model/prebuilt_rule_upgrade/types'; interface CommonRuleFieldEditProps { - fieldName: keyof DiffableCommonFields; + fieldName: UpgradeableCommonFields; } export function CommonRuleFieldEdit({ fieldName }: CommonRuleFieldEditProps) { switch (fieldName) { case 'name': return ; - case 'version': - /* "version" is not editable */ - return null; default: return null; // Will be replaced with `assertUnreachable(fieldName)` once all fields are implemented } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/custom_query_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/custom_query_rule_field_edit.tsx index 9fcf41a62e35d..004c94ed8dc48 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/custom_query_rule_field_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/custom_query_rule_field_edit.tsx @@ -6,7 +6,6 @@ */ import React from 'react'; -import type { DiffableCustomQueryFields } from '../../../../../../../common/api/detection_engine'; import { FieldFormWrapper } from './field_form_wrapper'; import { KqlQueryEdit, @@ -14,9 +13,10 @@ import { kqlQuerySerializer, kqlQueryDeserializer, } from './fields/kql_query'; +import type { UpgradeableCustomQueryFields } from '../../../../model/prebuilt_rule_upgrade/types'; interface CustomQueryRuleFieldEditProps { - fieldName: keyof DiffableCustomQueryFields; + fieldName: UpgradeableCustomQueryFields; } export function CustomQueryRuleFieldEdit({ fieldName }: CustomQueryRuleFieldEditProps) { 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/final_edit.tsx index 4f7f3f0ad8461..55ccf34f97a63 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/final_edit.tsx @@ -5,15 +5,8 @@ * 2.0. */ -import React, { useMemo } from 'react'; -import { DiffableCommonFields } from '../../../../../../../common/api/detection_engine'; -import type { - DiffableThreatMatchFields, - DiffableCustomQueryFields, - DiffableRuleTypes, - DiffableThresholdFields, - DiffableNewTermsFields, -} from '../../../../../../../common/api/detection_engine'; +import React from 'react'; +import type { DiffableRuleTypes } from '../../../../../../../common/api/detection_engine'; import { FinalEditContextProvider } from './final_edit_context'; import { assertUnreachable } from '../../../../../../../common/utility_types'; import { useDiffableRuleContext } from '../diffable_rule_context'; @@ -23,9 +16,18 @@ 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 { + UpgradeableDiffableFields, + UpgradeableCustomQueryFields, + UpgradeableSavedQueryFields, + UpgradeableThreatMatchFields, + UpgradeableThresholdFields, + UpgradeableNewTermsFields, +} from '../../../../model/prebuilt_rule_upgrade/types'; +import { isCommonFieldName } from '../../../../model/prebuilt_rule_upgrade/constants'; interface FinalEditProps { - fieldName: string; + fieldName: UpgradeableDiffableFields; setReadOnlyMode: () => void; } @@ -40,37 +42,32 @@ export function FinalEdit({ fieldName, setReadOnlyMode }: FinalEditProps) { } interface FinalEditFieldProps { - fieldName: string; + fieldName: UpgradeableDiffableFields; ruleType: DiffableRuleTypes; } function FieldEdit({ fieldName, ruleType }: FinalEditFieldProps) { - const { data: commonField } = useMemo( - () => DiffableCommonFields.keyof().safeParse(fieldName), - [fieldName] - ); - - if (commonField) { - return ; + if (isCommonFieldName(fieldName)) { + return ; } switch (ruleType) { case 'query': - return ; + return ; case 'saved_query': - return ; + return ; case 'eql': return {'Rule type not yet implemented'}; case 'esql': return {'Rule type not yet implemented'}; case 'threat_match': - return ; + return ; case 'threshold': - return ; + return ; case 'machine_learning': return {'Rule type not yet implemented'}; case 'new_terms': - return ; + return ; default: return assertUnreachable(ruleType); } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/new_terms_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/new_terms_rule_field_edit.tsx index 4f0e8da4909bb..ad42397ef4c62 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/new_terms_rule_field_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/new_terms_rule_field_edit.tsx @@ -6,7 +6,6 @@ */ import React from 'react'; -import type { DiffableNewTermsFields } from '../../../../../../../common/api/detection_engine'; import { FieldFormWrapper } from './field_form_wrapper'; import { KqlQueryEdit, @@ -14,9 +13,10 @@ import { kqlQuerySerializer, kqlQueryDeserializer, } from './fields/kql_query'; +import type { UpgradeableNewTermsFields } from '../../../../model/prebuilt_rule_upgrade/types'; interface NewTermsRuleFieldEditProps { - fieldName: keyof DiffableNewTermsFields; + fieldName: UpgradeableNewTermsFields; } export function NewTermsRuleFieldEdit({ fieldName }: NewTermsRuleFieldEditProps) { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/saved_query_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/saved_query_rule_field_edit.tsx index 61a97e691f0c5..ebc0a784faf91 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/saved_query_rule_field_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/saved_query_rule_field_edit.tsx @@ -6,7 +6,6 @@ */ import React from 'react'; -import type { DiffableSavedQueryFields } from '../../../../../../../common/api/detection_engine'; import { FieldFormWrapper } from './field_form_wrapper'; import { KqlQueryEdit, @@ -14,9 +13,10 @@ import { kqlQuerySerializer, kqlQueryDeserializer, } from './fields/kql_query'; +import type { UpgradeableSavedQueryFields } from '../../../../model/prebuilt_rule_upgrade/types'; interface SavedQueryRuleFieldEditProps { - fieldName: keyof DiffableSavedQueryFields; + fieldName: UpgradeableSavedQueryFields; } export function SavedQueryRuleFieldEdit({ fieldName }: SavedQueryRuleFieldEditProps) { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threat_match_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threat_match_rule_field_edit.tsx index c98b44ae74ccd..831b85055660d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threat_match_rule_field_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threat_match_rule_field_edit.tsx @@ -6,7 +6,6 @@ */ import React from 'react'; -import type { DiffableThreatMatchFields } from '../../../../../../../common/api/detection_engine'; import { FieldFormWrapper } from './field_form_wrapper'; import { KqlQueryEdit, @@ -14,9 +13,10 @@ import { kqlQuerySerializer, kqlQueryDeserializer, } from './fields/kql_query'; +import type { UpgradeableThreatMatchFields } from '../../../../model/prebuilt_rule_upgrade/types'; interface ThreatMatchRuleFieldEditProps { - fieldName: keyof DiffableThreatMatchFields; + fieldName: UpgradeableThreatMatchFields; } export function ThreatMatchRuleFieldEdit({ fieldName }: ThreatMatchRuleFieldEditProps) { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threshold_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threshold_rule_field_edit.tsx index 870164d730dc8..d4094777865ab 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threshold_rule_field_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threshold_rule_field_edit.tsx @@ -6,7 +6,6 @@ */ import React from 'react'; -import type { DiffableThresholdFields } from '../../../../../../../common/api/detection_engine'; import { FieldFormWrapper } from './field_form_wrapper'; import { KqlQueryEdit, @@ -14,9 +13,10 @@ import { kqlQuerySerializer, kqlQueryDeserializer, } from './fields/kql_query'; +import type { UpgradeableThresholdFields } from '../../../../model/prebuilt_rule_upgrade/types'; interface ThresholdRuleFieldEditProps { - fieldName: keyof DiffableThresholdFields; + fieldName: UpgradeableThresholdFields; } export function ThresholdRuleFieldEdit({ fieldName }: ThresholdRuleFieldEditProps) { 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/final_side/final_side.tsx index b17d518a3d92b..80e6881da01c0 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/final_side/final_side.tsx @@ -13,9 +13,10 @@ import * as i18n from './translations'; import { FinalReadOnly } from '../final_readonly/final_readonly'; import { FinalEdit } from '../final_edit/final_edit'; import { FinalSideMode } from './constants'; +import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/types'; interface FinalSideProps { - fieldName: string; + fieldName: UpgradeableDiffableFields; } export function FinalSide({ fieldName }: FinalSideProps): JSX.Element { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/constants.ts new file mode 100644 index 0000000000000..a392ed66948c7 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/constants.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 { DiffableCommonFields } from '../../../../../common/api/detection_engine'; +import type { NonUpgradeableDiffableFields } from './types'; + +export const NON_UPGRADEABLE_DIFFABLE_FIELDS = [ + 'author', + 'license', + 'rule_id', + 'type', + 'version', +] as const; + +export const COMMON_FIELD_NAMES = DiffableCommonFields.keyof().options; + +export function isCommonFieldName(fieldName: string): fieldName is keyof DiffableCommonFields { + return (COMMON_FIELD_NAMES as string[]).includes(fieldName); +} + +export function inNonUpgradeableFieldName( + fieldName: string +): fieldName is NonUpgradeableDiffableFields { + return (NON_UPGRADEABLE_DIFFABLE_FIELDS as Readonly).includes(fieldName); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/types.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/types.ts new file mode 100644 index 0000000000000..d74e0fc020cb4 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/types.ts @@ -0,0 +1,63 @@ +/* + * 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 { NON_UPGRADEABLE_DIFFABLE_FIELDS } from './constants'; +import type { + DiffableCommonFields, + DiffableCustomQueryFields, + DiffableEqlFields, + DiffableEsqlFields, + DiffableMachineLearningFields, + DiffableNewTermsFields, + DiffableSavedQueryFields, + DiffableThreatMatchFields, + DiffableThresholdFields, + RuleFieldsDiff, +} from '../../../../../common/api/detection_engine'; + +export type NonUpgradeableDiffableFields = (typeof NON_UPGRADEABLE_DIFFABLE_FIELDS)[number]; + +export type UpgradeableDiffableFields = Exclude; + +export type UpgradeableCommonFields = Exclude< + keyof DiffableCommonFields, + NonUpgradeableDiffableFields +>; + +export type UpgradeableCustomQueryFields = Exclude< + keyof DiffableCustomQueryFields, + NonUpgradeableDiffableFields +>; + +export type UpgradeableSavedQueryFields = Exclude< + keyof DiffableSavedQueryFields, + NonUpgradeableDiffableFields +>; + +export type UpgradeableEqlFields = Exclude; + +export type UpgradeableEsqlFields = Exclude; + +export type UpgradeableThreatMatchFields = Exclude< + keyof DiffableThreatMatchFields, + NonUpgradeableDiffableFields +>; + +export type UpgradeableThresholdFields = Exclude< + keyof DiffableThresholdFields, + NonUpgradeableDiffableFields +>; + +export type UpgradeableMachineLearningFields = Exclude< + keyof DiffableMachineLearningFields, + NonUpgradeableDiffableFields +>; + +export type UpgradeableNewTermsFields = Exclude< + keyof DiffableNewTermsFields, + NonUpgradeableDiffableFields +>; From 02710b3bc4655d04a8d0a1e18aad7e0d503960c7 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Sat, 12 Oct 2024 12:22:29 +0200 Subject: [PATCH 30/40] Update x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/constants.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤦 Typo Co-authored-by: Maxim Palenov --- .../rule_management/model/prebuilt_rule_upgrade/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/constants.ts index a392ed66948c7..6f25272e0434b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/constants.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/constants.ts @@ -22,7 +22,7 @@ export function isCommonFieldName(fieldName: string): fieldName is keyof Diffabl return (COMMON_FIELD_NAMES as string[]).includes(fieldName); } -export function inNonUpgradeableFieldName( +export function isNonUpgradeableFieldName( fieldName: string ): fieldName is NonUpgradeableDiffableFields { return (NON_UPGRADEABLE_DIFFABLE_FIELDS as Readonly).includes(fieldName); From 9a4741b55ba2220334660a7c388b06b6786b2179 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Mon, 14 Oct 2024 13:15:02 +0200 Subject: [PATCH 31/40] Update code comment text --- .../rule_details/three_way_diff/comparison_side/utils.ts | 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/utils.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/utils.ts index fa2560e64655c..d0673c460a1d5 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 @@ -17,7 +17,7 @@ import type { * * @param version - The version for which the field value is to be picked. * @param fieldThreeWayDiff - The three-way diff object containing the field values for different versions. - * @param resolvedValue - Field value that the upgraded rule will have. + * @param resolvedValue - A value field will be upgraded to. * @returns - The field value for the specified version */ export function pickFieldValueForVersion( From 05563a5e7e0339b335c3b14e1b7fe8bb302b883e Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Mon, 14 Oct 2024 13:19:35 +0200 Subject: [PATCH 32/40] Fix a typo in `isNonUpgradeableFieldName` --- .../components/rule_upgrade_conflicts_resolver.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/rule_upgrade_conflicts_resolver.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/components/rule_upgrade_conflicts_resolver.tsx index d178bf7acb503..e5cb04aa70e6f 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/components/rule_upgrade_conflicts_resolver.tsx @@ -9,7 +9,7 @@ import React from 'react'; import type { RuleUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { FieldUpgradeConflictsResolver } from './field_upgrade_conflicts_resolver'; import type { NonUpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/types'; -import { inNonUpgradeableFieldName } from '../../../../model/prebuilt_rule_upgrade/constants'; +import { isNonUpgradeableFieldName } from '../../../../model/prebuilt_rule_upgrade/constants'; type FieldDiffEntries = Array< [ @@ -30,7 +30,7 @@ export function RuleUpgradeConflictsResolver({ >; const fields = fieldDiffEntries.filter(([fieldName]) => { - return inNonUpgradeableFieldName(fieldName) === false; + return isNonUpgradeableFieldName(fieldName) === false; }) as FieldDiffEntries; fields.map(([fieldName, fieldDiff]) => ( From 61326b898b72aaa1ee86b3281ab746b3215e54f7 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Mon, 14 Oct 2024 15:35:12 +0200 Subject: [PATCH 33/40] Simplify `isTimelineSearchOpen`/`toggleIsTimelineSearchOpen` implementation --- .../rule_upgrade_conflicts_resolver.tsx | 6 ++---- .../final_edit/fields/kql_query.tsx | 18 ++++++------------ 2 files changed, 8 insertions(+), 16 deletions(-) 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/components/rule_upgrade_conflicts_resolver.tsx index e5cb04aa70e6f..2cb0cab915fae 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/components/rule_upgrade_conflicts_resolver.tsx @@ -24,7 +24,7 @@ interface RuleUpgradeConflictsResolverProps { export function RuleUpgradeConflictsResolver({ ruleUpgradeState, -}: RuleUpgradeConflictsResolverProps): JSX.Element { +}: RuleUpgradeConflictsResolverProps): React.ReactNode { const fieldDiffEntries = Object.entries(ruleUpgradeState.diff.fields) as FieldDiffEntries< typeof ruleUpgradeState.diff.fields >; @@ -33,7 +33,7 @@ export function RuleUpgradeConflictsResolver({ return isNonUpgradeableFieldName(fieldName) === false; }) as FieldDiffEntries; - fields.map(([fieldName, fieldDiff]) => ( + return fields.map(([fieldName, fieldDiff]) => ( )); - - return <>{fields}; } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx index 4f34ecc996247..ac570dc22d427 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx @@ -5,7 +5,8 @@ * 2.0. */ -import React, { useState, useCallback } from 'react'; +import React, { useCallback } from 'react'; +import { useToggle } from 'react-use'; import { css } from '@emotion/css'; import { EuiButtonEmpty } from '@elastic/eui'; import type { Type } from '@kbn/securitysolution-io-ts-alerting-types'; @@ -53,21 +54,13 @@ interface KqlQueryEditProps { export function KqlQueryEdit({ finalDiffableRule, setValidity, setFieldValue }: KqlQueryEditProps) { const defaultIndexPattern = useDefaultIndexPattern(); - const indexPatternParameters = getUseRuleIndexPatternParameters( finalDiffableRule, defaultIndexPattern ); - - const isSavedQueryRule = finalDiffableRule.type === 'saved_query'; - const { indexPattern, isIndexPatternLoading } = useRuleIndexPattern(indexPatternParameters); - const [isTimelineSearchOpen, setIsTimelineSearchOpen] = useState(false); - - const handleOpenTimelineSearch = useCallback(() => setIsTimelineSearchOpen(true), []); - - const handleCloseTimelineSearch = useCallback(() => setIsTimelineSearchOpen(false), []); + const [isTimelineSearchOpen, toggleIsTimelineSearchOpen] = useToggle(false); const handleSetRuleFromTimeline = useCallback( ({ queryBar: timelineQueryBar }) => { @@ -78,6 +71,7 @@ export function KqlQueryEdit({ finalDiffableRule, setValidity, setFieldValue }: const { onOpenTimeline } = useRuleFromTimeline(handleSetRuleFromTimeline); + const isSavedQueryRule = finalDiffableRule.type === 'saved_query'; const savedQueryId = isSavedQueryRule && 'saved_query_id' in finalDiffableRule.kql_query ? finalDiffableRule.kql_query.saved_query_id @@ -97,7 +91,7 @@ export function KqlQueryEdit({ finalDiffableRule, setValidity, setFieldValue }: ...kqlQuerySchema.queryBar, label: stepDefineRuleI18n.QUERY_BAR_LABEL, labelAppend: isSavedQueryRule ? null : ( - + ), }} component={QueryBarDefineRule} @@ -105,7 +99,7 @@ export function KqlQueryEdit({ finalDiffableRule, setValidity, setFieldValue }: indexPattern, isLoading: isIndexPatternLoading, openTimelineSearch: isTimelineSearchOpen, - onCloseTimelineSearch: handleCloseTimelineSearch, + onCloseTimelineSearch: toggleIsTimelineSearchOpen, onValidityChange: setValidity, onOpenTimeline, isDisabled: isSavedQueryRule, From d0c6f55f5801cbdc2f873949ed1530c419789d59 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Mon, 14 Oct 2024 15:41:07 +0200 Subject: [PATCH 34/40] Move getting saved query ID into a function --- .../three_way_diff/final_edit/fields/kql_query.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx index ac570dc22d427..b56bf564eccc2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx @@ -72,13 +72,9 @@ export function KqlQueryEdit({ finalDiffableRule, setValidity, setFieldValue }: const { onOpenTimeline } = useRuleFromTimeline(handleSetRuleFromTimeline); const isSavedQueryRule = finalDiffableRule.type === 'saved_query'; - const savedQueryId = - isSavedQueryRule && 'saved_query_id' in finalDiffableRule.kql_query - ? finalDiffableRule.kql_query.saved_query_id - : undefined; const { savedQuery } = useGetSavedQuery({ - savedQueryId, + savedQueryId: getSavedQueryId(finalDiffableRule), ruleType: finalDiffableRule.type, }); @@ -233,3 +229,11 @@ function getUseRuleIndexPatternParameters( return indexPatternParams; } + +function getSavedQueryId(diffableRule: DiffableRule): string | undefined { + if (diffableRule.type === 'saved_query' && 'saved_query_id' in diffableRule.kql_query) { + return diffableRule.kql_query.saved_query_id; + } + + return undefined; +} From 5b3ebf9f20e491241b8a92b876ed40c0f1bb19d3 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Mon, 14 Oct 2024 16:09:26 +0200 Subject: [PATCH 35/40] Refactor `getUseRuleIndexPatternParameters` --- .../final_edit/fields/kql_query.tsx | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx index b56bf564eccc2..e57c28a99ad4e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx @@ -205,29 +205,25 @@ function getUseRuleIndexPatternParameters( finalDiffableRule: DiffableRule, defaultIndexPattern: string[] ): UseRuleIndexPatternParameters { - let indexPatternParams: UseRuleIndexPatternParameters = { + if (!('data_source' in finalDiffableRule) || !finalDiffableRule.data_source) { + return { + dataSourceType: DataSourceType.IndexPatterns, + index: defaultIndexPattern, + dataViewId: undefined, + }; + } + if (finalDiffableRule.data_source.type === DataSourceTypeSnakeCase.data_view) { + return { + dataSourceType: DataSourceType.DataView, + index: [], + dataViewId: finalDiffableRule.data_source.data_view_id, + }; + } + return { dataSourceType: DataSourceType.IndexPatterns, - index: defaultIndexPattern, + index: finalDiffableRule.data_source.index_patterns, dataViewId: undefined, }; - - if ('data_source' in finalDiffableRule && finalDiffableRule.data_source) { - if (finalDiffableRule.data_source.type === DataSourceTypeSnakeCase.data_view) { - indexPatternParams = { - dataSourceType: DataSourceType.DataView, - index: [], - dataViewId: finalDiffableRule.data_source.data_view_id, - }; - } else { - indexPatternParams = { - dataSourceType: DataSourceType.IndexPatterns, - index: finalDiffableRule.data_source.index_patterns, - dataViewId: undefined, - }; - } - } - - return indexPatternParams; } function getSavedQueryId(diffableRule: DiffableRule): string | undefined { From 2079647c3869610a8433ddcb9bb6e4883600d96d Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Mon, 14 Oct 2024 16:15:22 +0200 Subject: [PATCH 36/40] Move field-related types and constants into `fields.ts` --- .../field_upgrade_conflicts_resolver.tsx | 2 +- .../rule_upgrade_conflicts_resolver.tsx | 4 +-- .../final_edit/common_rule_field_edit.tsx | 2 +- .../custom_query_rule_field_edit.tsx | 2 +- .../three_way_diff/final_edit/final_edit.tsx | 4 +-- .../final_edit/new_terms_rule_field_edit.tsx | 2 +- .../saved_query_rule_field_edit.tsx | 2 +- .../threat_match_rule_field_edit.tsx | 2 +- .../final_edit/threshold_rule_field_edit.tsx | 2 +- .../three_way_diff/final_side/final_side.tsx | 2 +- .../model/prebuilt_rule_upgrade/constants.ts | 29 ------------------- .../{types.ts => fields.ts} | 23 +++++++++++++-- 12 files changed, 33 insertions(+), 43 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/constants.ts rename x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/{types.ts => fields.ts} (73%) 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 57b095ac2b3db..6a2ad17f45f26 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 @@ -20,7 +20,7 @@ import { ComparisonSide } from '../comparison_side/comparison_side'; import { FinalSide } from '../final_side/final_side'; import { FieldUpgradeConflictsResolverHeader } from './field_upgrade_conflicts_resolver_header'; import { useDiffableRuleContext } from '../diffable_rule_context'; -import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/types'; +import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; interface FieldUpgradeConflictsResolverProps { fieldName: FieldName; 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/components/rule_upgrade_conflicts_resolver.tsx index 2cb0cab915fae..3379cf2ab3e96 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/components/rule_upgrade_conflicts_resolver.tsx @@ -8,8 +8,8 @@ import React from 'react'; import type { RuleUpgradeState } from '../../../../model/prebuilt_rule_upgrade'; import { FieldUpgradeConflictsResolver } from './field_upgrade_conflicts_resolver'; -import type { NonUpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/types'; -import { isNonUpgradeableFieldName } from '../../../../model/prebuilt_rule_upgrade/constants'; +import type { NonUpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; +import { isNonUpgradeableFieldName } from '../../../../model/prebuilt_rule_upgrade/fields'; type FieldDiffEntries = Array< [ 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 44a5ac40e5dc5..0cb7ce3982868 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 @@ -8,7 +8,7 @@ import React from 'react'; import { FieldFormWrapper } from './field_form_wrapper'; import { NameEdit, nameSchema } from './fields/name'; -import type { UpgradeableCommonFields } from '../../../../model/prebuilt_rule_upgrade/types'; +import type { UpgradeableCommonFields } from '../../../../model/prebuilt_rule_upgrade/fields'; interface CommonRuleFieldEditProps { fieldName: UpgradeableCommonFields; } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/custom_query_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/custom_query_rule_field_edit.tsx index 004c94ed8dc48..3dc3cc5b87023 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/custom_query_rule_field_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/custom_query_rule_field_edit.tsx @@ -13,7 +13,7 @@ import { kqlQuerySerializer, kqlQueryDeserializer, } from './fields/kql_query'; -import type { UpgradeableCustomQueryFields } from '../../../../model/prebuilt_rule_upgrade/types'; +import type { UpgradeableCustomQueryFields } from '../../../../model/prebuilt_rule_upgrade/fields'; interface CustomQueryRuleFieldEditProps { fieldName: UpgradeableCustomQueryFields; 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/final_edit.tsx index 55ccf34f97a63..1696714e36531 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/final_edit.tsx @@ -23,8 +23,8 @@ import type { UpgradeableThreatMatchFields, UpgradeableThresholdFields, UpgradeableNewTermsFields, -} from '../../../../model/prebuilt_rule_upgrade/types'; -import { isCommonFieldName } from '../../../../model/prebuilt_rule_upgrade/constants'; +} from '../../../../model/prebuilt_rule_upgrade/fields'; +import { isCommonFieldName } from '../../../../model/prebuilt_rule_upgrade/fields'; interface FinalEditProps { fieldName: UpgradeableDiffableFields; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/new_terms_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/new_terms_rule_field_edit.tsx index ad42397ef4c62..183200aef1c43 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/new_terms_rule_field_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/new_terms_rule_field_edit.tsx @@ -13,7 +13,7 @@ import { kqlQuerySerializer, kqlQueryDeserializer, } from './fields/kql_query'; -import type { UpgradeableNewTermsFields } from '../../../../model/prebuilt_rule_upgrade/types'; +import type { UpgradeableNewTermsFields } from '../../../../model/prebuilt_rule_upgrade/fields'; interface NewTermsRuleFieldEditProps { fieldName: UpgradeableNewTermsFields; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/saved_query_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/saved_query_rule_field_edit.tsx index ebc0a784faf91..fa573e6339e9f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/saved_query_rule_field_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/saved_query_rule_field_edit.tsx @@ -13,7 +13,7 @@ import { kqlQuerySerializer, kqlQueryDeserializer, } from './fields/kql_query'; -import type { UpgradeableSavedQueryFields } from '../../../../model/prebuilt_rule_upgrade/types'; +import type { UpgradeableSavedQueryFields } from '../../../../model/prebuilt_rule_upgrade/fields'; interface SavedQueryRuleFieldEditProps { fieldName: UpgradeableSavedQueryFields; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threat_match_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threat_match_rule_field_edit.tsx index 831b85055660d..5f2adbb113fd5 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threat_match_rule_field_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threat_match_rule_field_edit.tsx @@ -13,7 +13,7 @@ import { kqlQuerySerializer, kqlQueryDeserializer, } from './fields/kql_query'; -import type { UpgradeableThreatMatchFields } from '../../../../model/prebuilt_rule_upgrade/types'; +import type { UpgradeableThreatMatchFields } from '../../../../model/prebuilt_rule_upgrade/fields'; interface ThreatMatchRuleFieldEditProps { fieldName: UpgradeableThreatMatchFields; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threshold_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threshold_rule_field_edit.tsx index d4094777865ab..4975ca49205e7 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threshold_rule_field_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/threshold_rule_field_edit.tsx @@ -13,7 +13,7 @@ import { kqlQuerySerializer, kqlQueryDeserializer, } from './fields/kql_query'; -import type { UpgradeableThresholdFields } from '../../../../model/prebuilt_rule_upgrade/types'; +import type { UpgradeableThresholdFields } from '../../../../model/prebuilt_rule_upgrade/fields'; interface ThresholdRuleFieldEditProps { fieldName: UpgradeableThresholdFields; 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/final_side/final_side.tsx index 80e6881da01c0..b1522fe464253 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/final_side/final_side.tsx @@ -13,7 +13,7 @@ import * as i18n from './translations'; import { FinalReadOnly } from '../final_readonly/final_readonly'; import { FinalEdit } from '../final_edit/final_edit'; import { FinalSideMode } from './constants'; -import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/types'; +import type { UpgradeableDiffableFields } from '../../../../model/prebuilt_rule_upgrade/fields'; interface FinalSideProps { fieldName: UpgradeableDiffableFields; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/constants.ts deleted file mode 100644 index 6f25272e0434b..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/constants.ts +++ /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 { DiffableCommonFields } from '../../../../../common/api/detection_engine'; -import type { NonUpgradeableDiffableFields } from './types'; - -export const NON_UPGRADEABLE_DIFFABLE_FIELDS = [ - 'author', - 'license', - 'rule_id', - 'type', - 'version', -] as const; - -export const COMMON_FIELD_NAMES = DiffableCommonFields.keyof().options; - -export function isCommonFieldName(fieldName: string): fieldName is keyof DiffableCommonFields { - return (COMMON_FIELD_NAMES as string[]).includes(fieldName); -} - -export function isNonUpgradeableFieldName( - fieldName: string -): fieldName is NonUpgradeableDiffableFields { - return (NON_UPGRADEABLE_DIFFABLE_FIELDS as Readonly).includes(fieldName); -} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/types.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/fields.ts similarity index 73% rename from x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/types.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/fields.ts index d74e0fc020cb4..c384b48a79d4f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/types.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/prebuilt_rule_upgrade/fields.ts @@ -5,9 +5,8 @@ * 2.0. */ -import type { NON_UPGRADEABLE_DIFFABLE_FIELDS } from './constants'; +import { DiffableCommonFields } from '../../../../../common/api/detection_engine'; import type { - DiffableCommonFields, DiffableCustomQueryFields, DiffableEqlFields, DiffableEsqlFields, @@ -61,3 +60,23 @@ export type UpgradeableNewTermsFields = Exclude< keyof DiffableNewTermsFields, NonUpgradeableDiffableFields >; + +export const NON_UPGRADEABLE_DIFFABLE_FIELDS = [ + 'author', + 'license', + 'rule_id', + 'type', + 'version', +] as const; + +export const COMMON_FIELD_NAMES = DiffableCommonFields.keyof().options; + +export function isCommonFieldName(fieldName: string): fieldName is keyof DiffableCommonFields { + return (COMMON_FIELD_NAMES as string[]).includes(fieldName); +} + +export function isNonUpgradeableFieldName( + fieldName: string +): fieldName is NonUpgradeableDiffableFields { + return (NON_UPGRADEABLE_DIFFABLE_FIELDS as Readonly).includes(fieldName); +} From 9749c8c2a9f61eb54f194d70cde266e386a76d59 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Mon, 14 Oct 2024 16:18:10 +0200 Subject: [PATCH 37/40] Make a separate type for field components --- .../three_way_diff/final_edit/field_form_wrapper.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx index 51c9c5397dd38..a2cca120d4de7 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx @@ -17,12 +17,14 @@ import { useFinalEditContext } from './final_edit_context'; import { useDiffableRuleContext } from '../diffable_rule_context'; import * as i18n from '../translations'; +type FieldComponent = React.ComponentType<{ + finalDiffableRule: DiffableRule; + setValidity: (isValid: boolean) => void; + setFieldValue: (fieldName: string, fieldValue: unknown) => void; +}>; + interface FieldFormWrapperProps { - component: React.ComponentType<{ - finalDiffableRule: DiffableRule; - setValidity: (isValid: boolean) => void; - setFieldValue: (fieldName: string, fieldValue: unknown) => void; - }>; + component: FieldComponent; fieldFormSchema: FormSchema; deserializer?: (fieldValue: FormData, finalDiffableRule: DiffableRule) => FormData; serializer?: (formData: FormData) => FormData; From 048dfac7c1ec77b92720297637e09bedf1d04457 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Mon, 14 Oct 2024 16:25:52 +0200 Subject: [PATCH 38/40] Add explicit field component return types --- .../three_way_diff/final_edit/fields/kql_query.tsx | 6 +++++- .../rule_details/three_way_diff/final_edit/fields/name.tsx | 2 +- 2 files changed, 6 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/kql_query.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx index e57c28a99ad4e..abd3c93550694 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/kql_query.tsx @@ -52,7 +52,11 @@ interface KqlQueryEditProps { setFieldValue: (fieldName: string, fieldValue: unknown) => void; } -export function KqlQueryEdit({ finalDiffableRule, setValidity, setFieldValue }: KqlQueryEditProps) { +export function KqlQueryEdit({ + finalDiffableRule, + setValidity, + setFieldValue, +}: KqlQueryEditProps): JSX.Element { const defaultIndexPattern = useDefaultIndexPattern(); const indexPatternParameters = getUseRuleIndexPatternParameters( finalDiffableRule, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/name.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/name.tsx index a789c58574495..10ae6cffbe50d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/name.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/name.tsx @@ -13,7 +13,7 @@ import type { RuleName } from '../../../../../../../../common/api/detection_engi export const nameSchema = { name: schema.name } as FormSchema<{ name: RuleName }>; -export function NameEdit() { +export function NameEdit(): JSX.Element { return ( Date: Mon, 14 Oct 2024 17:22:20 +0200 Subject: [PATCH 39/40] Refactor passing data via local context --- .../final_edit/field_form_wrapper.tsx | 5 +- .../three_way_diff/final_edit/final_edit.tsx | 29 +++-------- .../final_edit/final_edit_context.tsx | 35 ------------- .../final_readonly/final_readonly.tsx | 8 ++- .../three_way_diff/final_side/final_side.tsx | 29 +++++++---- .../final_side/final_side_context.tsx | 50 +++++++++++++++++++ 6 files changed, 80 insertions(+), 76 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/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_edit/field_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx index a2cca120d4de7..b4a53ee7aea0a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/field_form_wrapper.tsx @@ -13,7 +13,7 @@ import type { DiffableAllFields, DiffableRule, } from '../../../../../../../common/api/detection_engine'; -import { useFinalEditContext } from './final_edit_context'; +import { useFinalSideContext } from '../final_side/final_side_context'; import { useDiffableRuleContext } from '../diffable_rule_context'; import * as i18n from '../translations'; @@ -45,8 +45,7 @@ export function FieldFormWrapper({ deserializer, serializer, }: FieldFormWrapperProps) { - const { fieldName, setReadOnlyMode } = useFinalEditContext(); - + const { fieldName, setReadOnlyMode } = useFinalSideContext(); const { finalDiffableRule, setRuleFieldResolvedValue } = useDiffableRuleContext(); const deserialize = useCallback( 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/final_edit.tsx index 1696714e36531..698d138208d70 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/final_edit.tsx @@ -6,8 +6,6 @@ */ import React from 'react'; -import type { DiffableRuleTypes } from '../../../../../../../common/api/detection_engine'; -import { FinalEditContextProvider } from './final_edit_context'; import { assertUnreachable } from '../../../../../../../common/utility_types'; import { useDiffableRuleContext } from '../diffable_rule_context'; import { CommonRuleFieldEdit } from './common_rule_field_edit'; @@ -17,7 +15,6 @@ 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 { - UpgradeableDiffableFields, UpgradeableCustomQueryFields, UpgradeableSavedQueryFields, UpgradeableThreatMatchFields, @@ -25,33 +22,19 @@ import type { UpgradeableNewTermsFields, } from '../../../../model/prebuilt_rule_upgrade/fields'; import { isCommonFieldName } from '../../../../model/prebuilt_rule_upgrade/fields'; +import { useFinalSideContext } from '../final_side/final_side_context'; -interface FinalEditProps { - fieldName: UpgradeableDiffableFields; - setReadOnlyMode: () => void; -} - -export function FinalEdit({ fieldName, setReadOnlyMode }: FinalEditProps) { +export function FinalEdit() { const { finalDiffableRule } = useDiffableRuleContext(); + const { type } = finalDiffableRule; - return ( - - - - ); -} - -interface FinalEditFieldProps { - fieldName: UpgradeableDiffableFields; - ruleType: DiffableRuleTypes; -} + const { fieldName } = useFinalSideContext(); -function FieldEdit({ fieldName, ruleType }: FinalEditFieldProps) { if (isCommonFieldName(fieldName)) { return ; } - switch (ruleType) { + switch (type) { case 'query': return ; case 'saved_query': @@ -69,6 +52,6 @@ function FieldEdit({ fieldName, ruleType }: FinalEditFieldProps) { case 'new_terms': return ; default: - return assertUnreachable(ruleType); + return assertUnreachable(type); } } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx deleted file mode 100644 index f3505235e1332..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/final_edit_context.tsx +++ /dev/null @@ -1,35 +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 } from 'react'; -import { invariant } from '../../../../../../../common/utils/invariant'; - -interface FinalEditContextType { - fieldName: string; - setReadOnlyMode: () => void; -} - -const FinalEditContext = createContext(null); - -interface FinalEditContextProviderProps { - value: FinalEditContextType; -} - -export function FinalEditContextProvider({ - children, - value, -}: PropsWithChildren) { - return {children}; -} - -export function useFinalEditContext() { - const context = useContext(FinalEditContext); - - invariant(context !== null, 'useFinalEditContext must be used inside a FinalEditContextProvider'); - - return context; -} 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/final_readonly.tsx index 909663b4e8390..21b8475fe3002 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/final_readonly.tsx @@ -9,13 +9,11 @@ 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'; -interface FinalReadOnlyProps { - fieldName: string; - setEditMode: () => void; -} +export function FinalReadOnly() { + const { setEditMode, fieldName } = useFinalSideContext(); -export function FinalReadOnly({ fieldName, setEditMode }: FinalReadOnlyProps) { return ( <> 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/final_side/final_side.tsx index b1522fe464253..30e3f4461195a 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/final_side/final_side.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useCallback } from 'react'; +import React from 'react'; import { EuiTitle } from '@elastic/eui'; import { SideHeader } from '../components/side_header'; import { FinalSideHelpInfo } from './final_side_help_info'; @@ -14,16 +14,14 @@ import { FinalReadOnly } from '../final_readonly/final_readonly'; import { FinalEdit } from '../final_edit/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 { fieldName: UpgradeableDiffableFields; } export function FinalSide({ fieldName }: FinalSideProps): JSX.Element { - const [mode, setMode] = React.useState(FinalSideMode.READONLY); // TODO: Replace with state from context - const setReadOnlyMode = useCallback(() => setMode(FinalSideMode.READONLY), []); - const setEditMode = useCallback(() => setMode(FinalSideMode.EDIT), []); - return ( <> @@ -34,11 +32,22 @@ export function FinalSide({ fieldName }: FinalSideProps): JSX.Element { - {mode === FinalSideMode.EDIT ? ( - - ) : ( - - )} + + + ); } + +function FinalSideContent(): JSX.Element { + const { mode } = useFinalSideContext(); + + switch (mode) { + case FinalSideMode.READONLY: + return ; + 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/final_side/final_side_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side_context.tsx new file mode 100644 index 0000000000000..6beb0535e5e27 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_side/final_side_context.tsx @@ -0,0 +1,50 @@ +/* + * 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 './constants'; +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; +} + +export function FinalSideContextProvider({ + children, + fieldName, +}: PropsWithChildren) { + const [mode, setMode] = React.useState(FinalSideMode.READONLY); + 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; +} From 655d1265b2d6fffc586278ffd738c45a89e5dc55 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Mon, 14 Oct 2024 17:24:12 +0200 Subject: [PATCH 40/40] Remove duplicated `RuleUpgradeState` type --- .../use_prebuilt_rules_upgrade_state.ts | 11 ----------- 1 file changed, 11 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 ad64b26be0f28..d44f9738b1fd6 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 @@ -21,17 +21,6 @@ import { } from '../../../../../../common/api/detection_engine'; import { convertRuleToDiffable } from '../../../../../../common/detection_engine/prebuilt_rules/diff/convert_rule_to_diffable'; -export interface RuleUpgradeState extends RuleUpgradeInfoForReview { - /** - * Rule containing desired values users expect to see in the upgraded rule. - */ - finalRule: DiffableRule; - /** - * Indicates whether there are conflicts blocking rule upgrading. - */ - hasUnresolvedConflicts: boolean; -} - type RuleResolvedConflicts = Partial; type RulesResolvedConflicts = Record;