From 9fdfe773c9966ed7e7efdf65864474a03c60b4ac Mon Sep 17 00:00:00 2001 From: oatkiller Date: Thu, 9 Apr 2020 12:47:54 -0400 Subject: [PATCH] fixed up stuff, but reducer is still having a hard time --- .../endpoint/models/policy_details_config.ts | 55 +++++++------- .../public/applications/endpoint/types.ts | 73 +++++++++---------- .../policy/policy_forms/eventing/checkbox.tsx | 29 ++------ .../view/policy/policy_forms/eventing/mac.tsx | 14 ++-- .../policy/policy_forms/eventing/windows.tsx | 13 ++-- 5 files changed, 78 insertions(+), 106 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 0d6b6096a430c2..bf96942e83a915 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 @@ -45,34 +45,31 @@ export function clone(policyDetailsConfig: UIPolicyConfig): UIPolicyConfig { } /** - * Returns cloned `configuration` with `value` set by the `keyPath`. + * Returns value from `configuration` */ +export const getIn = (a: UIPolicyConfig) => (key: Key) => < + subKey extends keyof UIPolicyConfig[Key] +>( + subKey: subKey +) => ( + leafKey: LeafKey +): UIPolicyConfig[Key][subKey][LeafKey] => { + return a[key][subKey][leafKey]; +}; -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; -} +/** + * Returns cloned `configuration` with `value` set by the `keyPath`. + */ +export const setIn = (a: UIPolicyConfig) => (key: Key) => < + subKey extends keyof UIPolicyConfig[Key] +>( + subKey: subKey +) => (leafKey: LeafKey) => < + V extends UIPolicyConfig[Key][subKey][LeafKey] +>( + v: V +): UIPolicyConfig => { + const c = clone(a); + c[key][subKey][leafKey] = v; + return c; +}; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/types.ts b/x-pack/plugins/endpoint/public/applications/endpoint/types.ts index 5caab1450b2b6b..dda50847169e7f 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/types.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/types.ts @@ -118,38 +118,21 @@ export interface PolicyDetailsState { * Endpoint Policy configuration */ export interface PolicyConfig { - windows: { - events: { - process: boolean; - network: boolean; - }; - /** malware mode can be off, detect, prevent or prevent and notify user */ - malware: MalwareFields; + windows: UIPolicyConfig['windows'] & { logging: { stdout: string; file: string; }; advanced: PolicyConfigAdvancedOptions; }; - mac: { - events: { - file: boolean; - process: boolean; - network: boolean; - }; - malware: MalwareFields; + mac: UIPolicyConfig['mac'] & { logging: { stdout: string; file: string; }; advanced: PolicyConfigAdvancedOptions; }; - linux: { - events: { - file: boolean; - process: boolean; - network: boolean; - }; + linux: UIPolicyConfig['linux'] & { logging: { stdout: string; file: string; @@ -172,29 +155,39 @@ interface PolicyConfigAdvancedOptions { }; } -/** - * Windows-specific policy configuration that is supported via the UI - */ -type WindowsPolicyConfig = Pick; - -/** - * Mac-specific policy configuration that is supported via the UI - */ -type MacPolicyConfig = Pick; - -/** - * Linux-specific policy configuration that is supported via the UI - */ -type LinuxPolicyConfig = Pick; - /** * The set of Policy configuration settings that are show/edited via the UI */ -export interface UIPolicyConfig { - windows: WindowsPolicyConfig; - mac: MacPolicyConfig; - linux: LinuxPolicyConfig; -} +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +export type UIPolicyConfig = { + windows: { + events: { + process: boolean; + network: boolean; + }; + /** malware mode can be off, detect, prevent or prevent and notify user */ + malware: MalwareFields; + }; + mac: { + events: { + file: boolean; + process: boolean; + network: boolean; + }; + malware: MalwareFields; + }; + + /** + * Linux-specific policy configuration that is supported via the UI + */ + linux: { + events: { + file: boolean; + process: boolean; + network: boolean; + }; + }; +}; /** OS used in Policy */ export enum OS { 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 3da3f4daffe339..5cae342e25ab56 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 @@ -8,47 +8,34 @@ import React, { useCallback, useMemo } from 'react'; import { EuiCheckbox } from '@elastic/eui'; import { useDispatch } from 'react-redux'; import { htmlIdGenerator } from '@elastic/eui'; -import { setIn } from '../../../../models/policy_details_config'; import { usePolicyDetailsSelector } from '../../policy_hooks'; import { policyConfig } from '../../../../store/policy_details/selectors'; import { PolicyDetailsAction } from '../../../../store/policy_details'; import { UIPolicyConfig } from '../../../../types'; -export const EventingCheckbox = React.memo(function< - T extends keyof UIPolicyConfig & string, - TT extends keyof UIPolicyConfig[T] & string, - TTT extends keyof UIPolicyConfig[T][TT] & string ->({ +export const EventingCheckbox = React.memo(function({ name, - os, - protectionEvent, - protectionField, + setter, + getter, }: { name: string; - os: T; - protectionEvent: TT; - protectionField: TTT; + setter: (config: UIPolicyConfig, checked: boolean) => UIPolicyConfig; + getter: (config: UIPolicyConfig) => boolean; }) { const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); - const selected = policyDetailsConfig[os][protectionEvent][protectionField]; + const selected = getter(policyDetailsConfig); const dispatch = useDispatch<(action: PolicyDetailsAction) => void>(); const handleCheckboxChange = useCallback( (event: React.ChangeEvent) => { if (policyDetailsConfig) { - const payload = setIn( - policyDetailsConfig, - [os, protectionEvent, protectionField], - event.target.checked - ); - dispatch({ type: 'userChangedPolicyConfig', - payload: { policyConfig: payload }, + payload: { policyConfig: setter(policyDetailsConfig, event.target.checked) }, }); } }, - [dispatch, os, policyDetailsConfig, protectionEvent, protectionField] + [dispatch, policyDetailsConfig, setter] ); 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 d832eed3786438..e652b47edca7a6 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 @@ -7,13 +7,13 @@ import React, { useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { htmlIdGenerator } from '@elastic/eui'; import { EuiTitle, EuiText, EuiSpacer } from '@elastic/eui'; import { EventingCheckbox } from './checkbox'; import { OS, UIPolicyConfig } from '../../../../types'; import { usePolicyDetailsSelector } from '../../policy_hooks'; import { selectedMacEventing, totalMacEventing } from '../../../../store/policy_details/selectors'; import { ConfigForm } from '../config_form'; +import { getIn, setIn } from '../../../../models/policy_details_config'; export const MacEventing = React.memo(() => { const selected = usePolicyDetailsSelector(selectedMacEventing); @@ -22,7 +22,6 @@ export const MacEventing = React.memo(() => { const checkboxes: Array<{ name: string; os: 'mac'; - protectionEvent: keyof UIPolicyConfig['mac']; protectionField: keyof UIPolicyConfig['mac']['events']; }> = useMemo( () => [ @@ -31,7 +30,6 @@ export const MacEventing = React.memo(() => { defaultMessage: 'File', }), os: OS.mac, - protectionEvent: 'events', protectionField: 'file', }, { @@ -39,7 +37,6 @@ export const MacEventing = React.memo(() => { defaultMessage: 'Process', }), os: OS.mac, - protectionEvent: 'events', protectionField: 'process', }, { @@ -47,7 +44,6 @@ export const MacEventing = React.memo(() => { defaultMessage: 'Network', }), os: OS.mac, - protectionEvent: 'events', protectionField: 'network', }, ], @@ -69,12 +65,12 @@ export const MacEventing = React.memo(() => { {checkboxes.map((item, index) => { return ( htmlIdGenerator()(), [])} name={item.name} key={index} - os={item.os} - protectionEvent={item.protectionEvent} - protectionField={item.protectionField} + setter={(config, checked) => + setIn(config)(item.os)('events')(item.protectionField)(checked) + } + getter={config => getIn(config)(item.os)('events')(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 ee7ce56391b7cc..1ab0434fcc3786 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 @@ -16,6 +16,7 @@ import { totalWindowsEventing, } from '../../../../store/policy_details/selectors'; import { ConfigForm } from '../config_form'; +import { setIn, getIn } from '../../../../models/policy_details_config'; export const WindowsEventing = React.memo(() => { const selected = usePolicyDetailsSelector(selectedWindowsEventing); @@ -24,7 +25,6 @@ export const WindowsEventing = React.memo(() => { const checkboxes: Array<{ name: string; os: 'windows'; - protectionEvent: keyof UIPolicyConfig['windows']; protectionField: keyof UIPolicyConfig['windows']['events']; }> = useMemo( () => [ @@ -33,7 +33,6 @@ export const WindowsEventing = React.memo(() => { defaultMessage: 'Process', }), os: OS.windows, - protectionEvent: 'events', protectionField: 'process', }, { @@ -41,7 +40,6 @@ export const WindowsEventing = React.memo(() => { defaultMessage: 'Network', }), os: OS.windows, - protectionEvent: 'events', protectionField: 'network', }, ], @@ -65,9 +63,10 @@ export const WindowsEventing = React.memo(() => { + setIn(config)(item.os)('events')(item.protectionField)(checked) + } + getter={config => getIn(config)(item.os)('events')(item.protectionField)} /> ); })} @@ -99,7 +98,7 @@ export const WindowsEventing = React.memo(() => { [] )} id="windowsEventingForm" - rightCorner={collectionsEnabled()} + rightCorner={collectionsEnabled} children={renderCheckboxes} /> );