diff --git a/frontend/src/container/Trace/Search/AllTags/Tag/TagValue.tsx b/frontend/src/container/Trace/Search/AllTags/Tag/TagValue.tsx index 22abbe9df7..a74463d5a4 100644 --- a/frontend/src/container/Trace/Search/AllTags/Tag/TagValue.tsx +++ b/frontend/src/container/Trace/Search/AllTags/Tag/TagValue.tsx @@ -1,7 +1,7 @@ import { Select } from 'antd'; import { BaseOptionType } from 'antd/es/select'; import getTagValue from 'api/trace/getTagValue'; -import React, { useCallback, useMemo, useState } from 'react'; +import React, { memo, useCallback, useMemo, useState } from 'react'; import { useQuery } from 'react-query'; import { useSelector } from 'react-redux'; import { AppState } from 'store/reducers'; @@ -17,6 +17,7 @@ import { getTagValueOptions, onTagValueChange, selectOptions, + separateTagValues, TagValueTypes, } from './utils'; @@ -81,66 +82,27 @@ function TagValue(props: TagValueProps): JSX.Element { [index, selectedKey, selectedOperator, setLocalSelectedTags], ); - const onSetLocalValue = useCallback(() => { - setLocalTagValue([]); - }, []); - - const onSelectedHandler = useCallback( - (value: unknown) => { - if ( - typeof value === 'number' || - (typeof value === 'string' && !Number.isNaN(Number(value)) && value !== ' ') - ) { - setLocalTagValue([value]); - setLocalSelectedTags((tags) => [ - ...tags.slice(0, index), - { - Key: selectedKey, - Operator: selectedOperator, - StringValues: [], - NumberValues: [Number(value)], - BoolValues: [], - }, - ...tags.slice(index + 1, tags.length), - ]); - } else if ( - typeof value === 'boolean' || - value === 'true' || - value === 'false' - ) { - setLocalTagValue([value]); - setLocalSelectedTags((tags) => [ - ...tags.slice(0, index), - { - Key: selectedKey, - Operator: selectedOperator, - StringValues: [], - NumberValues: [], - BoolValues: [value === 'true' || value === true], - }, - ...tags.slice(index + 1, tags.length), - ]); - } else if (typeof value === 'string') { - setLocalTagValue([value]); - setLocalSelectedTags((tags) => [ - ...tags.slice(0, index), - { - Key: selectedKey, - Operator: selectedOperator, - StringValues: [value], - NumberValues: [], - BoolValues: [], - }, - ...tags.slice(index + 1, tags.length), - ]); - } - }, - [index, selectedKey, selectedOperator, setLocalSelectedTags], - ); - const onChangeHandler = useCallback( - (value: unknown) => onTagValueChange(value, setLocalTagValue), - [], + (value: unknown) => { + const updatedValues = onTagValueChange(value); + setLocalTagValue(updatedValues); + const { boolValues, numberValues, stringValues } = separateTagValues( + updatedValues, + selectedKey, + ); + + setLocalSelectedTags((tags) => [ + ...tags.slice(0, index), + { + ...tags[index], + BoolValues: boolValues, + NumberValues: numberValues, + StringValues: stringValues, + }, + ...tags.slice(index + 1), + ]); + }, + [index, setLocalSelectedTags, selectedKey], ); const getFilterOptions = useCallback( @@ -159,14 +121,11 @@ function TagValue(props: TagValueProps): JSX.Element { options={getTagValueOptions(data?.payload, tagType)} mode="tags" allowClear - onClear={onSetLocalValue} - onDeselect={onSetLocalValue} showSearch filterOption={getFilterOptions} disabled={isLoading || tagValueDisabled} value={localTagValue} onChange={onChangeHandler} - onSelect={onSelectedHandler} > {selectOptions(data?.payload, tagType)?.map((suggestion) => ( @@ -186,4 +145,4 @@ interface TagValueProps { tagKey: string; } -export default TagValue; +export default memo(TagValue); diff --git a/frontend/src/container/Trace/Search/AllTags/Tag/utils.ts b/frontend/src/container/Trace/Search/AllTags/Tag/utils.ts index 0ac195c3d1..a9367b9c0f 100644 --- a/frontend/src/container/Trace/Search/AllTags/Tag/utils.ts +++ b/frontend/src/container/Trace/Search/AllTags/Tag/utils.ts @@ -50,23 +50,56 @@ export const extractTagKey = (tagKey: string): string => { return ''; }; -export function onTagValueChange( - values: unknown, - setLocalValue: React.Dispatch>, -): void { - if (Array.isArray(values) && values.length > 0) { - if (typeof values[0] === 'number' || typeof values[0] === 'boolean') { - setLocalValue(values); - } else if (typeof values[0] === 'string') { - if (values[0] === 'true' || values[0] === 'false') { - setLocalValue([values[0] === 'true']); - } else if (values[0] !== ' ' && !Number.isNaN(Number(values[0]))) { - setLocalValue([Number(values[0])]); - } else { - setLocalValue([values[0]]); - } - } +export function onTagValueChange(values: unknown): TagValueTypes[] { + const stringValues = values as string[]; + + if (!Array.isArray(stringValues) || stringValues.length === 0) { + return []; } + + return values as TagValueTypes[]; +} + +export function separateTagValues( + values: TagValueTypes[], + selectedKey: string, +): { boolValues: boolean[]; numberValues: number[]; stringValues: string[] } { + if (selectedKey.includes('.(bool)')) { + const boolValues = values.filter( + (value) => typeof value === 'boolean', + ) as boolean[]; + + return { + boolValues, + numberValues: [], + stringValues: [], + }; + } + + if (selectedKey.includes('.(number)')) { + const numberValues = values + .filter((value) => typeof value === 'number' || !Number.isNaN(Number(value))) + .map((value) => Number(value)) as number[]; + return { + boolValues: [], + numberValues, + stringValues: [], + }; + } + + const stringValues = values.filter( + (value) => + typeof value === 'string' && + value !== 'true' && + value !== 'false' && + Number.isNaN(Number(value)), + ) as string[]; + + return { + boolValues: [], + numberValues: [], + stringValues, + }; } export function disableTagValue( @@ -93,22 +126,16 @@ export function disableTagValue( } return false; } - export function getInitialLocalValue( selectedNumberValues: number[], selectedBoolValues: boolean[], selectedStringValues: string[], ): TagValueTypes[] { - if (selectedStringValues && selectedStringValues.length > 0) { - return selectedStringValues; - } - if (selectedNumberValues && selectedNumberValues.length > 0) { - return selectedNumberValues; - } - if (selectedBoolValues && selectedBoolValues.length > 0) { - return selectedBoolValues; - } - return selectedStringValues; + return [ + ...selectedBoolValues, + ...selectedNumberValues, + ...selectedStringValues, + ]; } export function getTagValueOptions(