diff --git a/packages/kbn-securitysolution-autocomplete/src/field_value_wildcard/index.test.tsx b/packages/kbn-securitysolution-autocomplete/src/field_value_wildcard/index.test.tsx index 34769a76563c1..26a9307d24d0d 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field_value_wildcard/index.test.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/field_value_wildcard/index.test.tsx @@ -14,6 +14,7 @@ import { AutocompleteFieldWildcardComponent } from '.'; import { useFieldValueAutocomplete } from '../hooks/use_field_value_autocomplete'; import { fields, getField } from '../fields/index.mock'; import { autocompleteStartMock } from '../autocomplete/index.mock'; +import { FILENAME_WILDCARD_WARNING, FILEPATH_WARNING } from '@kbn/securitysolution-utils'; jest.mock('../hooks/use_field_value_autocomplete'); @@ -276,4 +277,116 @@ describe('AutocompleteFieldWildcardComponent', () => { selectedField: getField('file.path.text'), }); }); + + test('it does not invoke "onWarning" when no warning exists', () => { + const mockOnWarning = jest.fn(); + wrapper = mount( + + ); + + act(() => { + ( + wrapper.find(EuiComboBox).props() as unknown as { + onBlur: () => void; + } + ).onBlur(); + }); + + expect(mockOnWarning).not.toHaveBeenCalledWith(true); + }); + + test('it invokes "onWarning" when warning exists', () => { + const mockOnWarning = jest.fn(); + wrapper = mount( + + ); + + act(() => { + ( + wrapper.find(EuiComboBox).props() as unknown as { + onBlur: () => void; + } + ).onBlur(); + }); + + expect(mockOnWarning).toHaveBeenCalledWith(true); + expect( + wrapper + .find('[data-test-subj="valuesAutocompleteWildcardLabel"] div.euiFormHelpText') + .at(0) + .text() + ).toEqual(FILEPATH_WARNING); + }); + + test('it invokes "onWarning" when warning exists and is wildcard warning', () => { + const mockOnWarning = jest.fn(); + wrapper = mount( + + ); + + act(() => { + ( + wrapper.find(EuiComboBox).props() as unknown as { + onBlur: () => void; + } + ).onBlur(); + }); + + expect(mockOnWarning).toHaveBeenCalledWith(true); + const helpText = wrapper + .find('[data-test-subj="valuesAutocompleteWildcardLabel"] div.euiFormHelpText') + .at(0); + expect(helpText.text()).toEqual(FILENAME_WILDCARD_WARNING); + expect(helpText.find('.euiToolTipAnchor')).toBeTruthy(); + }); }); diff --git a/packages/kbn-securitysolution-autocomplete/src/field_value_wildcard/index.tsx b/packages/kbn-securitysolution-autocomplete/src/field_value_wildcard/index.tsx index 159267c3386de..82b9cb029d8dc 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field_value_wildcard/index.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/field_value_wildcard/index.tsx @@ -28,6 +28,7 @@ import { paramIsValid } from '../param_is_valid'; const SINGLE_SELECTION = { asPlainText: true }; +type Warning = string | React.ReactNode; interface AutocompleteFieldWildcardProps { placeholder: string; selectedField: DataViewFieldBase | undefined; @@ -43,7 +44,7 @@ interface AutocompleteFieldWildcardProps { onChange: (arg: string) => void; onError: (arg: boolean) => void; onWarning: (arg: boolean) => void; - warning?: string; + warning?: Warning; } export const AutocompleteFieldWildcardComponent: React.FC = memo( @@ -103,7 +104,7 @@ export const AutocompleteFieldWildcardComponent: React.FC { + (warn: Warning | undefined): void => { onWarning(warn !== undefined); }, [onWarning] @@ -194,9 +195,7 @@ export const AutocompleteFieldWildcardComponent: React.FC { diff --git a/packages/kbn-securitysolution-utils/src/path_validations/index.ts b/packages/kbn-securitysolution-utils/src/path_validations/index.ts index 27d2f31d76d9a..97a726703feef 100644 --- a/packages/kbn-securitysolution-utils/src/path_validations/index.ts +++ b/packages/kbn-securitysolution-utils/src/path_validations/index.ts @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n'; export const FILENAME_WILDCARD_WARNING = i18n.translate('utils.filename.wildcardWarning', { - defaultMessage: `A wildcard in the filename will affect the endpoint's performance`, + defaultMessage: `Using wildcards in file paths can impact Endpoint performance`, }); export const FILEPATH_WARNING = i18n.translate('utils.filename.pathWarning', { diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx index aa24ec6611b97..3832803a54971 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx @@ -6,7 +6,8 @@ */ import React, { useCallback, useMemo } from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiFormRow } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiIconTip } from '@elastic/eui'; import styled from 'styled-components'; import { ExceptionListType, @@ -37,7 +38,11 @@ import { FieldComponent, OperatorComponent, } from '@kbn/securitysolution-autocomplete'; -import { OperatingSystem, validateFilePathInput } from '@kbn/securitysolution-utils'; +import { + FILENAME_WILDCARD_WARNING, + OperatingSystem, + validateFilePathInput, +} from '@kbn/securitysolution-utils'; import { DataViewBase, DataViewFieldBase } from '@kbn/es-query'; import type { AutocompleteStart } from '../../../../../../../src/plugins/data/public'; @@ -268,6 +273,25 @@ export const BuilderEntryItem: React.FC = ({ } }; + // show this when wildcard filename with matches operator + const getWildcardWarning = (precedingWarning: string): React.ReactNode => { + return ( +

+ {precedingWarning}{' '} + + } + size="m" + /> +

+ ); + }; + const getFieldValueComboBox = (type: OperatorTypeEnum, isFirst: boolean): JSX.Element => { switch (type) { case OperatorTypeEnum.MATCH: @@ -319,6 +343,9 @@ export const BuilderEntryItem: React.FC = ({ [os] = osTypes as OperatingSystem[]; } const warning = validateFilePathInput({ os, value: wildcardValue }); + const actualWarning = + warning === FILENAME_WILDCARD_WARNING ? getWildcardWarning(warning) : warning; + return ( = ({ onError={handleError} onChange={handleFieldWildcardValueChange} onWarning={handleWarning} - warning={warning} + warning={actualWarning} placeholder={i18n.EXCEPTION_FIELD_VALUE_PLACEHOLDER} rowLabel={isFirst ? i18n.VALUE : undefined} selectedField={entry.correspondingKeywordField ?? entry.field}