mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-06-21 15:36:34 +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 { Select } from 'antd';
|
||||||
import { BaseOptionType } from 'antd/es/select';
|
import { BaseOptionType } from 'antd/es/select';
|
||||||
import getTagValue from 'api/trace/getTagValue';
|
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 { useQuery } from 'react-query';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
@ -17,6 +17,7 @@ import {
|
|||||||
getTagValueOptions,
|
getTagValueOptions,
|
||||||
onTagValueChange,
|
onTagValueChange,
|
||||||
selectOptions,
|
selectOptions,
|
||||||
|
separateTagValues,
|
||||||
TagValueTypes,
|
TagValueTypes,
|
||||||
} from './utils';
|
} from './utils';
|
||||||
|
|
||||||
@ -81,66 +82,27 @@ function TagValue(props: TagValueProps): JSX.Element {
|
|||||||
[index, selectedKey, selectedOperator, setLocalSelectedTags],
|
[index, selectedKey, selectedOperator, setLocalSelectedTags],
|
||||||
);
|
);
|
||||||
|
|
||||||
const onSetLocalValue = useCallback(() => {
|
const onChangeHandler = useCallback(
|
||||||
setLocalTagValue([]);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const onSelectedHandler = useCallback(
|
|
||||||
(value: unknown) => {
|
(value: unknown) => {
|
||||||
if (
|
const updatedValues = onTagValueChange(value);
|
||||||
typeof value === 'number' ||
|
setLocalTagValue(updatedValues);
|
||||||
(typeof value === 'string' && !Number.isNaN(Number(value)) && value !== ' ')
|
const { boolValues, numberValues, stringValues } = separateTagValues(
|
||||||
) {
|
updatedValues,
|
||||||
setLocalTagValue([value]);
|
selectedKey,
|
||||||
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(
|
setLocalSelectedTags((tags) => [
|
||||||
(value: unknown) => onTagValueChange(value, setLocalTagValue),
|
...tags.slice(0, index),
|
||||||
[],
|
{
|
||||||
|
...tags[index],
|
||||||
|
BoolValues: boolValues,
|
||||||
|
NumberValues: numberValues,
|
||||||
|
StringValues: stringValues,
|
||||||
|
},
|
||||||
|
...tags.slice(index + 1),
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
[index, setLocalSelectedTags, selectedKey],
|
||||||
);
|
);
|
||||||
|
|
||||||
const getFilterOptions = useCallback(
|
const getFilterOptions = useCallback(
|
||||||
@ -159,14 +121,11 @@ function TagValue(props: TagValueProps): JSX.Element {
|
|||||||
options={getTagValueOptions(data?.payload, tagType)}
|
options={getTagValueOptions(data?.payload, tagType)}
|
||||||
mode="tags"
|
mode="tags"
|
||||||
allowClear
|
allowClear
|
||||||
onClear={onSetLocalValue}
|
|
||||||
onDeselect={onSetLocalValue}
|
|
||||||
showSearch
|
showSearch
|
||||||
filterOption={getFilterOptions}
|
filterOption={getFilterOptions}
|
||||||
disabled={isLoading || tagValueDisabled}
|
disabled={isLoading || tagValueDisabled}
|
||||||
value={localTagValue}
|
value={localTagValue}
|
||||||
onChange={onChangeHandler}
|
onChange={onChangeHandler}
|
||||||
onSelect={onSelectedHandler}
|
|
||||||
>
|
>
|
||||||
{selectOptions(data?.payload, tagType)?.map((suggestion) => (
|
{selectOptions(data?.payload, tagType)?.map((suggestion) => (
|
||||||
<Select.Option key={suggestion.toString()} value={suggestion}>
|
<Select.Option key={suggestion.toString()} value={suggestion}>
|
||||||
@ -186,4 +145,4 @@ interface TagValueProps {
|
|||||||
tagKey: string;
|
tagKey: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TagValue;
|
export default memo(TagValue);
|
||||||
|
@ -50,23 +50,56 @@ export const extractTagKey = (tagKey: string): string => {
|
|||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
export function onTagValueChange(
|
export function onTagValueChange(values: unknown): TagValueTypes[] {
|
||||||
values: unknown,
|
const stringValues = values as string[];
|
||||||
setLocalValue: React.Dispatch<React.SetStateAction<TagValueTypes[]>>,
|
|
||||||
): void {
|
if (!Array.isArray(stringValues) || stringValues.length === 0) {
|
||||||
if (Array.isArray(values) && values.length > 0) {
|
return [];
|
||||||
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]]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(
|
export function disableTagValue(
|
||||||
@ -93,22 +126,16 @@ export function disableTagValue(
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getInitialLocalValue(
|
export function getInitialLocalValue(
|
||||||
selectedNumberValues: number[],
|
selectedNumberValues: number[],
|
||||||
selectedBoolValues: boolean[],
|
selectedBoolValues: boolean[],
|
||||||
selectedStringValues: string[],
|
selectedStringValues: string[],
|
||||||
): TagValueTypes[] {
|
): TagValueTypes[] {
|
||||||
if (selectedStringValues && selectedStringValues.length > 0) {
|
return [
|
||||||
return selectedStringValues;
|
...selectedBoolValues,
|
||||||
}
|
...selectedNumberValues,
|
||||||
if (selectedNumberValues && selectedNumberValues.length > 0) {
|
...selectedStringValues,
|
||||||
return selectedNumberValues;
|
];
|
||||||
}
|
|
||||||
if (selectedBoolValues && selectedBoolValues.length > 0) {
|
|
||||||
return selectedBoolValues;
|
|
||||||
}
|
|
||||||
return selectedStringValues;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTagValueOptions(
|
export function getTagValueOptions(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user