Skip to content

Commit 30695fb

Browse files
authored
[Security Solution][Exceptions] - Updates autocomplete validation for numbers and boolean (#74561)
## Summary This PR chips a bit at some stricter value validations that have been discussed. Further validation is needed, but this adds some more basic validation. - **Current:** if selected field is of type `boolean` users can add custom values in combo box - **Now:** if selected field is of type `boolean` users can only select `true` or `false` - **Current:** if selected field is of type `number` (that is kibana type number) user can input any values - **Now:** if selected field is of type `number` and no autocomplete suggestions are available, number input is used to restrict users - **Current:** for operator `match_any` it's conducting an autocomplete search after each selection resulting in some jumpy/weird behavior - **Now:** only conducts autocomplete search on initial field selection and if user enters value to search - **Current:** only validations on type date - **Now:** validation on type (Kibana type) date, number - **Current:** input would show red when there was an error but user could still submit - **Now:** submit button is disabled if error exists
1 parent e60cfa0 commit 30695fb

25 files changed

+1392
-388
lines changed

x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_exists.tsx

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,28 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66
import React from 'react';
7-
import { EuiComboBox } from '@elastic/eui';
7+
import { EuiFormRow, EuiComboBox } from '@elastic/eui';
88

99
interface AutocompleteFieldExistsProps {
1010
placeholder: string;
11+
rowLabel?: string;
1112
}
1213

1314
export const AutocompleteFieldExistsComponent: React.FC<AutocompleteFieldExistsProps> = ({
1415
placeholder,
16+
rowLabel,
1517
}): JSX.Element => (
16-
<EuiComboBox
17-
placeholder={placeholder}
18-
options={[]}
19-
selectedOptions={[]}
20-
onChange={undefined}
21-
isDisabled
22-
data-test-subj="valuesAutocompleteComboBox existsComboxBox"
23-
fullWidth
24-
/>
18+
<EuiFormRow label={rowLabel} fullWidth>
19+
<EuiComboBox
20+
placeholder={placeholder}
21+
options={[]}
22+
selectedOptions={[]}
23+
onChange={undefined}
24+
isDisabled
25+
data-test-subj="valuesAutocompleteComboBox existsComboxBox"
26+
fullWidth
27+
/>
28+
</EuiFormRow>
2529
);
2630

2731
AutocompleteFieldExistsComponent.displayName = 'AutocompleteFieldExists';

x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.tsx

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66
import React, { useState, useEffect, useCallback, useMemo } from 'react';
7-
import { EuiComboBoxOptionOption, EuiComboBox } from '@elastic/eui';
7+
import { EuiFormRow, EuiComboBoxOptionOption, EuiComboBox } from '@elastic/eui';
88

99
import { IFieldType } from '../../../../../../../src/plugins/data/common';
1010
import { useFindLists, ListSchema } from '../../../lists_plugin_deps';
1111
import { useKibana } from '../../../common/lib/kibana';
12-
import { getGenericComboBoxProps, paramIsValid } from './helpers';
12+
import { getGenericComboBoxProps } from './helpers';
13+
import * as i18n from './translations';
1314

1415
interface AutocompleteFieldListsProps {
1516
placeholder: string;
@@ -19,11 +20,13 @@ interface AutocompleteFieldListsProps {
1920
isDisabled: boolean;
2021
isClearable: boolean;
2122
isRequired?: boolean;
23+
rowLabel?: string;
2224
onChange: (arg: ListSchema) => void;
2325
}
2426

2527
export const AutocompleteFieldListsComponent: React.FC<AutocompleteFieldListsProps> = ({
2628
placeholder,
29+
rowLabel,
2730
selectedField,
2831
selectedValue,
2932
isLoading = false,
@@ -32,7 +35,7 @@ export const AutocompleteFieldListsComponent: React.FC<AutocompleteFieldListsPro
3235
isRequired = false,
3336
onChange,
3437
}): JSX.Element => {
35-
const [touched, setIsTouched] = useState(false);
38+
const [error, setError] = useState<string | undefined>(undefined);
3639
const { http } = useKibana().services;
3740
const [lists, setLists] = useState<ListSchema[]>([]);
3841
const { loading, result, start } = useFindLists();
@@ -75,7 +78,9 @@ export const AutocompleteFieldListsComponent: React.FC<AutocompleteFieldListsPro
7578
[labels, optionsMemo, onChange]
7679
);
7780

78-
const setIsTouchedValue = useCallback(() => setIsTouched(true), [setIsTouched]);
81+
const setIsTouchedValue = useCallback((): void => {
82+
setError(selectedValue == null ? i18n.FIELD_REQUIRED_ERR : undefined);
83+
}, [selectedValue]);
7984

8085
useEffect(() => {
8186
if (result != null) {
@@ -93,30 +98,27 @@ export const AutocompleteFieldListsComponent: React.FC<AutocompleteFieldListsPro
9398
}
9499
}, [selectedField, start, http]);
95100

96-
const isValid = useMemo(
97-
(): boolean => paramIsValid(selectedValue, selectedField, isRequired, touched),
98-
[selectedField, selectedValue, isRequired, touched]
99-
);
100-
101101
const isLoadingState = useMemo((): boolean => isLoading || loading, [isLoading, loading]);
102102

103103
return (
104-
<EuiComboBox
105-
placeholder={placeholder}
106-
isDisabled={isDisabled}
107-
isLoading={isLoadingState}
108-
isClearable={isClearable}
109-
options={comboOptions}
110-
selectedOptions={selectedComboOptions}
111-
onChange={handleValuesChange}
112-
isInvalid={!isValid}
113-
onFocus={setIsTouchedValue}
114-
singleSelection={{ asPlainText: true }}
115-
sortMatchesBy="startsWith"
116-
data-test-subj="valuesAutocompleteComboBox listsComboxBox"
117-
fullWidth
118-
async
119-
/>
104+
<EuiFormRow label={rowLabel} error={error} isInvalid={error != null} fullWidth>
105+
<EuiComboBox
106+
placeholder={placeholder}
107+
isDisabled={isDisabled}
108+
isLoading={isLoadingState}
109+
isClearable={isClearable}
110+
options={comboOptions}
111+
selectedOptions={selectedComboOptions}
112+
onChange={handleValuesChange}
113+
isInvalid={error != null}
114+
onBlur={setIsTouchedValue}
115+
singleSelection={{ asPlainText: true }}
116+
sortMatchesBy="startsWith"
117+
data-test-subj="valuesAutocompleteComboBox listsComboxBox"
118+
fullWidth
119+
async
120+
/>
121+
</EuiFormRow>
120122
);
121123
};
122124

0 commit comments

Comments
 (0)