-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Security Solution][Endpoint] Response Console framework support for …
…argument value selectors (#148693) ## Summary - PR adds the ability for Commands to define custom value selectors - components that will be rendered as the value when the Argument name is entered in the Console. These Argument Selectors can then provide the user with a better UX for selecting data that is not easily entered in the console via text input. - Introduces a File picker Argument Selector (not yet being used by real commands) that will be used in upcoming features. - Introduces a new `mustHaveValue` property to the definition of a command's argument. See PR on github for info.
- Loading branch information
1 parent
cdab97b
commit 9ac065a
Showing
32 changed files
with
1,835 additions
and
348 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
142 changes: 142 additions & 0 deletions
142
...ment/components/console/components/command_input/components/argument_selector_wrapper.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
/* | ||
* 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, useCallback } from 'react'; | ||
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; | ||
import styled, { createGlobalStyle } from 'styled-components'; | ||
import type { EuiTheme } from '@kbn/kibana-react-plugin/common'; | ||
import { useConsoleStateDispatch } from '../../../hooks/state_selectors/use_console_state_dispatch'; | ||
import { useWithCommandArgumentState } from '../../../hooks/state_selectors/use_with_command_argument_state'; | ||
import type { CommandArgDefinition, CommandArgumentValueSelectorProps } from '../../../types'; | ||
|
||
const ArgumentSelectorWrapperContainer = styled.span` | ||
user-select: none; | ||
.selectorContainer { | ||
max-width: 25vw; | ||
display: flex; | ||
align-items: center; | ||
height: 100%; | ||
} | ||
`; | ||
|
||
// FIXME:PT Delete below. Only here for DEV purposes | ||
const DevUxStyles = createGlobalStyle<{ theme: EuiTheme }>` | ||
body { | ||
&.style1 .argSelectorWrapper { | ||
.style1-hide { | ||
display: none; | ||
} | ||
.selectorContainer { | ||
border: ${({ theme: { eui } }) => eui.euiBorderThin}; | ||
border-radius: ${({ theme: { eui } }) => eui.euiBorderRadiusSmall}; | ||
padding: 0 ${({ theme: { eui } }) => eui.euiSizeXS}; | ||
} | ||
} | ||
&.style2 { | ||
.argSelectorWrapper { | ||
border: ${({ theme: { eui } }) => eui.euiBorderThin}; | ||
border-radius: ${({ theme: { eui } }) => eui.euiBorderRadiusSmall}; | ||
overflow: hidden; | ||
& > .euiFlexGroup { | ||
align-items: stretch; | ||
} | ||
.style2-hide { | ||
display: none; | ||
} | ||
.argNameContainer { | ||
background-color: ${({ theme: { eui } }) => eui.euiFormInputGroupLabelBackground}; | ||
} | ||
.argName { | ||
padding-left: ${({ theme: { eui } }) => eui.euiSizeXS}; | ||
height: 100%; | ||
display: flex; | ||
align-items: center; | ||
} | ||
.selectorContainer { | ||
padding: 0 ${({ theme: { eui } }) => eui.euiSizeXS}; | ||
} | ||
} | ||
} | ||
} | ||
`; | ||
|
||
// Type to ensure that `SelectorComponent` is defined | ||
type ArgDefinitionWithRequiredSelector = Omit<CommandArgDefinition, 'SelectorComponent'> & | ||
Pick<Required<CommandArgDefinition>, 'SelectorComponent'>; | ||
|
||
export interface ArgumentSelectorWrapperProps { | ||
argName: string; | ||
argIndex: number; | ||
argDefinition: ArgDefinitionWithRequiredSelector; | ||
} | ||
|
||
/** | ||
* handles displaying a custom argument value selector and manages its state | ||
*/ | ||
export const ArgumentSelectorWrapper = memo<ArgumentSelectorWrapperProps>( | ||
({ argName, argIndex, argDefinition: { SelectorComponent } }) => { | ||
const dispatch = useConsoleStateDispatch(); | ||
const { valueText, value, store } = useWithCommandArgumentState(argName, argIndex); | ||
|
||
const handleSelectorComponentOnChange = useCallback< | ||
CommandArgumentValueSelectorProps['onChange'] | ||
>( | ||
(updates) => { | ||
dispatch({ | ||
type: 'updateInputCommandArgState', | ||
payload: { | ||
name: argName, | ||
instance: argIndex, | ||
state: updates, | ||
}, | ||
}); | ||
}, | ||
[argIndex, argName, dispatch] | ||
); | ||
|
||
return ( | ||
<ArgumentSelectorWrapperContainer className="eui-displayInlineBlock argSelectorWrapper"> | ||
<EuiFlexGroup responsive={false} alignItems="center" gutterSize="none"> | ||
<EuiFlexItem grow={false} className="argNameContainer"> | ||
<div className="argName"> | ||
<span>{`--${argName}=`}</span> | ||
<span className="style1-hide style2-hide">{'"'}</span> | ||
</div> | ||
</EuiFlexItem> | ||
<EuiFlexItem grow={false}> | ||
{/* `div` below ensures that the `SelectorComponent` does NOT inherit the styles of a `flex` container */} | ||
<div className="selectorContainer eui-textTruncate"> | ||
<SelectorComponent | ||
value={value} | ||
valueText={valueText ?? ''} | ||
argName={argName} | ||
argIndex={argIndex} | ||
store={store} | ||
onChange={handleSelectorComponentOnChange} | ||
/> | ||
</div> | ||
</EuiFlexItem> | ||
<EuiFlexItem grow={false} className="style1-hide style2-hide"> | ||
{'"'} | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
|
||
<DevUxStyles /> | ||
</ArgumentSelectorWrapperContainer> | ||
); | ||
} | ||
); | ||
ArgumentSelectorWrapper.displayName = 'ArgumentSelectorWrapper'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.