[Security Solution][Endpoint] Adjust the colors for entered console commands to the UX mocks (#136580)

* adjust all command execution history entries to set command input `isValid`
* Color the user's command input property to the console output area
This commit is contained in:
Paul Tavares 2022-07-19 10:42:48 -04:00 committed by GitHub
parent 6ba8013da3
commit 3d3e33c388
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 31 deletions

View file

@ -28,7 +28,7 @@ export interface CommandExecutionOutputProps {
item: CommandHistoryItem; item: CommandHistoryItem;
} }
export const CommandExecutionOutput = memo<CommandExecutionOutputProps>( export const CommandExecutionOutput = memo<CommandExecutionOutputProps>(
({ item: { command, state, id, enteredAt } }) => { ({ item: { command, state, id, enteredAt, isValid } }) => {
const dispatch = useConsoleStateDispatch(); const dispatch = useConsoleStateDispatch();
const RenderComponent = command.commandDefinition.RenderComponent; const RenderComponent = command.commandDefinition.RenderComponent;
const [isLongRunningCommand, setIsLongRunningCommand] = useState(false); const [isLongRunningCommand, setIsLongRunningCommand] = useState(false);
@ -92,7 +92,7 @@ export const CommandExecutionOutput = memo<CommandExecutionOutputProps>(
return ( return (
<CommandOutputContainer> <CommandOutputContainer>
<div> <div>
<UserCommandInput input={command.input} /> <UserCommandInput input={command.input} isValid={isValid} />
</div> </div>
<div> <div>
{/* UX desire for 12px (current theme): achieved with EuiSpace sizes - s (8px) + xs (4px) */} {/* UX desire for 12px (current theme): achieved with EuiSpace sizes - s (8px) + xs (4px) */}

View file

@ -115,10 +115,12 @@ const cloneCommandDefinitionWithNewRenderComponent = (
const createCommandHistoryEntry = ( const createCommandHistoryEntry = (
command: CommandHistoryItem['command'], command: CommandHistoryItem['command'],
state: CommandHistoryItem['state'] = createCommandExecutionState() state: CommandHistoryItem['state'] = createCommandExecutionState(),
isValid: CommandHistoryItem['isValid'] = true
): CommandHistoryItem => { ): CommandHistoryItem => {
return { return {
id: uuidV4(), id: uuidV4(),
isValid,
enteredAt: new Date().toISOString(), enteredAt: new Date().toISOString(),
command, command,
state, state,
@ -143,14 +145,18 @@ export const handleExecuteCommand: ConsoleStoreReducer<
if (!commandDefinition) { if (!commandDefinition) {
return updateStateWithNewCommandHistoryItem( return updateStateWithNewCommandHistoryItem(
state, state,
createCommandHistoryEntry({ createCommandHistoryEntry(
input: parsedInput.input, {
args: parsedInput, input: parsedInput.input,
commandDefinition: { args: parsedInput,
...UnknownCommandDefinition, commandDefinition: {
RenderComponent: UnknownCommand, ...UnknownCommandDefinition,
RenderComponent: UnknownCommand,
},
}, },
}) undefined,
false
)
); );
} }
@ -185,7 +191,9 @@ export const handleExecuteCommand: ConsoleStoreReducer<
return updateStateWithNewCommandHistoryItem( return updateStateWithNewCommandHistoryItem(
state, state,
createCommandHistoryEntry( createCommandHistoryEntry(
cloneCommandDefinitionWithNewRenderComponent(command, HelpCommandArgument) cloneCommandDefinitionWithNewRenderComponent(command, HelpCommandArgument),
undefined,
false
) )
); );
} }
@ -203,7 +211,8 @@ export const handleExecuteCommand: ConsoleStoreReducer<
defaultMessage: 'Command does not support any arguments', defaultMessage: 'Command does not support any arguments',
} }
), ),
}) }),
false
) )
); );
} }
@ -238,7 +247,8 @@ export const handleExecuteCommand: ConsoleStoreReducer<
/> />
</ConsoleCodeBlock> </ConsoleCodeBlock>
), ),
}) }),
false
) )
); );
} }
@ -265,7 +275,8 @@ export const handleExecuteCommand: ConsoleStoreReducer<
)} )}
</ConsoleCodeBlock> </ConsoleCodeBlock>
), ),
}) }),
false
) )
); );
} }
@ -280,7 +291,8 @@ export const handleExecuteCommand: ConsoleStoreReducer<
cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), cloneCommandDefinitionWithNewRenderComponent(command, BadArgument),
createCommandExecutionState({ createCommandExecutionState({
errorMessage: exclusiveOrErrorMessage, errorMessage: exclusiveOrErrorMessage,
}) }),
false
) )
); );
} }
@ -309,7 +321,8 @@ export const handleExecuteCommand: ConsoleStoreReducer<
)} )}
</ConsoleCodeBlock> </ConsoleCodeBlock>
), ),
}) }),
false
) )
); );
} }
@ -332,7 +345,8 @@ export const handleExecuteCommand: ConsoleStoreReducer<
)} )}
</ConsoleCodeBlock> </ConsoleCodeBlock>
), ),
}) }),
false
) )
); );
} }
@ -357,7 +371,8 @@ export const handleExecuteCommand: ConsoleStoreReducer<
)} )}
</ConsoleCodeBlock> </ConsoleCodeBlock>
), ),
}) }),
false
) )
); );
} }
@ -381,7 +396,8 @@ export const handleExecuteCommand: ConsoleStoreReducer<
})} })}
</ConsoleCodeBlock> </ConsoleCodeBlock>
), ),
}) }),
false
) )
); );
} else if (exclusiveOrArgs.length > 0) { } else if (exclusiveOrArgs.length > 0) {
@ -391,7 +407,8 @@ export const handleExecuteCommand: ConsoleStoreReducer<
cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), cloneCommandDefinitionWithNewRenderComponent(command, BadArgument),
createCommandExecutionState({ createCommandExecutionState({
errorMessage: exclusiveOrErrorMessage, errorMessage: exclusiveOrErrorMessage,
}) }),
false
) )
); );
} else if (commandDefinition.mustHaveArgs) { } else if (commandDefinition.mustHaveArgs) {
@ -407,7 +424,8 @@ export const handleExecuteCommand: ConsoleStoreReducer<
})} })}
</ConsoleCodeBlock> </ConsoleCodeBlock>
), ),
}) }),
false
) )
); );
} }
@ -423,7 +441,8 @@ export const handleExecuteCommand: ConsoleStoreReducer<
cloneCommandDefinitionWithNewRenderComponent(command, BadArgument), cloneCommandDefinitionWithNewRenderComponent(command, BadArgument),
createCommandExecutionState({ createCommandExecutionState({
errorMessage: validationResult, errorMessage: validationResult,
}) }),
false
) )
); );
} }

View file

@ -79,6 +79,7 @@ export interface InputHistoryItem {
export interface CommandHistoryItem { export interface CommandHistoryItem {
id: string; id: string;
enteredAt: string; enteredAt: string;
isValid: boolean;
command: Command; command: Command;
state: CommandExecutionState; state: CommandExecutionState;
} }

View file

@ -5,8 +5,8 @@
* 2.0. * 2.0.
*/ */
import React, { memo } from 'react'; import React, { memo, useMemo } from 'react';
import { EuiCode } from '@elastic/eui'; import { EuiCode, EuiTextColor } from '@elastic/eui';
import styled from 'styled-components'; import styled from 'styled-components';
import { useTestIdGenerator } from '../../../hooks/use_test_id_generator'; import { useTestIdGenerator } from '../../../hooks/use_test_id_generator';
import { useDataTestSubj } from '../hooks/state_selectors/use_data_test_subj'; import { useDataTestSubj } from '../hooks/state_selectors/use_data_test_subj';
@ -17,18 +17,19 @@ const StyledEuiCode = styled(EuiCode)`
export interface UserCommandInputProps { export interface UserCommandInputProps {
input: string; input: string;
isValid?: boolean;
} }
export const UserCommandInput = memo<UserCommandInputProps>(({ input }) => { export const UserCommandInput = memo<UserCommandInputProps>(({ input, isValid = true }) => {
const getTestId = useTestIdGenerator(useDataTestSubj()); const getTestId = useTestIdGenerator(useDataTestSubj());
const displayInputValue = useMemo(() => {
return isValid ? input : <EuiTextColor>{input}</EuiTextColor>;
}, [input, isValid]);
return ( return (
<StyledEuiCode <StyledEuiCode transparentBackground={true} data-test-subj={getTestId('userCommandText')}>
language="shell" {displayInputValue}
transparentBackground={true}
data-test-subj={getTestId('userCommandText')}
>
{input}
</StyledEuiCode> </StyledEuiCode>
); );
}); });