From 3d9e34ca51a7a1bacf1a3633690646a0ad4b410e Mon Sep 17 00:00:00 2001 From: Candace Park Date: Wed, 8 Apr 2020 16:27:05 -0400 Subject: [PATCH] added setIn, still got some type errors tho --- .../endpoint/models/policy_details_config.ts | 33 +++++++++++++++++ .../policy/policy_forms/eventing/checkbox.tsx | 36 ++++++++++--------- .../view/policy/policy_forms/eventing/mac.tsx | 19 +++++++--- .../policy/policy_forms/eventing/windows.tsx | 16 ++++++--- 4 files changed, 78 insertions(+), 26 deletions(-) diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/models/policy_details_config.ts b/x-pack/plugins/endpoint/public/applications/endpoint/models/policy_details_config.ts index 1145d1d19242a..0d6b6096a430c 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/models/policy_details_config.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/models/policy_details_config.ts @@ -43,3 +43,36 @@ export function clone(policyDetailsConfig: UIPolicyConfig): UIPolicyConfig { */ return clonedConfig as UIPolicyConfig; } + +/** + * Returns cloned `configuration` with `value` set by the `keyPath`. + */ + +export function setIn< + K1 extends keyof UIPolicyConfig, + K2 extends keyof UIPolicyConfig[K1], + K3 extends keyof UIPolicyConfig[K1][K2] +>(configuration: UIPolicyConfig, keyPath: [K1, K2, K3], value: boolean | string): UIPolicyConfig; +export function setIn( + configuration: UIPolicyConfig, + keyPath: [K1, K2], + value: UIPolicyConfig[K1][K2] +): UIPolicyConfig; +export function setIn( + configuration: UIPolicyConfig, + keyPath: [K1], + value: UIPolicyConfig[K1] +): UIPolicyConfig; +export function setIn( + configuration: UIPolicyConfig, + keyPath: string[], + value: boolean | string +): UIPolicyConfig { + const payload = clone(configuration); + let current: any = payload; + while (keyPath.length > 1) { + current = current[keyPath.shift()!]; + } + current[keyPath[0]] = value; + return payload; +} diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/eventing/checkbox.tsx b/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/eventing/checkbox.tsx index cd46af222d076..54065b0b36233 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/eventing/checkbox.tsx +++ b/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/eventing/checkbox.tsx @@ -7,48 +7,50 @@ import React, { useCallback } from 'react'; import { EuiCheckbox } from '@elastic/eui'; import { useDispatch } from 'react-redux'; +import { setIn } from '../../../../models/policy_details_config'; import { usePolicyDetailsSelector } from '../../policy_hooks'; -import { policyConfig, windowsEventing } from '../../../../store/policy_details/selectors'; +import { policyConfig } from '../../../../store/policy_details/selectors'; import { PolicyDetailsAction } from '../../../../store/policy_details'; import { UIPolicyConfig } from '../../../../types'; -import { clone } from '../../../../models/policy_details_config'; -export const EventingCheckbox = React.memo(function({ +export const EventingCheckbox = React.memo(function< + T extends keyof UIPolicyConfig, + TT extends keyof UIPolicyConfig[T], + TTT extends keyof UIPolicyConfig[T][TT] +>({ id, name, os, + protectionEvent, protectionField, }: { id: string; name: string; os: T; - protectionField: keyof UIPolicyConfig[T]['events']; + protectionEvent: TT; + protectionField: TTT; }) { const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); - const eventing = usePolicyDetailsSelector(windowsEventing); + const selected = policyDetailsConfig[os][protectionEvent][protectionField]; const dispatch = useDispatch<(action: PolicyDetailsAction) => void>(); const handleCheckboxChange = useCallback( (event: React.ChangeEvent) => { if (policyDetailsConfig) { - const newPayload: UIPolicyConfig = clone(policyDetailsConfig); - newPayload[os].events[protectionField] = event.target.checked; + const payload = setIn( + policyDetailsConfig, + [os, protectionEvent, protectionField], + event.target.checked + ); dispatch({ type: 'userChangedPolicyConfig', - payload: { policyConfig: newPayload }, + payload: { policyConfig: payload }, }); } }, - [dispatch, os, policyDetailsConfig, protectionField] + [dispatch, os, policyDetailsConfig, protectionEvent, protectionField] ); - return ( - - ); + return ; }); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/eventing/mac.tsx b/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/eventing/mac.tsx index b373dd6b32782..d832eed378643 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/eventing/mac.tsx +++ b/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/eventing/mac.tsx @@ -10,7 +10,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { htmlIdGenerator } from '@elastic/eui'; import { EuiTitle, EuiText, EuiSpacer } from '@elastic/eui'; import { EventingCheckbox } from './checkbox'; -import { OS, EventingFields } from '../../../../types'; +import { OS, UIPolicyConfig } from '../../../../types'; import { usePolicyDetailsSelector } from '../../policy_hooks'; import { selectedMacEventing, totalMacEventing } from '../../../../store/policy_details/selectors'; import { ConfigForm } from '../config_form'; @@ -19,28 +19,36 @@ export const MacEventing = React.memo(() => { const selected = usePolicyDetailsSelector(selectedMacEventing); const total = usePolicyDetailsSelector(totalMacEventing); - const checkboxes = useMemo( + const checkboxes: Array<{ + name: string; + os: 'mac'; + protectionEvent: keyof UIPolicyConfig['mac']; + protectionField: keyof UIPolicyConfig['mac']['events']; + }> = useMemo( () => [ { name: i18n.translate('xpack.endpoint.policyDetailsConfig.mac.events.file', { defaultMessage: 'File', }), os: OS.mac, - protectionField: EventingFields.file, + protectionEvent: 'events', + protectionField: 'file', }, { name: i18n.translate('xpack.endpoint.policyDetailsConfig.mac.events.process', { defaultMessage: 'Process', }), os: OS.mac, - protectionField: EventingFields.process, + protectionEvent: 'events', + protectionField: 'process', }, { name: i18n.translate('xpack.endpoint.policyDetailsConfig.mac.events.network', { defaultMessage: 'Network', }), os: OS.mac, - protectionField: EventingFields.network, + protectionEvent: 'events', + protectionField: 'network', }, ], [] @@ -65,6 +73,7 @@ export const MacEventing = React.memo(() => { name={item.name} key={index} os={item.os} + protectionEvent={item.protectionEvent} protectionField={item.protectionField} /> ); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/eventing/windows.tsx b/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/eventing/windows.tsx index 3585407011a57..e2728bee682f4 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/eventing/windows.tsx +++ b/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_forms/eventing/windows.tsx @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiTitle, EuiText, EuiSpacer } from '@elastic/eui'; import { EventingCheckbox } from './checkbox'; -import { OS, EventingFields } from '../../../../types'; +import { OS, UIPolicyConfig } from '../../../../types'; import { usePolicyDetailsSelector } from '../../policy_hooks'; import { selectedWindowsEventing, @@ -21,21 +21,28 @@ export const WindowsEventing = React.memo(() => { const selected = usePolicyDetailsSelector(selectedWindowsEventing); const total = usePolicyDetailsSelector(totalWindowsEventing); - const checkboxes = useMemo( + const checkboxes: Array<{ + name: string; + os: 'windows'; + protectionEvent: keyof UIPolicyConfig['windows']; + protectionField: keyof UIPolicyConfig['windows']['events']; + }> = useMemo( () => [ { name: i18n.translate('xpack.endpoint.policyDetailsConfig.windows.events.process', { defaultMessage: 'Process', }), os: OS.windows, - protectionField: EventingFields.process, + protectionEvent: 'events', + protectionField: 'process', }, { name: i18n.translate('xpack.endpoint.policyDetailsConfig.windows.events.network', { defaultMessage: 'Network', }), os: OS.windows, - protectionField: EventingFields.network, + protectionEvent: 'events', + protectionField: 'network', }, ], [] @@ -60,6 +67,7 @@ export const WindowsEventing = React.memo(() => { name={item.name} key={index} os={item.os} + protectionEvent={item.protectionEvent} protectionField={item.protectionField} /> );