Changed the translation text for the description text in the antivirus registration form (#84626)

* Changed the text for the description text in the antivirus registration form. Moved the form component to components folder and extracted translations into constants to make code more readable.

* Extracted EventsForm to reduce duplication among events forms.
This commit is contained in:
Bohdan Tsymbala 2020-12-02 14:47:56 +01:00 committed by GitHub
parent 2ad3d2bc53
commit 32200af4e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 287 additions and 405 deletions

View file

@ -14,6 +14,29 @@ import { isAntivirusRegistrationEnabled } from '../../../store/policy_details/se
import { usePolicyDetailsSelector } from '../../policy_hooks';
import { ConfigForm } from '../../components/config_form';
const TRANSLATIONS: Readonly<{ [K in 'title' | 'description' | 'label']: string }> = {
title: i18n.translate(
'xpack.securitySolution.endpoint.policy.details.antivirusRegistration.type',
{
defaultMessage: 'Register as anti-virus',
}
),
description: i18n.translate(
'xpack.securitySolution.endpoint.policy.details.antivirusRegistration.explanation',
{
defaultMessage:
'Toggle on to register Elastic as an official Anti-Virus solution for Windows OS. ' +
'This will also disable Windows Defender.',
}
),
label: i18n.translate(
'xpack.securitySolution.endpoint.policy.details.antivirusRegistration.toggle',
{
defaultMessage: 'Register as anti-virus',
}
),
};
export const AntivirusRegistrationForm = memo(() => {
const antivirusRegistrationEnabled = usePolicyDetailsSelector(isAntivirusRegistrationEnabled);
const dispatch = useDispatch();
@ -30,31 +53,11 @@ export const AntivirusRegistrationForm = memo(() => {
);
return (
<ConfigForm
type={i18n.translate(
'xpack.securitySolution.endpoint.policy.details.antivirusRegistration.type',
{
defaultMessage: 'Register as anti-virus',
}
)}
supportedOss={[OperatingSystem.WINDOWS]}
>
<EuiText size="s">
{i18n.translate(
'xpack.securitySolution.endpoint.policy.details.antivirusRegistration.explanation',
{
defaultMessage: 'Switch the toggle to on to register Elastic anti-virus',
}
)}
</EuiText>
<ConfigForm type={TRANSLATIONS.title} supportedOss={[OperatingSystem.WINDOWS]}>
<EuiText size="s">{TRANSLATIONS.description}</EuiText>
<EuiSpacer size="s" />
<EuiSwitch
label={i18n.translate(
'xpack.securitySolution.endpoint.policy.details.antivirusRegistration.toggle',
{
defaultMessage: 'Register as anti-virus',
}
)}
label={TRANSLATIONS.label}
checked={antivirusRegistrationEnabled}
onChange={handleSwitchChange}
/>

View file

@ -0,0 +1,87 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiCheckbox, EuiSpacer, EuiText, htmlIdGenerator } from '@elastic/eui';
import { OperatingSystem, UIPolicyConfig } from '../../../../../../../common/endpoint/types';
import { OS } from '../../../types';
import { ConfigForm, ConfigFormHeading } from '../../components/config_form';
const OPERATING_SYSTEM_TO_TEST_SUBJ: { [K in OperatingSystem]: string } = {
[OperatingSystem.WINDOWS]: 'Windows',
[OperatingSystem.LINUX]: 'Linux',
[OperatingSystem.MAC]: 'Mac',
};
interface OperatingSystemToOsMap {
[OperatingSystem.WINDOWS]: OS.windows;
[OperatingSystem.LINUX]: OS.linux;
[OperatingSystem.MAC]: OS.mac;
}
export type ProtectionField<
T extends OperatingSystem
> = keyof UIPolicyConfig[OperatingSystemToOsMap[T]]['events'];
export type EventFormSelection<T extends OperatingSystem> = { [K in ProtectionField<T>]: boolean };
export interface EventFormOption<T extends OperatingSystem> {
name: string;
protectionField: ProtectionField<T>;
}
export interface EventsFormProps<T extends OperatingSystem> {
os: T;
options: ReadonlyArray<EventFormOption<T>>;
selection: EventFormSelection<T>;
onValueSelection: (value: ProtectionField<T>, selected: boolean) => void;
}
const countSelected = <T extends OperatingSystem>(selection: EventFormSelection<T>) => {
return Object.values(selection).filter((value) => value).length;
};
export const EventsForm = <T extends OperatingSystem>({
os,
options,
selection,
onValueSelection,
}: EventsFormProps<T>) => (
<ConfigForm
type={i18n.translate('xpack.securitySolution.endpoint.policy.details.eventCollection', {
defaultMessage: 'Event Collection',
})}
supportedOss={[os]}
rightCorner={
<EuiText size="s" color="subdued">
{i18n.translate('xpack.securitySolution.endpoint.policy.details.eventCollectionsEnabled', {
defaultMessage: '{selected} / {total} event collections enabled',
values: { selected: countSelected(selection), total: options.length },
})}
</EuiText>
}
>
<ConfigFormHeading>
{i18n.translate('xpack.securitySolution.endpoint.policyDetailsConfig.eventingEvents', {
defaultMessage: 'Events',
})}
</ConfigFormHeading>
<EuiSpacer size="s" />
{options.map(({ name, protectionField }) => (
<EuiCheckbox
key={String(protectionField)}
id={htmlIdGenerator()()}
label={name}
data-test-subj={`policy${OPERATING_SYSTEM_TO_TEST_SUBJ[os]}Event_${protectionField}`}
checked={selection[protectionField]}
onChange={(event) => onValueSelection(protectionField, event.target.checked)}
/>
))}
</ConfigForm>
);
EventsForm.displayName = 'EventsForm';

View file

@ -36,7 +36,7 @@ import { AgentsSummary } from './agents_summary';
import { VerticalDivider } from './vertical_divider';
import { WindowsEvents, MacEvents, LinuxEvents } from './policy_forms/events';
import { MalwareProtections } from './policy_forms/protections/malware';
import { AntivirusRegistrationForm } from './policy_forms/antivirus_registration';
import { AntivirusRegistrationForm } from './components/antivirus_registration_form';
import { useToasts } from '../../../../common/lib/kibana';
import { AppAction } from '../../../../common/store/actions';
import { SpyRoute } from '../../../../common/utils/route/spy_routes';

View file

@ -1,55 +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;
* you may not use this file except in compliance with the Elastic License.
*/
import React, { useCallback, useMemo } from 'react';
import { EuiCheckbox, EuiCheckboxProps, htmlIdGenerator } from '@elastic/eui';
import { useDispatch } from 'react-redux';
import { usePolicyDetailsSelector } from '../../policy_hooks';
import { policyConfig } from '../../../store/policy_details/selectors';
import { PolicyDetailsAction } from '../../../store/policy_details';
import { UIPolicyConfig } from '../../../../../../../common/endpoint/types';
type EventsCheckboxProps = Omit<EuiCheckboxProps, 'id' | 'label' | 'checked' | 'onChange'> & {
name: string;
setter: (config: UIPolicyConfig, checked: boolean) => UIPolicyConfig;
getter: (config: UIPolicyConfig) => boolean;
};
export const EventsCheckbox = React.memo(function ({
name,
setter,
getter,
...otherProps
}: EventsCheckboxProps) {
const policyDetailsConfig = usePolicyDetailsSelector(policyConfig);
const selected = getter(policyDetailsConfig);
const dispatch = useDispatch<(action: PolicyDetailsAction) => void>();
const checkboxId = useMemo(() => htmlIdGenerator()(), []);
const handleCheckboxChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
if (policyDetailsConfig) {
dispatch({
type: 'userChangedPolicyConfig',
payload: { policyConfig: setter(policyDetailsConfig, event.target.checked) },
});
}
},
[dispatch, policyDetailsConfig, setter]
);
return (
<EuiCheckbox
id={checkboxId}
label={name}
checked={selected}
onChange={handleCheckboxChange}
{...otherProps}
/>
);
});
EventsCheckbox.displayName = 'EventsCheckbox';

View file

@ -4,96 +4,59 @@
* you may not use this file except in compliance with the Elastic License.
*/
import React, { useMemo } from 'react';
import React, { memo } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiSpacer, EuiText } from '@elastic/eui';
import { EventsCheckbox } from './checkbox';
import { OS } from '../../../types';
import { useDispatch } from 'react-redux';
import { OperatingSystem } from '../../../../../../../common/endpoint/types';
import { policyConfig } from '../../../store/policy_details/selectors';
import { setIn } from '../../../models/policy_details_config';
import { usePolicyDetailsSelector } from '../../policy_hooks';
import { selectedLinuxEvents, totalLinuxEvents } from '../../../store/policy_details/selectors';
import { ConfigForm, ConfigFormHeading } from '../../components/config_form';
import { getIn, setIn } from '../../../models/policy_details_config';
import { OperatingSystem, UIPolicyConfig } from '../../../../../../../common/endpoint/types';
import {
COLLECTIONS_ENABLED_MESSAGE,
EVENTS_FORM_TYPE_LABEL,
EVENTS_HEADING,
} from './translations';
import { EventFormOption, EventsForm } from '../../components/events_form';
export const LinuxEvents = React.memo(() => {
const selected = usePolicyDetailsSelector(selectedLinuxEvents);
const total = usePolicyDetailsSelector(totalLinuxEvents);
const OPTIONS: ReadonlyArray<EventFormOption<OperatingSystem.LINUX>> = [
{
name: i18n.translate('xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.file', {
defaultMessage: 'File',
}),
protectionField: 'file',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.process',
{
defaultMessage: 'Process',
}
),
protectionField: 'process',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.network',
{
defaultMessage: 'Network',
}
),
protectionField: 'network',
},
];
const checkboxes = useMemo(() => {
const items: Array<{
name: string;
os: 'linux';
protectionField: keyof UIPolicyConfig['linux']['events'];
}> = [
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.file',
{
defaultMessage: 'File',
}
),
os: OS.linux,
protectionField: 'file',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.process',
{
defaultMessage: 'Process',
}
),
os: OS.linux,
protectionField: 'process',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.network',
{
defaultMessage: 'Network',
}
),
os: OS.linux,
protectionField: 'network',
},
];
return (
<>
<ConfigFormHeading>{EVENTS_HEADING}</ConfigFormHeading>
<EuiSpacer size="s" />
{items.map((item, index) => {
return (
<EventsCheckbox
name={item.name}
key={index}
data-test-subj={`policyLinuxEvent_${item.protectionField}`}
setter={(config, checked) =>
setIn(config)(item.os)('events')(item.protectionField)(checked)
}
getter={(config) => getIn(config)(item.os)('events')(item.protectionField)}
/>
);
})}
</>
);
}, []);
export const LinuxEvents = memo(() => {
const policyDetailsConfig = usePolicyDetailsSelector(policyConfig);
const dispatch = useDispatch();
return (
<ConfigForm
type={EVENTS_FORM_TYPE_LABEL}
supportedOss={[OperatingSystem.LINUX]}
dataTestSubj="linuxEventingForm"
rightCorner={
<EuiText size="s" color="subdued">
{COLLECTIONS_ENABLED_MESSAGE(selected, total)}
</EuiText>
<EventsForm<OperatingSystem.LINUX>
os={OperatingSystem.LINUX}
selection={policyDetailsConfig.linux.events}
options={OPTIONS}
onValueSelection={(value, selected) =>
dispatch({
type: 'userChangedPolicyConfig',
payload: { policyConfig: setIn(policyDetailsConfig)('linux')('events')(value)(selected) },
})
}
>
{checkboxes}
</ConfigForm>
/>
);
});
LinuxEvents.displayName = 'LinuxEvents';

View file

@ -4,96 +4,53 @@
* you may not use this file except in compliance with the Elastic License.
*/
import React, { useMemo } from 'react';
import React, { memo } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiSpacer, EuiText } from '@elastic/eui';
import { EventsCheckbox } from './checkbox';
import { OS } from '../../../types';
import { useDispatch } from 'react-redux';
import { OperatingSystem } from '../../../../../../../common/endpoint/types';
import { policyConfig } from '../../../store/policy_details/selectors';
import { setIn } from '../../../models/policy_details_config';
import { usePolicyDetailsSelector } from '../../policy_hooks';
import { selectedMacEvents, totalMacEvents } from '../../../store/policy_details/selectors';
import { ConfigForm, ConfigFormHeading } from '../../components/config_form';
import { getIn, setIn } from '../../../models/policy_details_config';
import { OperatingSystem, UIPolicyConfig } from '../../../../../../../common/endpoint/types';
import {
COLLECTIONS_ENABLED_MESSAGE,
EVENTS_FORM_TYPE_LABEL,
EVENTS_HEADING,
} from './translations';
import { EventFormOption, EventsForm } from '../../components/events_form';
export const MacEvents = React.memo(() => {
const selected = usePolicyDetailsSelector(selectedMacEvents);
const total = usePolicyDetailsSelector(totalMacEvents);
const OPTIONS: ReadonlyArray<EventFormOption<OperatingSystem.MAC>> = [
{
name: i18n.translate('xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.file', {
defaultMessage: 'File',
}),
protectionField: 'file',
},
{
name: i18n.translate('xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.process', {
defaultMessage: 'Process',
}),
protectionField: 'process',
},
{
name: i18n.translate('xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.network', {
defaultMessage: 'Network',
}),
protectionField: 'network',
},
];
const checkboxes = useMemo(() => {
const items: Array<{
name: string;
os: 'mac';
protectionField: keyof UIPolicyConfig['mac']['events'];
}> = [
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.file',
{
defaultMessage: 'File',
}
),
os: OS.mac,
protectionField: 'file',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.process',
{
defaultMessage: 'Process',
}
),
os: OS.mac,
protectionField: 'process',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.network',
{
defaultMessage: 'Network',
}
),
os: OS.mac,
protectionField: 'network',
},
];
return (
<>
<ConfigFormHeading>{EVENTS_HEADING}</ConfigFormHeading>
<EuiSpacer size="s" />
{items.map((item, index) => {
return (
<EventsCheckbox
name={item.name}
key={index}
data-test-subj={`policyMacEvent_${item.protectionField}`}
setter={(config, checked) =>
setIn(config)(item.os)('events')(item.protectionField)(checked)
}
getter={(config) => getIn(config)(item.os)('events')(item.protectionField)}
/>
);
})}
</>
);
}, []);
export const MacEvents = memo(() => {
const policyDetailsConfig = usePolicyDetailsSelector(policyConfig);
const dispatch = useDispatch();
return (
<ConfigForm
type={EVENTS_FORM_TYPE_LABEL}
supportedOss={[OperatingSystem.MAC]}
dataTestSubj="macEventingForm"
rightCorner={
<EuiText size="s" color="subdued">
{COLLECTIONS_ENABLED_MESSAGE(selected, total)}
</EuiText>
<EventsForm<OperatingSystem.MAC>
os={OperatingSystem.MAC}
selection={policyDetailsConfig.mac.events}
options={OPTIONS}
onValueSelection={(value, selected) =>
dispatch({
type: 'userChangedPolicyConfig',
payload: { policyConfig: setIn(policyDetailsConfig)('mac')('events')(value)(selected) },
})
}
>
{checkboxes}
</ConfigForm>
/>
);
});
MacEvents.displayName = 'MacEvents';

View file

@ -1,28 +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;
* you may not use this file except in compliance with the Elastic License.
*/
import { i18n } from '@kbn/i18n';
export const EVENTS_HEADING = i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.eventingEvents',
{
defaultMessage: 'Events',
}
);
export const EVENTS_FORM_TYPE_LABEL = i18n.translate(
'xpack.securitySolution.endpoint.policy.details.eventCollection',
{
defaultMessage: 'Event Collection',
}
);
export const COLLECTIONS_ENABLED_MESSAGE = (selected: number, total: number) => {
return i18n.translate('xpack.securitySolution.endpoint.policy.details.eventCollectionsEnabled', {
defaultMessage: '{selected} / {total} event collections enabled',
values: { selected, total },
});
};

View file

@ -4,142 +4,97 @@
* you may not use this file except in compliance with the Elastic License.
*/
import React, { useMemo } from 'react';
import React, { memo } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiSpacer, EuiText } from '@elastic/eui';
import { EventsCheckbox } from './checkbox';
import { OS } from '../../../types';
import { useDispatch } from 'react-redux';
import { OperatingSystem } from '../../../../../../../common/endpoint/types';
import { policyConfig } from '../../../store/policy_details/selectors';
import { setIn } from '../../../models/policy_details_config';
import { usePolicyDetailsSelector } from '../../policy_hooks';
import { selectedWindowsEvents, totalWindowsEvents } from '../../../store/policy_details/selectors';
import { ConfigForm, ConfigFormHeading } from '../../components/config_form';
import { getIn, setIn } from '../../../models/policy_details_config';
import {
Immutable,
OperatingSystem,
UIPolicyConfig,
} from '../../../../../../../common/endpoint/types';
import {
COLLECTIONS_ENABLED_MESSAGE,
EVENTS_FORM_TYPE_LABEL,
EVENTS_HEADING,
} from './translations';
import { EventFormOption, EventsForm } from '../../components/events_form';
export const WindowsEvents = React.memo(() => {
const selected = usePolicyDetailsSelector(selectedWindowsEvents);
const total = usePolicyDetailsSelector(totalWindowsEvents);
const OPTIONS: ReadonlyArray<EventFormOption<OperatingSystem.WINDOWS>> = [
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.dllDriverLoad',
{
defaultMessage: 'DLL and Driver Load',
}
),
protectionField: 'dll_and_driver_load',
},
{
name: i18n.translate('xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.dns', {
defaultMessage: 'DNS',
}),
protectionField: 'dns',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.file',
{
defaultMessage: 'File',
}
),
protectionField: 'file',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.network',
{
defaultMessage: 'Network',
}
),
protectionField: 'network',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.process',
{
defaultMessage: 'Process',
}
),
protectionField: 'process',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.registry',
{
defaultMessage: 'Registry',
}
),
protectionField: 'registry',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.security',
{
defaultMessage: 'Security',
}
),
protectionField: 'security',
},
];
const checkboxes = useMemo(() => {
const items: Immutable<
Array<{
name: string;
os: 'windows';
protectionField: keyof UIPolicyConfig['windows']['events'];
}>
> = [
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.dllDriverLoad',
{
defaultMessage: 'DLL and Driver Load',
}
),
os: OS.windows,
protectionField: 'dll_and_driver_load',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.dns',
{
defaultMessage: 'DNS',
}
),
os: OS.windows,
protectionField: 'dns',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.file',
{
defaultMessage: 'File',
}
),
os: OS.windows,
protectionField: 'file',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.network',
{
defaultMessage: 'Network',
}
),
os: OS.windows,
protectionField: 'network',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.process',
{
defaultMessage: 'Process',
}
),
os: OS.windows,
protectionField: 'process',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.registry',
{
defaultMessage: 'Registry',
}
),
os: OS.windows,
protectionField: 'registry',
},
{
name: i18n.translate(
'xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.security',
{
defaultMessage: 'Security',
}
),
os: OS.windows,
protectionField: 'security',
},
];
return (
<>
<ConfigFormHeading>{EVENTS_HEADING}</ConfigFormHeading>
<EuiSpacer size="s" />
{items.map((item, index) => {
return (
<EventsCheckbox
name={item.name}
key={index}
data-test-subj={`policyWindowsEvent_${item.protectionField}`}
setter={(config, checked) =>
setIn(config)(item.os)('events')(item.protectionField)(checked)
}
getter={(config) => getIn(config)(item.os)('events')(item.protectionField)}
/>
);
})}
</>
);
}, []);
export const WindowsEvents = memo(() => {
const policyDetailsConfig = usePolicyDetailsSelector(policyConfig);
const dispatch = useDispatch();
return (
<ConfigForm
type={EVENTS_FORM_TYPE_LABEL}
supportedOss={[OperatingSystem.WINDOWS]}
dataTestSubj="windowsEventingForm"
rightCorner={
<EuiText size="s" color="subdued">
{COLLECTIONS_ENABLED_MESSAGE(selected, total)}
</EuiText>
<EventsForm<OperatingSystem.WINDOWS>
os={OperatingSystem.WINDOWS}
selection={policyDetailsConfig.windows.events}
options={OPTIONS}
onValueSelection={(value, selected) =>
dispatch({
type: 'userChangedPolicyConfig',
payload: {
policyConfig: setIn(policyDetailsConfig)('windows')('events')(value)(selected),
},
})
}
>
{checkboxes}
</ConfigForm>
/>
);
});
WindowsEvents.displayName = 'WindowsEvents';