From 53f20972d082cde1af8e61a21442cde9bfb12778 Mon Sep 17 00:00:00 2001 From: Candace Park <56409205+parkiino@users.noreply.github.com> Date: Tue, 23 Mar 2021 15:23:58 -0400 Subject: [PATCH] [Security Solution][Endpoint][Admin] Refactor policy details protections (#94970) --- .../public/management/pages/policy/types.ts | 6 + .../components/protection_radio.tsx | 91 +++++ .../components/protection_switch.tsx | 100 ++++++ .../policy_forms/components/radio_buttons.tsx | 96 +++++ .../supported_version.tsx | 2 +- .../components/user_notification.tsx | 170 +++++++++ .../view/policy_forms/protections/malware.tsx | 327 +----------------- .../policy_forms/protections/ransomware.tsx | 308 +---------------- .../translations/translations/ja-JP.json | 10 - .../translations/translations/zh-CN.json | 10 - 10 files changed, 488 insertions(+), 632 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_radio.tsx create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_switch.tsx create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/radio_buttons.tsx rename x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/{protections => components}/supported_version.tsx (91%) create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/user_notification.tsx diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/types.ts b/x-pack/plugins/security_solution/public/management/pages/policy/types.ts index f7e054729c7b9..b2b95e2765bd8 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/types.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/types.ts @@ -120,6 +120,12 @@ export type RansomwareProtectionOSes = KeysByValueCriteria< { ransomware: ProtectionFields } >; +export type PolicyProtection = + | keyof Pick + | keyof Pick; + +export type MacPolicyProtection = keyof Pick; + export interface GetPolicyListResponse extends GetPackagePoliciesResponse { items: PolicyData[]; } diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_radio.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_radio.tsx new file mode 100644 index 0000000000000..8394b557207af --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_radio.tsx @@ -0,0 +1,91 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useMemo } from 'react'; +import { useDispatch } from 'react-redux'; +import { cloneDeep } from 'lodash'; +import { htmlIdGenerator, EuiRadio } from '@elastic/eui'; +import { + ImmutableArray, + ProtectionModes, + UIPolicyConfig, +} from '../../../../../../../common/endpoint/types'; +import { MacPolicyProtection, PolicyProtection } from '../../../types'; +import { usePolicyDetailsSelector } from '../../policy_hooks'; +import { policyConfig } from '../../../store/policy_details/selectors'; +import { AppAction } from '../../../../../../common/store/actions'; +import { useLicense } from '../../../../../../common/hooks/use_license'; + +export const ProtectionRadio = React.memo( + ({ + protection, + protectionMode, + osList, + label, + }: { + protection: PolicyProtection; + protectionMode: ProtectionModes; + osList: ImmutableArray>; + label: string; + }) => { + const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); + const dispatch = useDispatch<(action: AppAction) => void>(); + const radioButtonId = useMemo(() => htmlIdGenerator()(), []); + const selected = policyDetailsConfig && policyDetailsConfig.windows[protection].mode; + const isPlatinumPlus = useLicense().isPlatinumPlus(); + + const handleRadioChange = useCallback(() => { + if (policyDetailsConfig) { + const newPayload = cloneDeep(policyDetailsConfig); + for (const os of osList) { + if (os === 'windows') { + newPayload[os][protection].mode = protectionMode; + } else if (os === 'mac') { + newPayload[os][protection as MacPolicyProtection].mode = protectionMode; + } + if (isPlatinumPlus) { + if (os === 'windows') { + if (protectionMode === ProtectionModes.prevent) { + newPayload[os].popup[protection].enabled = true; + } else { + newPayload[os].popup[protection].enabled = false; + } + } else if (os === 'mac') { + if (protectionMode === ProtectionModes.prevent) { + newPayload[os].popup[protection as MacPolicyProtection].enabled = true; + } else { + newPayload[os].popup[protection as MacPolicyProtection].enabled = false; + } + } + } + } + dispatch({ + type: 'userChangedPolicyConfig', + payload: { policyConfig: newPayload }, + }); + } + }, [dispatch, protectionMode, policyDetailsConfig, isPlatinumPlus, osList, protection]); + + /** + * Passing an arbitrary id because EuiRadio + * requires an id if label is passed + */ + + return ( + + ); + } +); + +ProtectionRadio.displayName = 'ProtectionRadio'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_switch.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_switch.tsx new file mode 100644 index 0000000000000..cbe118e8dfa36 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_switch.tsx @@ -0,0 +1,100 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback } from 'react'; +import { useDispatch } from 'react-redux'; +import { i18n } from '@kbn/i18n'; +import { EuiSwitch } from '@elastic/eui'; +import { cloneDeep } from 'lodash'; +import { useLicense } from '../../../../../../common/hooks/use_license'; +import { policyConfig } from '../../../store/policy_details/selectors'; +import { usePolicyDetailsSelector } from '../../policy_hooks'; +import { AppAction } from '../../../../../../common/store/actions'; +import { + ImmutableArray, + ProtectionModes, + UIPolicyConfig, +} from '../../../../../../../common/endpoint/types'; +import { PolicyProtection, MacPolicyProtection } from '../../../types'; + +export const ProtectionSwitch = React.memo( + ({ + protection, + osList, + }: { + protection: PolicyProtection; + osList: ImmutableArray>; + }) => { + const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); + const isPlatinumPlus = useLicense().isPlatinumPlus(); + const dispatch = useDispatch<(action: AppAction) => void>(); + const selected = policyDetailsConfig && policyDetailsConfig.windows[protection].mode; + + const handleSwitchChange = useCallback( + (event) => { + if (policyDetailsConfig) { + const newPayload = cloneDeep(policyDetailsConfig); + if (event.target.checked === false) { + for (const os of osList) { + if (os === 'windows') { + newPayload[os][protection].mode = ProtectionModes.off; + } else if (os === 'mac') { + newPayload[os][protection as MacPolicyProtection].mode = ProtectionModes.off; + } + if (isPlatinumPlus) { + if (os === 'windows') { + newPayload[os].popup[protection].enabled = event.target.checked; + } else if (os === 'mac') { + newPayload[os].popup[protection as MacPolicyProtection].enabled = + event.target.checked; + } + } + } + } else { + for (const os of osList) { + if (os === 'windows') { + newPayload[os][protection].mode = ProtectionModes.prevent; + } else if (os === 'mac') { + newPayload[os][protection as MacPolicyProtection].mode = ProtectionModes.prevent; + } + if (isPlatinumPlus) { + if (os === 'windows') { + newPayload[os].popup[protection].enabled = event.target.checked; + } else if (os === 'mac') { + newPayload[os].popup[protection as MacPolicyProtection].enabled = + event.target.checked; + } + } + } + } + dispatch({ + type: 'userChangedPolicyConfig', + payload: { policyConfig: newPayload }, + }); + } + }, + [dispatch, policyDetailsConfig, isPlatinumPlus, protection, osList] + ); + + return ( + + ); + } +); + +ProtectionSwitch.displayName = 'ProtectionSwitch'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/radio_buttons.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/radio_buttons.tsx new file mode 100644 index 0000000000000..793c24a0c4d0c --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/radio_buttons.tsx @@ -0,0 +1,96 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useMemo } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import styled from 'styled-components'; +import { EuiSpacer, EuiFlexItem, EuiFlexGroup } from '@elastic/eui'; +import { + Immutable, + ImmutableArray, + ProtectionModes, + UIPolicyConfig, +} from '../../../../../../../common/endpoint/types'; +import { PolicyProtection } from '../../../types'; +import { ConfigFormHeading } from '../../components/config_form'; +import { ProtectionRadio } from './protection_radio'; + +export const RadioFlexGroup = styled(EuiFlexGroup)` + .no-right-margin-radio { + margin-right: 0; + } + .no-horizontal-margin-radio { + margin: ${(props) => props.theme.eui.ruleMargins.marginSmall} 0; + } +`; + +export const RadioButtons = React.memo( + ({ + protection, + osList, + }: { + protection: PolicyProtection; + osList: ImmutableArray>; + }) => { + const radios: Immutable< + Array<{ + id: ProtectionModes; + label: string; + }> + > = useMemo(() => { + return [ + { + id: ProtectionModes.detect, + label: i18n.translate('xpack.securitySolution.endpoint.policy.details.detect', { + defaultMessage: 'Detect', + }), + }, + { + id: ProtectionModes.prevent, + label: i18n.translate('xpack.securitySolution.endpoint.policy.details.prevent', { + defaultMessage: 'Prevent', + }), + }, + ]; + }, []); + + return ( + <> + + + + + + + + + + + + + + ); + } +); + +RadioButtons.displayName = 'RadioButtons'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/supported_version.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/supported_version.tsx similarity index 91% rename from x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/supported_version.tsx rename to x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/supported_version.tsx index 5985a5fe03ec3..b8418004206b9 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/supported_version.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/supported_version.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiText } from '@elastic/eui'; -import { popupVersionsMap } from './popup_options_to_versions'; +import { popupVersionsMap } from '../protections/popup_options_to_versions'; export const SupportedVersionNotice = ({ optionName }: { optionName: string }) => { const version = popupVersionsMap.get(optionName); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/user_notification.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/user_notification.tsx new file mode 100644 index 0000000000000..def9e78e994b0 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/user_notification.tsx @@ -0,0 +1,170 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback } from 'react'; +import { useDispatch } from 'react-redux'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { cloneDeep } from 'lodash'; +import { + EuiSpacer, + EuiFlexItem, + EuiFlexGroup, + EuiCheckbox, + EuiIconTip, + EuiText, + EuiTextArea, +} from '@elastic/eui'; +import { + ImmutableArray, + ProtectionModes, + UIPolicyConfig, +} from '../../../../../../../common/endpoint/types'; +import { PolicyProtection, MacPolicyProtection } from '../../../types'; +import { ConfigFormHeading } from '../../components/config_form'; +import { usePolicyDetailsSelector } from '../../policy_hooks'; +import { policyConfig } from '../../../store/policy_details/selectors'; +import { AppAction } from '../../../../../../common/store/actions'; +import { SupportedVersionNotice } from './supported_version'; + +export const UserNotification = React.memo( + ({ + protection, + osList, + }: { + protection: PolicyProtection; + osList: ImmutableArray>; + }) => { + const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); + const dispatch = useDispatch<(action: AppAction) => void>(); + const selected = policyDetailsConfig && policyDetailsConfig.windows[protection].mode; + const userNotificationSelected = + policyDetailsConfig && policyDetailsConfig.windows.popup[protection].enabled; + const userNotificationMessage = + policyDetailsConfig && policyDetailsConfig.windows.popup[protection].message; + + const handleUserNotificationCheckbox = useCallback( + (event) => { + if (policyDetailsConfig) { + const newPayload = cloneDeep(policyDetailsConfig); + for (const os of osList) { + if (os === 'windows') { + newPayload[os].popup[protection].enabled = event.target.checked; + } else if (os === 'mac') { + newPayload[os].popup[protection as MacPolicyProtection].enabled = + event.target.checked; + } + } + dispatch({ + type: 'userChangedPolicyConfig', + payload: { policyConfig: newPayload }, + }); + } + }, + [policyDetailsConfig, dispatch, protection, osList] + ); + + const handleCustomUserNotification = useCallback( + (event) => { + if (policyDetailsConfig) { + const newPayload = cloneDeep(policyDetailsConfig); + for (const os of osList) { + if (os === 'windows') { + newPayload[os].popup[protection].message = event.target.value; + } else if (os === 'mac') { + newPayload[os].popup[protection as MacPolicyProtection].message = event.target.value; + } + } + dispatch({ + type: 'userChangedPolicyConfig', + payload: { policyConfig: newPayload }, + }); + } + }, + [policyDetailsConfig, dispatch, protection, osList] + ); + + return ( + <> + + + + + + + + {userNotificationSelected && ( + <> + + + + +

+ +

+
+
+ + + + + + + } + /> + +
+ + + + )} + + ); + } +); + +UserNotification.displayName = 'UserNotification'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx index a5be095abfc59..03cd587ca7e5c 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx @@ -5,333 +5,29 @@ * 2.0. */ -import React, { useCallback, useMemo } from 'react'; -import { useDispatch } from 'react-redux'; +import React from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { - EuiCallOut, - EuiCheckbox, - EuiRadio, - EuiSpacer, - EuiSwitch, - EuiText, - EuiTextArea, - htmlIdGenerator, - EuiFlexGroup, - EuiFlexItem, - EuiIconTip, -} from '@elastic/eui'; -import { cloneDeep } from 'lodash'; -import styled from 'styled-components'; +import { EuiCallOut, EuiSpacer } from '@elastic/eui'; import { APP_ID } from '../../../../../../../common/constants'; import { SecurityPageName } from '../../../../../../app/types'; -import { - Immutable, - OperatingSystem, - ProtectionModes, -} from '../../../../../../../common/endpoint/types'; +import { Immutable, OperatingSystem } from '../../../../../../../common/endpoint/types'; import { MalwareProtectionOSes, OS } from '../../../types'; -import { ConfigForm, ConfigFormHeading } from '../../components/config_form'; -import { policyConfig } from '../../../store/policy_details/selectors'; -import { usePolicyDetailsSelector } from '../../policy_hooks'; +import { ConfigForm } from '../../components/config_form'; import { LinkToApp } from '../../../../../../common/components/endpoint/link_to_app'; import { useLicense } from '../../../../../../common/hooks/use_license'; -import { AppAction } from '../../../../../../common/store/actions'; -import { SupportedVersionNotice } from './supported_version'; - -export const RadioFlexGroup = styled(EuiFlexGroup)` - .no-right-margin-radio { - margin-right: 0; - } - .no-horizontal-margin-radio { - margin: ${(props) => props.theme.eui.ruleMargins.marginSmall} 0; - } -`; - -const OSes: Immutable = [OS.windows, OS.mac]; -const protection = 'malware'; - -const ProtectionRadio = React.memo( - ({ protectionMode, label }: { protectionMode: ProtectionModes; label: string }) => { - const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); - const dispatch = useDispatch<(action: AppAction) => void>(); - const radioButtonId = useMemo(() => htmlIdGenerator()(), []); - // currently just taking windows.malware, but both windows.malware and mac.malware should be the same value - const selected = policyDetailsConfig && policyDetailsConfig.windows.malware.mode; - const isPlatinumPlus = useLicense().isPlatinumPlus(); - - const handleRadioChange = useCallback(() => { - if (policyDetailsConfig) { - const newPayload = cloneDeep(policyDetailsConfig); - for (const os of OSes) { - newPayload[os][protection].mode = protectionMode; - if (isPlatinumPlus) { - if (protectionMode === ProtectionModes.prevent) { - newPayload[os].popup[protection].enabled = true; - } else { - newPayload[os].popup[protection].enabled = false; - } - } - } - dispatch({ - type: 'userChangedPolicyConfig', - payload: { policyConfig: newPayload }, - }); - } - }, [dispatch, protectionMode, policyDetailsConfig, isPlatinumPlus]); - - /** - * Passing an arbitrary id because EuiRadio - * requires an id if label is passed - */ - - return ( - - ); - } -); - -ProtectionRadio.displayName = 'ProtectionRadio'; +import { RadioButtons } from '../components/radio_buttons'; +import { UserNotification } from '../components/user_notification'; +import { ProtectionSwitch } from '../components/protection_switch'; /** The Malware Protections form for policy details * which will configure for all relevant OSes. */ export const MalwareProtections = React.memo(() => { - const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); - const dispatch = useDispatch<(action: AppAction) => void>(); - // currently just taking windows.malware, but both windows.malware and mac.malware should be the same value - const selected = policyDetailsConfig && policyDetailsConfig.windows.malware.mode; - const userNotificationSelected = - policyDetailsConfig && policyDetailsConfig.windows.popup.malware.enabled; - const userNotificationMessage = - policyDetailsConfig && policyDetailsConfig.windows.popup.malware.message; + const OSes: Immutable = [OS.windows, OS.mac]; + const protection = 'malware'; const isPlatinumPlus = useLicense().isPlatinumPlus(); - const radios: Immutable< - Array<{ - id: ProtectionModes; - label: string; - protection: 'malware'; - }> - > = useMemo(() => { - return [ - { - id: ProtectionModes.detect, - label: i18n.translate('xpack.securitySolution.endpoint.policy.details.detect', { - defaultMessage: 'Detect', - }), - protection: 'malware', - }, - { - id: ProtectionModes.prevent, - label: i18n.translate('xpack.securitySolution.endpoint.policy.details.prevent', { - defaultMessage: 'Prevent', - }), - protection: 'malware', - }, - ]; - }, []); - - const handleSwitchChange = useCallback( - (event) => { - if (policyDetailsConfig) { - const newPayload = cloneDeep(policyDetailsConfig); - if (event.target.checked === false) { - for (const os of OSes) { - newPayload[os][protection].mode = ProtectionModes.off; - if (isPlatinumPlus) { - newPayload[os].popup[protection].enabled = event.target.checked; - } - } - } else { - for (const os of OSes) { - newPayload[os][protection].mode = ProtectionModes.prevent; - if (isPlatinumPlus) { - newPayload[os].popup[protection].enabled = event.target.checked; - } - } - } - dispatch({ - type: 'userChangedPolicyConfig', - payload: { policyConfig: newPayload }, - }); - } - }, - [dispatch, policyDetailsConfig, isPlatinumPlus] - ); - - const handleUserNotificationCheckbox = useCallback( - (event) => { - if (policyDetailsConfig) { - const newPayload = cloneDeep(policyDetailsConfig); - for (const os of OSes) { - newPayload[os].popup[protection].enabled = event.target.checked; - } - dispatch({ - type: 'userChangedPolicyConfig', - payload: { policyConfig: newPayload }, - }); - } - }, - [policyDetailsConfig, dispatch] - ); - - const handleCustomUserNotification = useCallback( - (event) => { - if (policyDetailsConfig) { - const newPayload = cloneDeep(policyDetailsConfig); - for (const os of OSes) { - newPayload[os].popup[protection].message = event.target.value; - } - dispatch({ - type: 'userChangedPolicyConfig', - payload: { policyConfig: newPayload }, - }); - } - }, - [policyDetailsConfig, dispatch] - ); - - const radioButtons = useMemo(() => { - return ( - <> - - - - - - - - - - - - - {isPlatinumPlus && ( - <> - - - - - - - - - )} - {isPlatinumPlus && userNotificationSelected && ( - <> - - - - -

- -

-
-
- - - - - - - } - /> - -
- - - - )} - - ); - }, [ - radios, - selected, - isPlatinumPlus, - handleUserNotificationCheckbox, - userNotificationSelected, - userNotificationMessage, - handleCustomUserNotification, - ]); - - const protectionSwitch = useMemo(() => { - return ( - - ); - }, [handleSwitchChange, selected]); - return ( { })} supportedOss={[OperatingSystem.WINDOWS, OperatingSystem.MAC]} dataTestSubj="malwareProtectionsForm" - rightCorner={protectionSwitch} + rightCorner={} > - {radioButtons} + + {isPlatinumPlus && } = [OS.windows]; -const protection = 'ransomware'; - -const ProtectionRadio = React.memo( - ({ protectionMode, label }: { protectionMode: ProtectionModes; label: string }) => { - const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); - const dispatch = useDispatch<(action: AppAction) => void>(); - const radioButtonId = useMemo(() => htmlIdGenerator()(), []); - const selected = policyDetailsConfig && policyDetailsConfig.windows.ransomware.mode; - - const handleRadioChange: EuiRadioProps['onChange'] = useCallback(() => { - if (policyDetailsConfig) { - const newPayload = cloneDeep(policyDetailsConfig); - for (const os of OSes) { - newPayload[os][protection].mode = protectionMode; - if (protectionMode === ProtectionModes.prevent) { - newPayload[os].popup[protection].enabled = true; - } else { - newPayload[os].popup[protection].enabled = false; - } - } - dispatch({ - type: 'userChangedPolicyConfig', - payload: { policyConfig: newPayload }, - }); - } - }, [dispatch, protectionMode, policyDetailsConfig]); - - /** - * Passing an arbitrary id because EuiRadio - * requires an id if label is passed - */ - - return ( - - ); - } -); - -ProtectionRadio.displayName = 'ProtectionRadio'; +import { RadioButtons } from '../components/radio_buttons'; +import { UserNotification } from '../components/user_notification'; +import { ProtectionSwitch } from '../components/protection_switch'; /** The Ransomware Protections form for policy details * which will configure for all relevant OSes. */ export const Ransomware = React.memo(() => { - const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); - const dispatch = useDispatch<(action: AppAction) => void>(); - const selected = policyDetailsConfig && policyDetailsConfig.windows.ransomware.mode; - const userNotificationSelected = - policyDetailsConfig && policyDetailsConfig.windows.popup.ransomware.enabled; - const userNotificationMessage = - policyDetailsConfig && policyDetailsConfig.windows.popup.ransomware.message; - - const radios: Immutable< - Array<{ - id: ProtectionModes; - label: string; - protection: 'ransomware'; - }> - > = useMemo(() => { - return [ - { - id: ProtectionModes.detect, - label: i18n.translate('xpack.securitySolution.endpoint.policy.details.detect', { - defaultMessage: 'Detect', - }), - protection: 'ransomware', - }, - { - id: ProtectionModes.prevent, - label: i18n.translate('xpack.securitySolution.endpoint.policy.details.prevent', { - defaultMessage: 'Prevent', - }), - protection: 'ransomware', - }, - ]; - }, []); - - const handleSwitchChange: EuiSwitchProps['onChange'] = useCallback( - (event) => { - if (policyDetailsConfig) { - const newPayload = cloneDeep(policyDetailsConfig); - if (event.target.checked === false) { - for (const os of OSes) { - newPayload[os][protection].mode = ProtectionModes.off; - newPayload[os].popup[protection].enabled = event.target.checked; - } - } else { - for (const os of OSes) { - newPayload[os][protection].mode = ProtectionModes.prevent; - newPayload[os].popup[protection].enabled = event.target.checked; - } - } - dispatch({ - type: 'userChangedPolicyConfig', - payload: { policyConfig: newPayload }, - }); - } - }, - [dispatch, policyDetailsConfig] - ); - - const handleUserNotificationCheckbox: EuiCheckboxProps['onChange'] = useCallback( - (event) => { - if (policyDetailsConfig) { - const newPayload = cloneDeep(policyDetailsConfig); - for (const os of OSes) { - newPayload[os].popup[protection].enabled = event.target.checked; - } - dispatch({ - type: 'userChangedPolicyConfig', - payload: { policyConfig: newPayload }, - }); - } - }, - [policyDetailsConfig, dispatch] - ); - - const handleCustomUserNotification = useCallback( - (event) => { - if (policyDetailsConfig) { - const newPayload = cloneDeep(policyDetailsConfig); - for (const os of OSes) { - newPayload[os].popup[protection].message = event.target.value; - } - dispatch({ - type: 'userChangedPolicyConfig', - payload: { policyConfig: newPayload }, - }); - } - }, - [policyDetailsConfig, dispatch] - ); - - const radioButtons = useMemo(() => { - return ( - <> - - - - - - - - - - - - - - - - - - - - {userNotificationSelected && ( - <> - - - - -

- -

-
-
- - - - - - - } - /> - -
- - - - )} - - ); - }, [ - radios, - selected, - handleUserNotificationCheckbox, - userNotificationSelected, - userNotificationMessage, - handleCustomUserNotification, - ]); - - const protectionSwitch = useMemo(() => { - return ( - - ); - }, [handleSwitchChange, selected]); + const OSes: Immutable = [OS.windows]; + const protection = 'ransomware'; return ( { })} supportedOss={[OperatingSystem.WINDOWS]} dataTestSubj="ransomwareProtectionsForm" - rightCorner={protectionSwitch} + rightCorner={} > - {radioButtons} + +