[Security Solution][Endpoint] Refactor ConsoleCodeBlock of Response Actions console (#138576)

* Refactor ConsoleCodeBlock
* move `parsePidOrEntityIdParameter()` to `endpoint_responder`
* CommandList - avoid output help markup when there are no commands in the list
This commit is contained in:
Paul Tavares 2022-08-17 09:32:13 -04:00 committed by GitHub
parent 729ecbaddd
commit 19db56efec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 70 additions and 63 deletions

View file

@ -31,7 +31,7 @@ export const BadArgument = memo<CommandExecutionComponentProps<{}, { errorMessag
return (
<UnsupportedMessageCallout
header={
<ConsoleCodeBlock textColor="error">
<ConsoleCodeBlock textColor="danger">
<FormattedMessage
id="xpack.securitySolution.console.badArgument.title"
defaultMessage="Unsupported argument"

View file

@ -290,6 +290,11 @@ export const CommandList = memo<CommandListProps>(({ commands, display = 'defaul
{commandsByGroups.map((commandsByGroup) => {
const groupLabel = commandsByGroup[0].helpGroupLabel;
const filteredCommands = getFilteredCommands(commandsByGroup);
if (filteredCommands.length === 0) {
return null;
}
return (
<StyledEuiFlexGrid
columns={3}

View file

@ -7,38 +7,24 @@
import type { ReactNode } from 'react';
import React, { memo } from 'react';
import { EuiText, EuiTextColor } from '@elastic/eui';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import type { EuiTextProps } from '@elastic/eui';
import { EuiText } from '@elastic/eui';
import styled from 'styled-components';
const CodeBlock = styled(EuiText)`
font-family: ${(props) => props.theme.eui.euiCodeFontFamily};
`;
export const ConsoleCodeBlock = memo<{
children: ReactNode;
inline?: boolean;
textColor?: 'default' | 'error' | 'success';
textColor?: EuiTextProps['color'];
bold?: boolean;
}>(({ children, inline = false, textColor = 'default', bold = false }) => {
const baseStyledComponent = inline ? EuiTextColor : EuiText;
const CodeBlock = euiStyled(baseStyledComponent).attrs({
transparentBackground: true,
size: 's',
})`{
color: ${(props) => {
if (textColor === 'error') {
return props.theme.eui.euiColorDanger;
} else if (textColor === 'success') {
return props.theme.eui.euiColorSuccessText;
} else {
return props.theme.eui.euiColorDarkestShade;
}
}};
font-weight: ${(props) => {
return bold ? props.theme.eui.euiFontWeightBold : props.theme.eui.euiFontWeightRegular;
}};
font-family: ${(props) => props.theme.eui.euiCodeFontFamily};
padding: 0;
}
`;
return <CodeBlock>{children}</CodeBlock>;
return (
<CodeBlock size="relative" color={textColor} className={inline ? 'eui-displayInline' : ''}>
{bold ? <strong>{children}</strong> : children}
</CodeBlock>
);
});
ConsoleCodeBlock.displayName = 'ConsoleCodeBlock';

View file

@ -56,7 +56,7 @@ export const UnknownCommand = memo<CommandExecutionComponentProps>(({ command, s
return (
<UnsupportedMessageCallout
header={
<ConsoleCodeBlock textColor="error">
<ConsoleCodeBlock textColor="danger">
<FormattedMessage
id="xpack.securitySolution.console.unknownCommand.title"
defaultMessage="Unsupported text/command"

View file

@ -6,7 +6,7 @@
*/
import type { ParsedCommandInterface } from './parsed_command_input';
import { parseCommandInput, parsedPidOrEntityIdParameter } from './parsed_command_input';
import { parseCommandInput } from './parsed_command_input';
describe('when using parsed command input utils', () => {
describe('when using parseCommandInput()', () => {
@ -145,21 +145,4 @@ describe('when using parsed command input utils', () => {
);
});
});
describe('when using parsedPidOrEntityIdParameter()', () => {
it('should parse a pid as a number and return proper params', () => {
const parameters = parsedPidOrEntityIdParameter({ pid: ['123'] });
expect(parameters).toEqual({ pid: 123 });
});
it('should parse an entity id correctly and return proper params', () => {
const parameters = parsedPidOrEntityIdParameter({ entityId: ['123qwe'] });
expect(parameters).toEqual({ entity_id: '123qwe' });
});
it('should return undefined if no params are defined', () => {
const parameters = parsedPidOrEntityIdParameter({});
expect(parameters).toEqual(undefined);
});
});
});

View file

@ -8,7 +8,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { CommandDefinition } from '..';
import type { EndpointActionDataParameterTypes } from '../../../../../common/endpoint/types';
export type ParsedArgData = string[];
@ -185,16 +184,3 @@ export const getArgumentsForCommand = (command: CommandDefinition): string[] =>
? [buildArgumentText({ required: requiredArgs, optional: optionalArgs })]
: [];
};
export const parsedPidOrEntityIdParameter = (parameters: {
pid?: ParsedArgData;
entityId?: ParsedArgData;
}): EndpointActionDataParameterTypes => {
if (parameters.pid) {
return { pid: Number(parameters.pid[0]) };
} else if (parameters.entityId) {
return { entity_id: parameters.entityId[0] };
}
return undefined;
};

View file

@ -8,6 +8,7 @@
import React, { memo, useEffect } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import type { IHttpFetchError } from '@kbn/core-http-browser';
import { parsedPidOrEntityIdParameter } from './utils';
import { ActionSuccess } from './action_success';
import type {
ActionDetails,
@ -17,7 +18,6 @@ import { useGetActionDetails } from '../../hooks/endpoint/use_get_action_details
import type { EndpointCommandDefinitionMeta } from './types';
import { useSendKillProcessRequest } from '../../hooks/endpoint/use_send_kill_process_endpoint_request';
import type { CommandExecutionComponentProps } from '../console/types';
import { parsedPidOrEntityIdParameter } from '../console/service/parsed_command_input';
import { ActionError } from './action_error';
import { ACTION_DETAILS_REFRESH_INTERVAL } from './constants';

View file

@ -8,6 +8,7 @@
import React, { memo, useEffect } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import type { IHttpFetchError } from '@kbn/core-http-browser';
import { parsedPidOrEntityIdParameter } from './utils';
import { ActionSuccess } from './action_success';
import type {
ActionDetails,
@ -17,7 +18,6 @@ import { useGetActionDetails } from '../../hooks/endpoint/use_get_action_details
import type { EndpointCommandDefinitionMeta } from './types';
import { useSendSuspendProcessRequest } from '../../hooks/endpoint/use_send_suspend_process_endpoint_request';
import type { CommandExecutionComponentProps } from '../console/types';
import { parsedPidOrEntityIdParameter } from '../console/service/parsed_command_input';
import { ActionError } from './action_error';
import { ACTION_DETAILS_REFRESH_INTERVAL } from './constants';

View file

@ -0,0 +1,27 @@
/*
* 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 { parsedPidOrEntityIdParameter } from './utils';
describe('Endpoint Responder - Utilities', () => {
describe('when using parsedPidOrEntityIdParameter()', () => {
it('should parse a pid as a number and return proper params', () => {
const parameters = parsedPidOrEntityIdParameter({ pid: ['123'] });
expect(parameters).toEqual({ pid: 123 });
});
it('should parse an entity id correctly and return proper params', () => {
const parameters = parsedPidOrEntityIdParameter({ entityId: ['123qwe'] });
expect(parameters).toEqual({ entity_id: '123qwe' });
});
it('should return undefined if no params are defined', () => {
const parameters = parsedPidOrEntityIdParameter({});
expect(parameters).toEqual(undefined);
});
});
});

View file

@ -0,0 +1,20 @@
/*
* 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 type { EndpointActionDataParameterTypes } from '../../../../common/endpoint/types';
export const parsedPidOrEntityIdParameter = (parameters: {
pid?: string[];
entityId?: string[];
}): EndpointActionDataParameterTypes => {
if (parameters.pid) {
return { pid: Number(parameters.pid[0]) };
} else if (parameters.entityId) {
return { entity_id: parameters.entityId[0] };
}
return undefined;
};