mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-06-21 05:58:23 +08:00
feat: multiple values can be selected (#2365)
* feat: multiple values can be selected * chore: tag value is updated * fix: handle few edge cases --------- Co-authored-by: makeavish <makeavish786@gmail.com>
This commit is contained in:
parent
174fc107c2
commit
1f44f089e0
@ -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) => (
|
||||
<Select.Option key={suggestion.toString()} value={suggestion}>
|
||||
@ -186,4 +145,4 @@ interface TagValueProps {
|
||||
tagKey: string;
|
||||
}
|
||||
|
||||
export default TagValue;
|
||||
export default memo(TagValue);
|
||||
|
@ -50,23 +50,56 @@ export const extractTagKey = (tagKey: string): string => {
|
||||
return '';
|
||||
};
|
||||
|
||||
export function onTagValueChange(
|
||||
values: unknown,
|
||||
setLocalValue: React.Dispatch<React.SetStateAction<TagValueTypes[]>>,
|
||||
): 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(
|
||||
|
Loading…
x
Reference in New Issue
Block a user