Skip to content

Commit

Permalink
fixed up stuff, but reducer is still having a hard time
Browse files Browse the repository at this point in the history
  • Loading branch information
oatkiller committed Apr 9, 2020
1 parent c12e150 commit 9fdfe77
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 extends keyof UIPolicyConfig>(key: Key) => <
subKey extends keyof UIPolicyConfig[Key]
>(
subKey: subKey
) => <LeafKey extends keyof UIPolicyConfig[Key][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<K1 extends keyof UIPolicyConfig, K2 extends keyof UIPolicyConfig[K1]>(
configuration: UIPolicyConfig,
keyPath: [K1, K2],
value: UIPolicyConfig[K1][K2]
): UIPolicyConfig;
export function setIn<K1 extends keyof UIPolicyConfig>(
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 extends keyof UIPolicyConfig>(key: Key) => <
subKey extends keyof UIPolicyConfig[Key]
>(
subKey: subKey
) => <LeafKey extends keyof UIPolicyConfig[Key][subKey]>(leafKey: LeafKey) => <
V extends UIPolicyConfig[Key][subKey][LeafKey]
>(
v: V
): UIPolicyConfig => {
const c = clone(a);
c[key][subKey][leafKey] = v;
return c;
};
73 changes: 33 additions & 40 deletions x-pack/plugins/endpoint/public/applications/endpoint/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -172,29 +155,39 @@ interface PolicyConfigAdvancedOptions {
};
}

/**
* Windows-specific policy configuration that is supported via the UI
*/
type WindowsPolicyConfig = Pick<PolicyConfig['windows'], 'events' | 'malware'>;

/**
* Mac-specific policy configuration that is supported via the UI
*/
type MacPolicyConfig = Pick<PolicyConfig['mac'], 'malware' | 'events'>;

/**
* Linux-specific policy configuration that is supported via the UI
*/
type LinuxPolicyConfig = Pick<PolicyConfig['linux'], 'events'>;

/**
* 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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<HTMLInputElement>) => {
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 (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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(
() => [
Expand All @@ -31,23 +30,20 @@ export const MacEventing = React.memo(() => {
defaultMessage: 'File',
}),
os: OS.mac,
protectionEvent: 'events',
protectionField: 'file',
},
{
name: i18n.translate('xpack.endpoint.policyDetailsConfig.mac.events.process', {
defaultMessage: 'Process',
}),
os: OS.mac,
protectionEvent: 'events',
protectionField: 'process',
},
{
name: i18n.translate('xpack.endpoint.policyDetailsConfig.mac.events.network', {
defaultMessage: 'Network',
}),
os: OS.mac,
protectionEvent: 'events',
protectionField: 'network',
},
],
Expand All @@ -69,12 +65,12 @@ export const MacEventing = React.memo(() => {
{checkboxes.map((item, index) => {
return (
<EventingCheckbox
id={useMemo(() => 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)}
/>
);
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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(
() => [
Expand All @@ -33,15 +33,13 @@ export const WindowsEventing = React.memo(() => {
defaultMessage: 'Process',
}),
os: OS.windows,
protectionEvent: 'events',
protectionField: 'process',
},
{
name: i18n.translate('xpack.endpoint.policyDetailsConfig.windows.events.network', {
defaultMessage: 'Network',
}),
os: OS.windows,
protectionEvent: 'events',
protectionField: 'network',
},
],
Expand All @@ -65,9 +63,10 @@ export const WindowsEventing = React.memo(() => {
<EventingCheckbox
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)}
/>
);
})}
Expand Down Expand Up @@ -99,7 +98,7 @@ export const WindowsEventing = React.memo(() => {
[]
)}
id="windowsEventingForm"
rightCorner={collectionsEnabled()}
rightCorner={collectionsEnabled}
children={renderCheckboxes}
/>
);
Expand Down

0 comments on commit 9fdfe77

Please sign in to comment.