From c81750d8f3497bbcd59c06ebf3dae2defcf94285 Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Wed, 29 Jun 2022 17:46:13 -0400 Subject: [PATCH 1/7] Add `enteredAt` to CommandHistoryItem and some refactoring in `handleExecuteCommand` --- .../handle_execute_command.tsx | 304 ++++++++++-------- .../console/components/console_state/types.ts | 1 + 2 files changed, 168 insertions(+), 137 deletions(-) diff --git a/x-pack/plugins/security_solution/public/management/components/console/components/console_state/state_update_handlers/handle_execute_command.tsx b/x-pack/plugins/security_solution/public/management/components/console/components/console_state/state_update_handlers/handle_execute_command.tsx index 7bc01704c61bf..e9b049506d594 100644 --- a/x-pack/plugins/security_solution/public/management/components/console/components/console_state/state_update_handlers/handle_execute_command.tsx +++ b/x-pack/plugins/security_solution/public/management/components/console/components/console_state/state_update_handlers/handle_execute_command.tsx @@ -97,6 +97,18 @@ const cloneCommandDefinitionWithNewRenderComponent = ( }; }; +const createCommandHistoryEntry = ( + command: CommandHistoryItem['command'], + state: CommandHistoryItem['state'] = createCommandExecutionState() +): CommandHistoryItem => { + return { + id: uuidV4(), + enteredAt: new Date().toISOString(), + command, + state, + }; +}; + export const handleExecuteCommand: ConsoleStoreReducer< ConsoleDataAction & { type: 'executeCommand' } > = (state, action) => { @@ -113,18 +125,17 @@ export const handleExecuteCommand: ConsoleStoreReducer< // Unknown command if (!commandDefinition) { - return updateStateWithNewCommandHistoryItem(state, { - id: uuidV4(), - command: { + return updateStateWithNewCommandHistoryItem( + state, + createCommandHistoryEntry({ input: parsedInput.input, args: parsedInput, commandDefinition: { ...UnknownCommandDefinition, RenderComponent: UnknownCommand, }, - }, - state: createCommandExecutionState(), - }); + }) + ); } const command = { @@ -138,74 +149,82 @@ export const handleExecuteCommand: ConsoleStoreReducer< if (parsedInput.hasArgs) { // Show command help if (parsedInput.hasArg('help')) { - return updateStateWithNewCommandHistoryItem(state, { - id: uuidV4(), - command: cloneCommandDefinitionWithNewRenderComponent(command, HelpCommandArgument), - state: createCommandExecutionState(), - }); + return updateStateWithNewCommandHistoryItem( + state, + createCommandHistoryEntry( + cloneCommandDefinitionWithNewRenderComponent(command, HelpCommandArgument) + ) + ); } // Command supports no arguments if (!commandDefinition.args || Object.keys(commandDefinition.args).length === 0) { - return updateStateWithNewCommandHistoryItem(state, { - id: uuidV4(), - command: cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), - state: createCommandExecutionState({ - errorMessage: i18n.translate( - 'xpack.securitySolution.console.commandValidation.noArgumentsSupported', - { - defaultMessage: 'Command does not support any arguments', - } - ), - }), - }); + return updateStateWithNewCommandHistoryItem( + state, + createCommandHistoryEntry( + cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), + createCommandExecutionState({ + errorMessage: i18n.translate( + 'xpack.securitySolution.console.commandValidation.noArgumentsSupported', + { + defaultMessage: 'Command does not support any arguments', + } + ), + }) + ) + ); } // no unknown arguments allowed? const unknownInputArgs = getUnknownArguments(parsedInput.args, commandDefinition.args); if (unknownInputArgs.length) { - return updateStateWithNewCommandHistoryItem(state, { - id: uuidV4(), - command: cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), - state: createCommandExecutionState({ - errorMessage: ( - {parsedInput.name}, - unknownArgs: ( - - {unknownInputArgs.map(toCliArgumentOption).join(', ')} - - ), - }} - /> - ), - }), - }); + return updateStateWithNewCommandHistoryItem( + state, + createCommandHistoryEntry( + cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), + createCommandExecutionState({ + errorMessage: ( + {parsedInput.name}, + unknownArgs: ( + + {unknownInputArgs.map(toCliArgumentOption).join(', ')} + + ), + }} + /> + ), + }) + ) + ); } // Missing required Arguments for (const requiredArg of requiredArgs) { if (!parsedInput.args[requiredArg]) { - return updateStateWithNewCommandHistoryItem(state, { - id: uuidV4(), - command: cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), - state: createCommandExecutionState({ - errorMessage: i18n.translate( - 'xpack.securitySolution.console.commandValidation.missingRequiredArg', - { - defaultMessage: 'Missing required argument: {argName}', - values: { - argName: toCliArgumentOption(requiredArg), - }, - } - ), - }), - }); + return updateStateWithNewCommandHistoryItem( + state, + + createCommandHistoryEntry( + cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), + createCommandExecutionState({ + errorMessage: i18n.translate( + 'xpack.securitySolution.console.commandValidation.missingRequiredArg', + { + defaultMessage: 'Missing required argument: {argName}', + values: { + argName: toCliArgumentOption(requiredArg), + }, + } + ), + }) + ) + ); } } @@ -216,87 +235,100 @@ export const handleExecuteCommand: ConsoleStoreReducer< // Unknown argument if (!argDefinition) { - return updateStateWithNewCommandHistoryItem(state, { - id: uuidV4(), - command: cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), - state: createCommandExecutionState({ - errorMessage: i18n.translate( - 'xpack.securitySolution.console.commandValidation.unsupportedArg', - { - defaultMessage: 'Unsupported argument: {argName}', - values: { argName: toCliArgumentOption(argName) }, - } - ), - }), - }); + return updateStateWithNewCommandHistoryItem( + state, + createCommandHistoryEntry( + cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), + + createCommandExecutionState({ + errorMessage: i18n.translate( + 'xpack.securitySolution.console.commandValidation.unsupportedArg', + { + defaultMessage: 'Unsupported argument: {argName}', + values: { argName: toCliArgumentOption(argName) }, + } + ), + }) + ) + ); } // does not allow multiple values if (!argDefinition.allowMultiples && Array.isArray(argInput) && argInput.length > 1) { - return updateStateWithNewCommandHistoryItem(state, { - id: uuidV4(), - command: cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), - state: createCommandExecutionState({ - errorMessage: i18n.translate( - 'xpack.securitySolution.console.commandValidation.argSupportedOnlyOnce', - { - defaultMessage: 'Argument can only be used once: {argName}', - values: { argName: toCliArgumentOption(argName) }, - } - ), - }), - }); + return updateStateWithNewCommandHistoryItem( + state, + createCommandHistoryEntry( + cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), + createCommandExecutionState({ + errorMessage: i18n.translate( + 'xpack.securitySolution.console.commandValidation.argSupportedOnlyOnce', + { + defaultMessage: 'Argument can only be used once: {argName}', + values: { argName: toCliArgumentOption(argName) }, + } + ), + }) + ) + ); } if (argDefinition.validate) { const validationResult = argDefinition.validate(argInput); if (validationResult !== true) { - return updateStateWithNewCommandHistoryItem(state, { - id: uuidV4(), - command: cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), - state: createCommandExecutionState({ - errorMessage: i18n.translate( - 'xpack.securitySolution.console.commandValidation.invalidArgValue', - { - defaultMessage: 'Invalid argument value: {argName}. {error}', - values: { argName: toCliArgumentOption(argName), error: validationResult }, - } - ), - }), - }); + return updateStateWithNewCommandHistoryItem( + state, + createCommandHistoryEntry( + cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), + createCommandExecutionState({ + errorMessage: i18n.translate( + 'xpack.securitySolution.console.commandValidation.invalidArgValue', + { + defaultMessage: 'Invalid argument value: {argName}. {error}', + values: { argName: toCliArgumentOption(argName), error: validationResult }, + } + ), + }) + ) + ); } } } } else if (requiredArgs.length > 0) { - return updateStateWithNewCommandHistoryItem(state, { - id: uuidV4(), - command: cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), - state: createCommandExecutionState({ - errorMessage: i18n.translate( - 'xpack.securitySolution.console.commandValidation.mustHaveArgs', - { - defaultMessage: 'Missing required arguments: {requiredArgs}', - values: { - requiredArgs: requiredArgs.map((argName) => toCliArgumentOption(argName)).join(', '), - }, - } - ), - }), - }); + return updateStateWithNewCommandHistoryItem( + state, + createCommandHistoryEntry( + cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), + createCommandExecutionState({ + errorMessage: i18n.translate( + 'xpack.securitySolution.console.commandValidation.mustHaveArgs', + { + defaultMessage: 'Missing required arguments: {requiredArgs}', + values: { + requiredArgs: requiredArgs + .map((argName) => toCliArgumentOption(argName)) + .join(', '), + }, + } + ), + }) + ) + ); } else if (commandDefinition.mustHaveArgs) { - return updateStateWithNewCommandHistoryItem(state, { - id: uuidV4(), - command: cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), - state: createCommandExecutionState({ - errorMessage: i18n.translate( - 'xpack.securitySolution.console.commandValidation.oneArgIsRequired', - { - defaultMessage: 'At least one argument must be used', - } - ), - }), - }); + return updateStateWithNewCommandHistoryItem( + state, + createCommandHistoryEntry( + cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), + createCommandExecutionState({ + errorMessage: i18n.translate( + 'xpack.securitySolution.console.commandValidation.oneArgIsRequired', + { + defaultMessage: 'At least one argument must be used', + } + ), + }) + ) + ); } // if the Command definition has a `validate()` callback, then call it now @@ -304,20 +336,18 @@ export const handleExecuteCommand: ConsoleStoreReducer< const validationResult = commandDefinition.validate(command); if (validationResult !== true) { - return updateStateWithNewCommandHistoryItem(state, { - id: uuidV4(), - command: cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), - state: createCommandExecutionState({ - errorMessage: validationResult, - }), - }); + return updateStateWithNewCommandHistoryItem( + state, + createCommandHistoryEntry( + cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), + createCommandExecutionState({ + errorMessage: validationResult, + }) + ) + ); } } // All is good. Execute the command - return updateStateWithNewCommandHistoryItem(state, { - id: uuidV4(), - command, - state: createCommandExecutionState(), - }); + return updateStateWithNewCommandHistoryItem(state, createCommandHistoryEntry(command)); }; diff --git a/x-pack/plugins/security_solution/public/management/components/console/components/console_state/types.ts b/x-pack/plugins/security_solution/public/management/components/console/components/console_state/types.ts index 082e3868c0375..e80daeb6e3ba2 100644 --- a/x-pack/plugins/security_solution/public/management/components/console/components/console_state/types.ts +++ b/x-pack/plugins/security_solution/public/management/components/console/components/console_state/types.ts @@ -68,6 +68,7 @@ export interface InputHistoryItem { export interface CommandHistoryItem { id: string; + enteredAt: string; command: Command; state: CommandExecutionState; } From 16d4ff38fcd6c2c47970060be7f9ca8800970959 Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Wed, 29 Jun 2022 18:59:46 -0400 Subject: [PATCH 2/7] New components: ConsoleText + LongRunningCommandHint --- .../console/components/console_text.tsx | 34 +++++++++++++++++++ .../components/long_running_command_hint.tsx | 26 ++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 x-pack/plugins/security_solution/public/management/components/console/components/console_text.tsx create mode 100644 x-pack/plugins/security_solution/public/management/components/console/components/long_running_command_hint.tsx diff --git a/x-pack/plugins/security_solution/public/management/components/console/components/console_text.tsx b/x-pack/plugins/security_solution/public/management/components/console/components/console_text.tsx new file mode 100644 index 0000000000000..e89d9b9c3bbb8 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/console/components/console_text.tsx @@ -0,0 +1,34 @@ +/* + * 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 React, { memo, PropsWithChildren } from 'react'; +import { EuiText, EuiTextColor, EuiTextColorProps, EuiTextProps, useEuiTheme } from '@elastic/eui'; + +type ConsoleTextProps = PropsWithChildren<{ + size?: EuiTextProps['size']; + color?: EuiTextColorProps['color']; + className?: string; + 'data-test-subj'?: string; +}>; + +export const ConsoleText = memo( + ({ size = 's', color, children, 'data-test-subj': dataTestSubj, className }) => { + const { euiTheme } = useEuiTheme(); + + return ( + // className of `font-family-code` below is defined globally in `Console` styles + + {children} + + ); + } +); +ConsoleText.displayName = 'ConsoleText'; diff --git a/x-pack/plugins/security_solution/public/management/components/console/components/long_running_command_hint.tsx b/x-pack/plugins/security_solution/public/management/components/console/components/long_running_command_hint.tsx new file mode 100644 index 0000000000000..cb7561ed1c013 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/console/components/long_running_command_hint.tsx @@ -0,0 +1,26 @@ +/* + * 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 React, { memo } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { ConsoleText } from './console_text'; +import { useDataTestSubj } from '../hooks/state_selectors/use_data_test_subj'; +import { useTestIdGenerator } from '../../../hooks/use_test_id_generator'; + +export const LongRunningCommandHint = memo(() => { + const getTestId = useTestIdGenerator(useDataTestSubj()); + + return ( + + + + ); +}); +LongRunningCommandHint.displayName = 'LongRunningCommandHint'; From fcf4ab10c823585e43ae8b42748b7d8fb2551cf3 Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Wed, 29 Jun 2022 19:00:41 -0400 Subject: [PATCH 3/7] Adds logic to display the Long running command hint to the execution output --- .../components/command_execution_output.tsx | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_output.tsx b/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_output.tsx index 5d4641ff31777..45a21ca77dbec 100644 --- a/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_output.tsx +++ b/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_output.tsx @@ -5,9 +5,11 @@ * 2.0. */ -import React, { memo, useCallback, useMemo } from 'react'; +import React, { memo, useCallback, useEffect, useMemo, useState } from 'react'; import { EuiLoadingChart, EuiSpacer } from '@elastic/eui'; import styled from 'styled-components'; +import moment from 'moment'; +import { LongRunningCommandHint } from './long_running_command_hint'; import { CommandExecutionResult } from './command_execution_result'; import type { CommandExecutionComponentProps } from '../types'; import type { CommandExecutionState, CommandHistoryItem } from './console_state/types'; @@ -26,9 +28,10 @@ export interface CommandExecutionOutputProps { item: CommandHistoryItem; } export const CommandExecutionOutput = memo( - ({ item: { command, state, id } }) => { + ({ item: { command, state, id, enteredAt } }) => { const dispatch = useConsoleStateDispatch(); const RenderComponent = command.commandDefinition.RenderComponent; + const [isLongRunningCommand, setIsLongRunningCommand] = useState(false); const isRunning = useMemo(() => { return state.status === 'pending'; @@ -62,6 +65,30 @@ export const CommandExecutionOutput = memo( [dispatch, id] ); + // keep track if this becomes a long running command + useEffect(() => { + let timeoutId: number; + + if (isRunning && !isLongRunningCommand) { + const elapsedSeconds = moment().diff(moment(enteredAt), 'seconds'); + + if (elapsedSeconds >= 15) { + setIsLongRunningCommand(true); + return; + } + + timeoutId = setTimeout(() => { + setIsLongRunningCommand(true); + }, (15 - elapsedSeconds) * 1000); + } + + return () => { + if (timeoutId) { + clearTimeout(timeoutId); + } + }; + }, [enteredAt, isLongRunningCommand, isRunning]); + return (
@@ -80,6 +107,13 @@ export const CommandExecutionOutput = memo( /> {isRunning && } + + {isRunning && isLongRunningCommand && ( + <> + + + + )}
); From 366b643186a95b0fd2c4602d12940c7d8aa0f811 Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Wed, 29 Jun 2022 19:05:33 -0400 Subject: [PATCH 4/7] use ConsoleText in command execution result --- .../components/command_execution_result.tsx | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_result.tsx b/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_result.tsx index 30bed05afc0ee..1fb0b2ebe26d6 100644 --- a/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_result.tsx +++ b/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_result.tsx @@ -8,10 +8,11 @@ import React, { memo, PropsWithChildren, ComponentType, useMemo } from 'react'; import type { ReactNode } from 'react'; import { i18n } from '@kbn/i18n'; -import { CommonProps, EuiPanel, EuiSpacer, EuiText, EuiTextColor } from '@elastic/eui'; +import { CommonProps, EuiPanel, EuiSpacer } from '@elastic/eui'; import classNames from 'classnames'; import { useDataTestSubj } from '../hooks/state_selectors/use_data_test_subj'; import { useTestIdGenerator } from '../../../hooks/use_test_id_generator'; +import { ConsoleText } from './console_text'; const COMMAND_EXECUTION_RESULT_SUCCESS_TITLE = i18n.translate( 'xpack.securitySolution.commandExecutionResult.successTitle', @@ -84,24 +85,19 @@ export const CommandExecutionResult = memo( data-test-subj={dataTestSubj ? dataTestSubj : getTestId('commandExecutionResult')} > {showAs === 'pending' ? ( - - - {children ?? COMMAND_EXECUTION_RESULT_PENDING} - - + {children ?? COMMAND_EXECUTION_RESULT_PENDING} ) : ( <> {showTitle && ( <> - - - {title - ? title - : showAs === 'success' - ? COMMAND_EXECUTION_RESULT_SUCCESS_TITLE - : COMMAND_EXECUTION_RESULT_FAILURE_TITLE} - - + + {title + ? title + : showAs === 'success' + ? COMMAND_EXECUTION_RESULT_SUCCESS_TITLE + : COMMAND_EXECUTION_RESULT_FAILURE_TITLE} + + )} From 02f9fcd83393bcfd2f6442bac08fee87c4893b1e Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Thu, 30 Jun 2022 09:49:32 -0400 Subject: [PATCH 5/7] Fix type issue --- .../components/console/components/command_execution_output.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_output.tsx b/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_output.tsx index 45a21ca77dbec..d8134769db4c3 100644 --- a/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_output.tsx +++ b/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_output.tsx @@ -67,7 +67,7 @@ export const CommandExecutionOutput = memo( // keep track if this becomes a long running command useEffect(() => { - let timeoutId: number; + let timeoutId: ReturnType; if (isRunning && !isLongRunningCommand) { const elapsedSeconds = moment().diff(moment(enteredAt), 'seconds'); From ad5271c08d5aaa74eae59b3257b41958d0bae2f7 Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Thu, 30 Jun 2022 11:17:00 -0400 Subject: [PATCH 6/7] tests for logic around showing long running command hint --- .../command_execution_output.test.tsx | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 x-pack/plugins/security_solution/public/management/components/console/components/command_execution_output.test.tsx diff --git a/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_output.test.tsx b/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_output.test.tsx new file mode 100644 index 0000000000000..e39a36de0ddfa --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_output.test.tsx @@ -0,0 +1,73 @@ +/* + * 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 React from 'react'; +import { ConsoleProps } from '..'; +import { AppContextTestRender } from '../../../../common/mock/endpoint'; +import { getConsoleTestSetup } from '../mocks'; +import { act } from '@testing-library/react'; +import { CommandExecutionComponentProps } from '../types'; + +describe('When using CommandExecutionOutput component', () => { + let render: (props?: Partial) => ReturnType; + let renderResult: ReturnType; + let setCmd1ToComplete: () => void; + + beforeEach(() => { + const { renderConsole, commands, enterCommand } = getConsoleTestSetup(); + + const cmd1 = commands.find((command) => command.name === 'cmd1'); + + if (!cmd1) { + throw new Error('cmd1 command not found in test mocks'); + } + + (cmd1.RenderComponent as jest.Mock).mockImplementation( + (props: CommandExecutionComponentProps) => { + setCmd1ToComplete = () => props.setStatus('success'); + + return
{'output'}
; + } + ); + + render = (props = {}) => { + renderResult = renderConsole(props); + enterCommand('cmd1'); + return renderResult; + }; + }); + + it('should show long running hint message if pending and >15s have passed', () => { + jest.useFakeTimers(); + render(); + + expect(renderResult.queryByTestId('test-longRunningCommandHint')).toBeNull(); + + act(() => { + jest.advanceTimersByTime(16 * 1000); + }); + + expect(renderResult.getByTestId('test-longRunningCommandHint')).not.toBeNull(); + }); + + it('should remove long running hint message if command completes', async () => { + jest.useFakeTimers(); + render(); + + act(() => { + jest.advanceTimersByTime(16 * 1000); + }); + + expect(renderResult.getByTestId('test-longRunningCommandHint')).not.toBeNull(); + + act(() => { + setCmd1ToComplete(); + }); + + expect(renderResult.queryByTestId('test-longRunningCommandHint')).toBeNull(); + }); +}); From 924925992dd2eb1de0859517829eba65815f7076 Mon Sep 17 00:00:00 2001 From: Paul Tavares <56442535+paul-tavares@users.noreply.github.com> Date: Thu, 30 Jun 2022 11:24:04 -0400 Subject: [PATCH 7/7] Apply suggestions from code review From Ash Co-authored-by: Ashokaditya <1849116+ashokaditya@users.noreply.github.com> --- .../components/console/components/long_running_command_hint.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/management/components/console/components/long_running_command_hint.tsx b/x-pack/plugins/security_solution/public/management/components/console/components/long_running_command_hint.tsx index cb7561ed1c013..549938b675b56 100644 --- a/x-pack/plugins/security_solution/public/management/components/console/components/long_running_command_hint.tsx +++ b/x-pack/plugins/security_solution/public/management/components/console/components/long_running_command_hint.tsx @@ -18,7 +18,7 @@ export const LongRunningCommandHint = memo(() => { );