fix: having filter removing payload (#2706)

This commit is contained in:
Yevhen Shevchenko 2023-05-18 14:14:34 +03:00 committed by GitHub
parent 679eb39256
commit 18fc1a2761
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 458 additions and 120 deletions

View File

@ -6,7 +6,11 @@ import createQueryParams from 'lib/createQueryParams';
import { ErrorResponse, SuccessResponse } from 'types/api'; import { ErrorResponse, SuccessResponse } from 'types/api';
// ** Types // ** Types
import { IGetAggregateAttributePayload } from 'types/api/queryBuilder/getAggregatorAttribute'; import { IGetAggregateAttributePayload } from 'types/api/queryBuilder/getAggregatorAttribute';
import { IQueryAutocompleteResponse } from 'types/api/queryBuilder/queryAutocompleteResponse'; import {
BaseAutocompleteData,
IQueryAutocompleteResponse,
} from 'types/api/queryBuilder/queryAutocompleteResponse';
import { v4 as uuid } from 'uuid';
export const getAggregateAttribute = async ({ export const getAggregateAttribute = async ({
aggregateOperator, aggregateOperator,
@ -26,11 +30,15 @@ export const getAggregateAttribute = async ({
})}`, })}`,
); );
const payload: BaseAutocompleteData[] =
response.data.data.attributeKeys?.map((item) => ({ ...item, id: uuid() })) ||
[];
return { return {
statusCode: 200, statusCode: 200,
error: null, error: null,
message: response.statusText, message: response.statusText,
payload: response.data.data, payload: { attributeKeys: payload },
}; };
} catch (e) { } catch (e) {
return ErrorResponseHandler(e as AxiosError); return ErrorResponseHandler(e as AxiosError);

View File

@ -5,7 +5,11 @@ import createQueryParams from 'lib/createQueryParams';
import { ErrorResponse, SuccessResponse } from 'types/api'; import { ErrorResponse, SuccessResponse } from 'types/api';
// ** Types // ** Types
import { IGetAttributeKeysPayload } from 'types/api/queryBuilder/getAttributeKeys'; import { IGetAttributeKeysPayload } from 'types/api/queryBuilder/getAttributeKeys';
import { IQueryAutocompleteResponse } from 'types/api/queryBuilder/queryAutocompleteResponse'; import {
BaseAutocompleteData,
IQueryAutocompleteResponse,
} from 'types/api/queryBuilder/queryAutocompleteResponse';
import { v4 as uuid } from 'uuid';
export const getAggregateKeys = async ({ export const getAggregateKeys = async ({
aggregateOperator, aggregateOperator,
@ -28,11 +32,15 @@ export const getAggregateKeys = async ({
})}&tagType=${tagType}`, })}&tagType=${tagType}`,
); );
const payload: BaseAutocompleteData[] =
response.data.data.attributeKeys?.map((item) => ({ ...item, id: uuid() })) ||
[];
return { return {
statusCode: 200, statusCode: 200,
error: null, error: null,
message: response.statusText, message: response.statusText,
payload: response.data.data, payload: { attributeKeys: payload },
}; };
} catch (e) { } catch (e) {
return ErrorResponseHandler(e as AxiosError); return ErrorResponseHandler(e as AxiosError);

View File

@ -10,20 +10,27 @@ import {
import { import {
BoolOperators, BoolOperators,
DataSource, DataSource,
LogsAggregatorOperator,
MetricAggregateOperator, MetricAggregateOperator,
NumberOperators, NumberOperators,
PanelTypeKeys, PanelTypeKeys,
QueryAdditionalFilter, QueryAdditionalFilter,
ReduceOperators, ReduceOperators,
StringOperators, StringOperators,
TracesAggregatorOperator,
} from 'types/common/queryBuilder'; } from 'types/common/queryBuilder';
import { SelectOption } from 'types/common/select'; import { SelectOption } from 'types/common/select';
import { v4 as uuid } from 'uuid';
import {
logsAggregateOperatorOptions,
metricAggregateOperatorOptions,
tracesAggregateOperatorOptions,
} from './queryBuilderOperators';
export const MAX_FORMULAS = 20; export const MAX_FORMULAS = 20;
export const MAX_QUERIES = 26; export const MAX_QUERIES = 26;
export const selectValueDivider = '--';
export const formulasNames: string[] = Array.from( export const formulasNames: string[] = Array.from(
Array(MAX_FORMULAS), Array(MAX_FORMULAS),
(_, i) => `F${i + 1}`, (_, i) => `F${i + 1}`,
@ -37,10 +44,10 @@ export enum QueryBuilderKeys {
GET_ATTRIBUTE_KEY = 'GET_ATTRIBUTE_KEY', GET_ATTRIBUTE_KEY = 'GET_ATTRIBUTE_KEY',
} }
export const mapOfOperators: Record<DataSource, string[]> = { export const mapOfOperators = {
metrics: Object.values(MetricAggregateOperator), metrics: metricAggregateOperatorOptions,
logs: Object.values(LogsAggregatorOperator), logs: logsAggregateOperatorOptions,
traces: Object.values(TracesAggregatorOperator), traces: tracesAggregateOperatorOptions,
}; };
export const mapOfFilters: Record<DataSource, QueryAdditionalFilter[]> = { export const mapOfFilters: Record<DataSource, QueryAdditionalFilter[]> = {
@ -78,6 +85,7 @@ export const initialHavingValues: HavingForm = {
}; };
export const initialAggregateAttribute: IBuilderQuery['aggregateAttribute'] = { export const initialAggregateAttribute: IBuilderQuery['aggregateAttribute'] = {
id: uuid(),
dataType: null, dataType: null,
key: '', key: '',
isColumn: null, isColumn: null,

View File

@ -0,0 +1,304 @@
import {
LogsAggregatorOperator,
MetricAggregateOperator,
TracesAggregatorOperator,
} from 'types/common/queryBuilder';
import { SelectOption } from 'types/common/select';
export const metricAggregateOperatorOptions: SelectOption<string, string>[] = [
{
value: MetricAggregateOperator.NOOP,
label: 'NOOP',
},
{
value: MetricAggregateOperator.COUNT,
label: 'Count',
},
{
value: MetricAggregateOperator.COUNT_DISTINCT,
// eslint-disable-next-line sonarjs/no-duplicate-string
label: 'Count Distinct',
},
{
value: MetricAggregateOperator.SUM,
label: 'Sum',
},
{
value: MetricAggregateOperator.AVG,
label: 'Avg',
},
{
value: MetricAggregateOperator.MAX,
label: 'Max',
},
{
value: MetricAggregateOperator.MIN,
label: 'Min',
},
{
value: MetricAggregateOperator.P05,
label: 'P05',
},
{
value: MetricAggregateOperator.P10,
label: 'P10',
},
{
value: MetricAggregateOperator.P20,
label: 'P20',
},
{
value: MetricAggregateOperator.P25,
label: 'P25',
},
{
value: MetricAggregateOperator.P50,
label: 'P50',
},
{
value: MetricAggregateOperator.P75,
label: 'P75',
},
{
value: MetricAggregateOperator.P90,
label: 'P90',
},
{
value: MetricAggregateOperator.P95,
label: 'P95',
},
{
value: MetricAggregateOperator.P99,
label: 'P99',
},
{
value: MetricAggregateOperator.RATE,
label: 'Rate',
},
{
value: MetricAggregateOperator.SUM_RATE,
label: 'Sum_rate',
},
{
value: MetricAggregateOperator.AVG_RATE,
label: 'Avg_rate',
},
{
value: MetricAggregateOperator.MAX_RATE,
label: 'Max_rate',
},
{
value: MetricAggregateOperator.MIN_RATE,
label: 'Min_rate',
},
{
value: MetricAggregateOperator.RATE_SUM,
label: 'Rate_sum',
},
{
value: MetricAggregateOperator.RATE_AVG,
label: 'Rate_avg',
},
{
value: MetricAggregateOperator.RATE_MIN,
label: 'Rate_min',
},
{
value: MetricAggregateOperator.RATE_MAX,
label: 'Rate_max',
},
{
value: MetricAggregateOperator.HIST_QUANTILE_50,
label: 'Hist_quantile_50',
},
{
value: MetricAggregateOperator.HIST_QUANTILE_75,
label: 'Hist_quantile_75',
},
{
value: MetricAggregateOperator.HIST_QUANTILE_90,
label: 'Hist_quantile_90',
},
{
value: MetricAggregateOperator.HIST_QUANTILE_95,
label: 'Hist_quantile_95',
},
{
value: MetricAggregateOperator.HIST_QUANTILE_99,
label: 'Hist_quantile_99',
},
];
export const tracesAggregateOperatorOptions: SelectOption<string, string>[] = [
{
value: TracesAggregatorOperator.NOOP,
label: 'NOOP',
},
{
value: TracesAggregatorOperator.COUNT,
label: 'Count',
},
{
value: TracesAggregatorOperator.COUNT_DISTINCT,
label: 'Count Distinct',
},
{
value: TracesAggregatorOperator.SUM,
label: 'Sum',
},
{
value: TracesAggregatorOperator.AVG,
label: 'Avg',
},
{
value: TracesAggregatorOperator.MAX,
label: 'Max',
},
{
value: TracesAggregatorOperator.MIN,
label: 'Min',
},
{
value: TracesAggregatorOperator.P05,
label: 'P05',
},
{
value: TracesAggregatorOperator.P10,
label: 'P10',
},
{
value: TracesAggregatorOperator.P20,
label: 'P20',
},
{
value: TracesAggregatorOperator.P25,
label: 'P25',
},
{
value: TracesAggregatorOperator.P50,
label: 'P50',
},
{
value: TracesAggregatorOperator.P75,
label: 'P75',
},
{
value: TracesAggregatorOperator.P90,
label: 'P90',
},
{
value: TracesAggregatorOperator.P95,
label: 'P95',
},
{
value: TracesAggregatorOperator.P99,
label: 'P99',
},
{
value: TracesAggregatorOperator.RATE,
label: 'Rate',
},
{
value: TracesAggregatorOperator.RATE_SUM,
label: 'Rate_sum',
},
{
value: TracesAggregatorOperator.RATE_AVG,
label: 'Rate_avg',
},
{
value: TracesAggregatorOperator.RATE_MIN,
label: 'Rate_min',
},
{
value: TracesAggregatorOperator.RATE_MAX,
label: 'Rate_max',
},
];
export const logsAggregateOperatorOptions: SelectOption<string, string>[] = [
{
value: LogsAggregatorOperator.NOOP,
label: 'NOOP',
},
{
value: LogsAggregatorOperator.COUNT,
label: 'Count',
},
{
value: LogsAggregatorOperator.COUNT_DISTINCT,
label: 'Count Distinct',
},
{
value: LogsAggregatorOperator.SUM,
label: 'Sum',
},
{
value: LogsAggregatorOperator.AVG,
label: 'Avg',
},
{
value: LogsAggregatorOperator.MAX,
label: 'Max',
},
{
value: LogsAggregatorOperator.MIN,
label: 'Min',
},
{
value: LogsAggregatorOperator.P05,
label: 'P05',
},
{
value: LogsAggregatorOperator.P10,
label: 'P10',
},
{
value: LogsAggregatorOperator.P20,
label: 'P20',
},
{
value: LogsAggregatorOperator.P25,
label: 'P25',
},
{
value: LogsAggregatorOperator.P50,
label: 'P50',
},
{
value: LogsAggregatorOperator.P75,
label: 'P75',
},
{
value: LogsAggregatorOperator.P90,
label: 'P90',
},
{
value: LogsAggregatorOperator.P95,
label: 'P95',
},
{
value: LogsAggregatorOperator.P99,
label: 'P99',
},
{
value: LogsAggregatorOperator.RATE,
label: 'Rate',
},
{
value: LogsAggregatorOperator.RATE_SUM,
label: 'Rate_sum',
},
{
value: LogsAggregatorOperator.RATE_AVG,
label: 'Rate_avg',
},
{
value: LogsAggregatorOperator.RATE_MIN,
label: 'Rate_min',
},
{
value: LogsAggregatorOperator.RATE_MAX,
label: 'Rate_max',
},
];

View File

@ -2,14 +2,19 @@
import { AutoComplete, Spin } from 'antd'; import { AutoComplete, Spin } from 'antd';
// ** Api // ** Api
import { getAggregateAttribute } from 'api/queryBuilder/getAggregateAttribute'; import { getAggregateAttribute } from 'api/queryBuilder/getAggregateAttribute';
import { initialAggregateAttribute } from 'constants/queryBuilder'; import {
initialAggregateAttribute,
QueryBuilderKeys,
selectValueDivider,
} from 'constants/queryBuilder';
import { getFilterObjectValue } from 'lib/newQueryBuilder/getFilterObjectValue'; import { getFilterObjectValue } from 'lib/newQueryBuilder/getFilterObjectValue';
import { transformStringWithPrefix } from 'lib/query/transformStringWithPrefix'; import { transformStringWithPrefix } from 'lib/query/transformStringWithPrefix';
import React, { memo, useMemo, useState } from 'react'; import React, { memo, useCallback, useMemo, useState } from 'react';
import { useQuery } from 'react-query'; import { useQuery } from 'react-query';
import { DataSource } from 'types/common/queryBuilder'; import { DataSource } from 'types/common/queryBuilder';
import { ExtendedSelectOption } from 'types/common/select'; import { ExtendedSelectOption } from 'types/common/select';
import { transformToUpperCase } from 'utils/transformToUpperCase'; import { transformToUpperCase } from 'utils/transformToUpperCase';
import { v4 as uuid } from 'uuid';
import { selectStyle } from '../QueryBuilderSearch/config'; import { selectStyle } from '../QueryBuilderSearch/config';
// ** Types // ** Types
@ -19,57 +24,60 @@ export const AggregatorFilter = memo(function AggregatorFilter({
onChange, onChange,
query, query,
}: AgregatorFilterProps): JSX.Element { }: AgregatorFilterProps): JSX.Element {
const [searchText, setSearchText] = useState<string>(''); const [optionsData, setOptionsData] = useState<ExtendedSelectOption[]>([]);
const { data, isFetching } = useQuery( const { data, isFetching } = useQuery(
[ [
'GET_AGGREGATE_ATTRIBUTE', QueryBuilderKeys.GET_AGGREGATE_ATTRIBUTE,
searchText, query.aggregateAttribute.key,
query.aggregateOperator, query.aggregateOperator,
query.dataSource, query.dataSource,
], ],
async () => async () =>
getAggregateAttribute({ getAggregateAttribute({
searchText, searchText: query.aggregateAttribute.key,
aggregateOperator: query.aggregateOperator, aggregateOperator: query.aggregateOperator,
dataSource: query.dataSource, dataSource: query.dataSource,
}), }),
{ enabled: !!query.aggregateOperator && !!query.dataSource }, {
enabled: !!query.aggregateOperator && !!query.dataSource,
onSuccess: (data) => {
const options: ExtendedSelectOption[] =
data?.payload?.attributeKeys?.map((item) => ({
label: transformStringWithPrefix({
str: item.key,
prefix: item.type || '',
condition: !item.isColumn,
}),
value: `${transformStringWithPrefix({
str: item.key,
prefix: item.type || '',
condition: !item.isColumn,
})}${selectValueDivider}${item.id || uuid()}`,
key: item.id || uuid(),
})) || [];
setOptionsData(options);
},
},
); );
const handleSearchAttribute = (searchText: string): void => { const handleChangeAttribute = useCallback(
const { key } = getFilterObjectValue(searchText); (
setSearchText(key); value: string,
}; option: ExtendedSelectOption | ExtendedSelectOption[],
): void => {
const currentOption = option as ExtendedSelectOption;
const optionsData: ExtendedSelectOption[] = const { key } = getFilterObjectValue(value);
data?.payload?.attributeKeys?.map((item) => ({
label: transformStringWithPrefix({
str: item.key,
prefix: item.type || '',
condition: !item.isColumn,
}),
value: transformStringWithPrefix({
str: item.key,
prefix: item.type || '',
condition: !item.isColumn,
}),
key: transformStringWithPrefix({
str: item.key,
prefix: item.type || '',
condition: !item.isColumn,
}),
})) || [];
const handleChangeAttribute = (value: string): void => { const currentAttributeObj = data?.payload?.attributeKeys?.find(
const { key, isColumn } = getFilterObjectValue(value); (item) => currentOption.key === item.id,
const currentAttributeObj = data?.payload?.attributeKeys?.find( ) || { ...initialAggregateAttribute, key };
(item) => item.key === key && isColumn === item.isColumn,
) || { ...initialAggregateAttribute, key };
setSearchText(''); onChange(currentAttributeObj);
onChange(currentAttributeObj); },
}; [data, onChange],
);
const value = useMemo( const value = useMemo(
() => () =>
@ -88,12 +96,10 @@ export const AggregatorFilter = memo(function AggregatorFilter({
return ( return (
<AutoComplete <AutoComplete
showSearch
placeholder={placeholder} placeholder={placeholder}
style={selectStyle} style={selectStyle}
showArrow={false} showArrow={false}
filterOption={false} filterOption={false}
onSearch={handleSearchAttribute}
notFoundContent={isFetching ? <Spin size="small" /> : null} notFoundContent={isFetching ? <Spin size="small" /> : null}
options={optionsData} options={optionsData}
value={value} value={value}

View File

@ -1,15 +1,16 @@
import { Select, Spin } from 'antd'; import { Select, Spin } from 'antd';
import { getAggregateKeys } from 'api/queryBuilder/getAttributeKeys'; import { getAggregateKeys } from 'api/queryBuilder/getAttributeKeys';
// ** Constants // ** Constants
import { QueryBuilderKeys } from 'constants/queryBuilder'; import { QueryBuilderKeys, selectValueDivider } from 'constants/queryBuilder';
import { getFilterObjectValue } from 'lib/newQueryBuilder/getFilterObjectValue'; import { getFilterObjectValue } from 'lib/newQueryBuilder/getFilterObjectValue';
// ** Components // ** Components
// ** Helpers // ** Helpers
import { transformStringWithPrefix } from 'lib/query/transformStringWithPrefix'; import { transformStringWithPrefix } from 'lib/query/transformStringWithPrefix';
import React, { memo, useMemo, useState } from 'react'; import React, { memo, useState } from 'react';
import { useQuery } from 'react-query'; import { useQuery } from 'react-query';
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse'; import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
import { ExtendedSelectOption } from 'types/common/select'; import { ExtendedSelectOption } from 'types/common/select';
import { v4 as uuid } from 'uuid';
import { selectStyle } from '../QueryBuilderSearch/config'; import { selectStyle } from '../QueryBuilderSearch/config';
import { GroupByFilterProps } from './GroupByFilter.interfaces'; import { GroupByFilterProps } from './GroupByFilter.interfaces';
@ -20,6 +21,7 @@ export const GroupByFilter = memo(function GroupByFilter({
disabled, disabled,
}: GroupByFilterProps): JSX.Element { }: GroupByFilterProps): JSX.Element {
const [searchText, setSearchText] = useState<string>(''); const [searchText, setSearchText] = useState<string>('');
const [optionsData, setOptionsData] = useState<ExtendedSelectOption[]>([]);
const [isFocused, setIsFocused] = useState<boolean>(false); const [isFocused, setIsFocused] = useState<boolean>(false);
const { data, isFetching } = useQuery( const { data, isFetching } = useQuery(
@ -31,7 +33,38 @@ export const GroupByFilter = memo(function GroupByFilter({
aggregateOperator: query.aggregateOperator, aggregateOperator: query.aggregateOperator,
searchText, searchText,
}), }),
{ enabled: !disabled && isFocused, keepPreviousData: true }, {
enabled: !disabled && isFocused,
onSuccess: (data) => {
const keys = query.groupBy.reduce<string[]>((acc, item) => {
acc.push(item.key);
return acc;
}, []);
const filteredOptions: BaseAutocompleteData[] =
data?.payload?.attributeKeys?.filter(
(attrKey) => !keys.includes(attrKey.key),
) || [];
const options: ExtendedSelectOption[] =
filteredOptions.map((item) => ({
label: transformStringWithPrefix({
str: item.key,
prefix: item.type || '',
condition: !item.isColumn,
}),
value: `${transformStringWithPrefix({
str: item.key,
prefix: item.type || '',
condition: !item.isColumn,
})}${selectValueDivider}${item.id || uuid()}`,
key: item.id || uuid(),
title: item.key,
})) || [];
setOptionsData(options);
},
},
); );
const handleSearchKeys = (searchText: string): void => { const handleSearchKeys = (searchText: string): void => {
@ -46,51 +79,27 @@ export const GroupByFilter = memo(function GroupByFilter({
setIsFocused(true); setIsFocused(true);
}; };
const optionsData: ExtendedSelectOption[] = useMemo(() => {
if (data && data.payload && data.payload.attributeKeys) {
return data.payload.attributeKeys.map((item) => ({
label: transformStringWithPrefix({
str: item.key,
prefix: item.type || '',
condition: !item.isColumn,
}),
value: transformStringWithPrefix({
str: item.key,
prefix: item.type || '',
condition: !item.isColumn,
}),
key: transformStringWithPrefix({
str: item.key,
prefix: item.type || '',
condition: !item.isColumn,
}),
}));
}
return [];
}, [data]);
const handleChange = (values: ExtendedSelectOption[]): void => { const handleChange = (values: ExtendedSelectOption[]): void => {
const groupByValues: BaseAutocompleteData[] = values.map((item) => { const groupByValues: BaseAutocompleteData[] = values.map((item) => {
const responseKeys = data?.payload?.attributeKeys || []; const responseKeys = data?.payload?.attributeKeys || [];
const { key, isColumn } = getFilterObjectValue(item.value); const { key } = getFilterObjectValue(item.value);
const existGroupResponse = responseKeys.find( const existGroupResponse = responseKeys.find(
(group) => group.key === key && group.isColumn === isColumn, (group) => group.id === item.key,
); );
if (existGroupResponse) { if (existGroupResponse) {
return existGroupResponse; return existGroupResponse;
} }
const existGroupQuery = query.groupBy.find( const existGroupQuery = query.groupBy.find((group) => group.id === item.key);
(group) => group.key === key && group.isColumn === isColumn,
);
if (existGroupQuery) { if (existGroupQuery) {
return existGroupQuery; return existGroupQuery;
} }
return { return {
id: uuid(),
isColumn: null, isColumn: null,
key, key,
dataType: null, dataType: null,
@ -98,7 +107,6 @@ export const GroupByFilter = memo(function GroupByFilter({
}; };
}); });
setSearchText('');
onChange(groupByValues); onChange(groupByValues);
}; };
@ -108,16 +116,12 @@ export const GroupByFilter = memo(function GroupByFilter({
prefix: item.type || '', prefix: item.type || '',
condition: !item.isColumn, condition: !item.isColumn,
}), }),
key: transformStringWithPrefix({ key: item.id || uuid(),
value: `${transformStringWithPrefix({
str: item.key, str: item.key,
prefix: item.type || '', prefix: item.type || '',
condition: !item.isColumn, condition: !item.isColumn,
}), })}${selectValueDivider}${item.id || uuid()}`,
value: transformStringWithPrefix({
str: item.key,
prefix: item.type || '',
condition: !item.isColumn,
}),
})); }));
return ( return (

View File

@ -204,7 +204,9 @@ export function HavingFilter({
const handleDeselect = (value: string): void => { const handleDeselect = (value: string): void => {
const result = localValues.filter((item) => item !== value); const result = localValues.filter((item) => item !== value);
setLocalValues(result); const having: Having[] = result.map(transformFromStringToHaving);
onChange(having);
resetChanges();
}; };
useEffect(() => { useEffect(() => {

View File

@ -1,7 +1,8 @@
import { SelectProps } from 'antd'; import { SelectProps } from 'antd';
import { SelectOption } from 'types/common/select';
export type OperatorsSelectProps = Omit<SelectProps, 'onChange' | 'value'> & { export type OperatorsSelectProps = Omit<SelectProps, 'onChange' | 'value'> & {
operators: string[]; operators: SelectOption<string, string>[];
onChange: (value: string) => void; onChange: (value: string) => void;
value: string; value: string;
}; };

View File

@ -1,10 +1,7 @@
import { Select } from 'antd'; import { Select } from 'antd';
import React, { memo } from 'react'; import React, { memo } from 'react';
// ** Types
import { SelectOption } from 'types/common/select';
// ** Helpers
import { transformToUpperCase } from 'utils/transformToUpperCase';
// ** Types
import { selectStyle } from '../QueryBuilderSearch/config'; import { selectStyle } from '../QueryBuilderSearch/config';
import { OperatorsSelectProps } from './OperatorsSelect.interfaces'; import { OperatorsSelectProps } from './OperatorsSelect.interfaces';
@ -14,16 +11,9 @@ export const OperatorsSelect = memo(function OperatorsSelect({
onChange, onChange,
...props ...props
}: OperatorsSelectProps): JSX.Element { }: OperatorsSelectProps): JSX.Element {
const operatorsOptions: SelectOption<string, string>[] = operators.map(
(operator) => ({
label: transformToUpperCase(operator),
value: operator,
}),
);
return ( return (
<Select <Select
options={operatorsOptions} options={operators}
value={value} value={value}
onChange={onChange} onChange={onChange}
style={selectStyle} style={selectStyle}

View File

@ -14,6 +14,7 @@ import {
UseQueryOperations, UseQueryOperations,
} from 'types/common/operations.types'; } from 'types/common/operations.types';
import { DataSource } from 'types/common/queryBuilder'; import { DataSource } from 'types/common/queryBuilder';
import { SelectOption } from 'types/common/select';
export const useQueryOperations: UseQueryOperations = ({ query, index }) => { export const useQueryOperations: UseQueryOperations = ({ query, index }) => {
const { const {
@ -21,7 +22,7 @@ export const useQueryOperations: UseQueryOperations = ({ query, index }) => {
removeEntityByIndex, removeEntityByIndex,
panelType, panelType,
} = useQueryBuilder(); } = useQueryBuilder();
const [operators, setOperators] = useState<string[]>([]); const [operators, setOperators] = useState<SelectOption<string, string>[]>([]);
const [listOfAdditionalFilters, setListOfAdditionalFilters] = useState< const [listOfAdditionalFilters, setListOfAdditionalFilters] = useState<
string[] string[]
>([]); >([]);
@ -90,7 +91,7 @@ export const useQueryOperations: UseQueryOperations = ({ query, index }) => {
...query, ...query,
...initCopyResult, ...initCopyResult,
dataSource: nextSource, dataSource: nextSource,
aggregateOperator: newOperators[0], aggregateOperator: newOperators[0].value,
}; };
setOperators(newOperators); setOperators(newOperators);

View File

@ -4,28 +4,30 @@ import {
BaseAutocompleteData, BaseAutocompleteData,
} from 'types/api/queryBuilder/queryAutocompleteResponse'; } from 'types/api/queryBuilder/queryAutocompleteResponse';
const isTypeExist = (str: string): boolean => { const getType = (str: string): AutocompleteType | null => {
const types: AutocompleteType[] = ['tag', 'resource']; const types: AutocompleteType[] = ['tag', 'resource'];
let isExist = false;
let currentType: AutocompleteType | null = null;
types.forEach((type) => { types.forEach((type) => {
if (str.includes(type)) { if (str.includes(type)) {
isExist = true; currentType = type;
} }
}); });
return isExist; return currentType;
}; };
export const getFilterObjectValue = ( export const getFilterObjectValue = (
value: string, value: string,
): Omit<BaseAutocompleteData, 'dataType' | 'type'> => { ): Omit<BaseAutocompleteData, 'dataType' | 'id'> => {
const isExist = isTypeExist(value); const type = getType(value);
if (!isExist) { if (!type) {
return { isColumn: true, key: value }; return { isColumn: true, key: value, type: null };
} }
const splittedValue = value.split(TYPE_ADDON_REGEXP); const splittedValue = value.split(TYPE_ADDON_REGEXP);
return { isColumn: false, key: splittedValue[1] }; return { isColumn: false, key: splittedValue[1], type };
}; };

View File

@ -1,6 +1,7 @@
import { mapOfOperators, PANEL_TYPES } from 'constants/queryBuilder'; import { mapOfOperators, PANEL_TYPES } from 'constants/queryBuilder';
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider'; import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
import { DataSource, StringOperators } from 'types/common/queryBuilder'; import { DataSource, StringOperators } from 'types/common/queryBuilder';
import { SelectOption } from 'types/common/select';
type GetQueryOperatorsParams = { type GetQueryOperatorsParams = {
dataSource: DataSource; dataSource: DataSource;
@ -11,12 +12,12 @@ type GetQueryOperatorsParams = {
export const getOperatorsBySourceAndPanelType = ({ export const getOperatorsBySourceAndPanelType = ({
dataSource, dataSource,
panelType, panelType,
}: GetQueryOperatorsParams): string[] => { }: GetQueryOperatorsParams): SelectOption<string, string>[] => {
let operatorsByDataSource = mapOfOperators[dataSource]; let operatorsByDataSource = mapOfOperators[dataSource];
if (dataSource !== DataSource.METRICS && panelType !== PANEL_TYPES.LIST) { if (dataSource !== DataSource.METRICS && panelType !== PANEL_TYPES.LIST) {
operatorsByDataSource = operatorsByDataSource.filter( operatorsByDataSource = operatorsByDataSource.filter(
(operator) => operator !== StringOperators.NOOP, (operator) => operator.value !== StringOperators.NOOP,
); );
} }

View File

@ -111,7 +111,7 @@ export function QueryBuilderProvider({
aggregateOperator: getOperatorsBySourceAndPanelType({ aggregateOperator: getOperatorsBySourceAndPanelType({
dataSource: initialDataSource, dataSource: initialDataSource,
panelType, panelType,
})[0], })[0].value,
} }
: {}), : {}),
}; };

View File

@ -5,6 +5,7 @@ export type DataType = 'int64' | 'float64' | 'string' | 'bool';
export type AutocompleteType = 'tag' | 'resource'; export type AutocompleteType = 'tag' | 'resource';
export interface BaseAutocompleteData { export interface BaseAutocompleteData {
id?: string;
dataType: DataType | null; dataType: DataType | null;
isColumn: boolean | null; isColumn: boolean | null;
key: string; key: string;
@ -12,5 +13,5 @@ export interface BaseAutocompleteData {
} }
export interface IQueryAutocompleteResponse { export interface IQueryAutocompleteResponse {
attributeKeys: BaseAutocompleteData[]; attributeKeys: BaseAutocompleteData[] | null;
} }

View File

@ -3,6 +3,8 @@ import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteRe
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData'; import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
import { DataSource } from 'types/common/queryBuilder'; import { DataSource } from 'types/common/queryBuilder';
import { SelectOption } from './select';
type UseQueryOperationsParams = Pick<QueryProps, 'index' | 'query'>; type UseQueryOperationsParams = Pick<QueryProps, 'index' | 'query'>;
export type HandleChangeQueryData = < export type HandleChangeQueryData = <
@ -17,7 +19,7 @@ export type UseQueryOperations = (
params: UseQueryOperationsParams, params: UseQueryOperationsParams,
) => { ) => {
isMetricsDataSource: boolean; isMetricsDataSource: boolean;
operators: string[]; operators: SelectOption<string, string>[];
listOfAdditionalFilters: string[]; listOfAdditionalFilters: string[];
handleChangeOperator: (value: string) => void; handleChangeOperator: (value: string) => void;
handleChangeAggregatorAttribute: (value: BaseAutocompleteData) => void; handleChangeAggregatorAttribute: (value: BaseAutocompleteData) => void;