diff --git a/superset-frontend/src/components/Select/Select.tsx b/superset-frontend/src/components/Select/Select.tsx index fde08fdf3d33..9c7b92c38cf8 100644 --- a/superset-frontend/src/components/Select/Select.tsx +++ b/superset-frontend/src/components/Select/Select.tsx @@ -42,7 +42,7 @@ import Icons from 'src/components/Icons'; import { getClientErrorObject } from 'src/utils/getClientErrorObject'; import { SLOW_DEBOUNCE } from 'src/constants'; import { rankedSearchCompare } from 'src/utils/rankedSearchCompare'; -import { getValue, hasOption } from './utils'; +import { getValue, hasOption, isObject } from './utils'; const { Option } = AntdSelect; @@ -385,18 +385,20 @@ const Select = ( const hasCustomLabels = fullSelectOptions.some(opt => !!opt?.customLabel); - const handleOnSelect = (selectedItem: string | number | AntdLabeledValue) => { + const handleOnSelect = ( + selectedItem: string | number | AntdLabeledValue | undefined, + ) => { if (isSingleMode) { setSelectValue(selectedItem); } else { setSelectValue(previousState => { const array = ensureIsArray(previousState); - const isObject = typeof selectedItem === 'object'; - const value = isObject ? selectedItem.value : selectedItem; + const isLabeledValue = isObject(selectedItem); + const value = isLabeledValue ? selectedItem.value : selectedItem; // Tokenized values can contain duplicated values if (!hasOption(value, array)) { const result = [...array, selectedItem]; - return isObject + return isLabeledValue ? (result as AntdLabeledValue[]) : (result as (string | number)[]); } @@ -406,9 +408,11 @@ const Select = ( setInputValue(''); }; - const handleOnDeselect = (value: string | number | AntdLabeledValue) => { + const handleOnDeselect = ( + value: string | number | AntdLabeledValue | undefined, + ) => { if (Array.isArray(selectValue)) { - if (typeof value === 'number' || typeof value === 'string') { + if (typeof value === 'number' || typeof value === 'string' || !value) { const array = selectValue as (string | number)[]; setSelectValue(array.filter(element => element !== value)); } else { diff --git a/superset-frontend/src/components/Select/utils.ts b/superset-frontend/src/components/Select/utils.ts index 4eda84a7411d..73c6dd353324 100644 --- a/superset-frontend/src/components/Select/utils.ts +++ b/superset-frontend/src/components/Select/utils.ts @@ -25,7 +25,7 @@ import { GroupedOptionsType, } from 'react-select'; -function isObject(value: unknown): value is Record { +export function isObject(value: unknown): value is Record { return ( value !== null && typeof value === 'object' && diff --git a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent/index.tsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent/index.tsx index 58b1b25081f2..4c521d8aad45 100644 --- a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent/index.tsx +++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent/index.tsx @@ -406,11 +406,15 @@ const AdhocFilterEditPopoverSimpleTabContent: React.FC = props => { {...operatorSelectProps} /> {MULTI_OPERATORS.has(operatorId) || suggestions.length > 0 ? ( - + // We need to delay rendering the select because we can't pass a primitive value without options + // We can't pass value = [null] and options=[] + comparatorSelectProps.value && suggestions.length === 0 ? null : ( + + ) ) : (