mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-13 16:19:00 +08:00
fix: having filter removing payload (#2706)
This commit is contained in:
parent
679eb39256
commit
18fc1a2761
@ -6,7 +6,11 @@ import createQueryParams from 'lib/createQueryParams';
|
||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||
// ** Types
|
||||
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 ({
|
||||
aggregateOperator,
|
||||
@ -26,11 +30,15 @@ export const getAggregateAttribute = async ({
|
||||
})}`,
|
||||
);
|
||||
|
||||
const payload: BaseAutocompleteData[] =
|
||||
response.data.data.attributeKeys?.map((item) => ({ ...item, id: uuid() })) ||
|
||||
[];
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
error: null,
|
||||
message: response.statusText,
|
||||
payload: response.data.data,
|
||||
payload: { attributeKeys: payload },
|
||||
};
|
||||
} catch (e) {
|
||||
return ErrorResponseHandler(e as AxiosError);
|
||||
|
@ -5,7 +5,11 @@ import createQueryParams from 'lib/createQueryParams';
|
||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||
// ** Types
|
||||
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 ({
|
||||
aggregateOperator,
|
||||
@ -28,11 +32,15 @@ export const getAggregateKeys = async ({
|
||||
})}&tagType=${tagType}`,
|
||||
);
|
||||
|
||||
const payload: BaseAutocompleteData[] =
|
||||
response.data.data.attributeKeys?.map((item) => ({ ...item, id: uuid() })) ||
|
||||
[];
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
error: null,
|
||||
message: response.statusText,
|
||||
payload: response.data.data,
|
||||
payload: { attributeKeys: payload },
|
||||
};
|
||||
} catch (e) {
|
||||
return ErrorResponseHandler(e as AxiosError);
|
||||
|
@ -10,20 +10,27 @@ import {
|
||||
import {
|
||||
BoolOperators,
|
||||
DataSource,
|
||||
LogsAggregatorOperator,
|
||||
MetricAggregateOperator,
|
||||
NumberOperators,
|
||||
PanelTypeKeys,
|
||||
QueryAdditionalFilter,
|
||||
ReduceOperators,
|
||||
StringOperators,
|
||||
TracesAggregatorOperator,
|
||||
} from 'types/common/queryBuilder';
|
||||
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_QUERIES = 26;
|
||||
|
||||
export const selectValueDivider = '--';
|
||||
|
||||
export const formulasNames: string[] = Array.from(
|
||||
Array(MAX_FORMULAS),
|
||||
(_, i) => `F${i + 1}`,
|
||||
@ -37,10 +44,10 @@ export enum QueryBuilderKeys {
|
||||
GET_ATTRIBUTE_KEY = 'GET_ATTRIBUTE_KEY',
|
||||
}
|
||||
|
||||
export const mapOfOperators: Record<DataSource, string[]> = {
|
||||
metrics: Object.values(MetricAggregateOperator),
|
||||
logs: Object.values(LogsAggregatorOperator),
|
||||
traces: Object.values(TracesAggregatorOperator),
|
||||
export const mapOfOperators = {
|
||||
metrics: metricAggregateOperatorOptions,
|
||||
logs: logsAggregateOperatorOptions,
|
||||
traces: tracesAggregateOperatorOptions,
|
||||
};
|
||||
|
||||
export const mapOfFilters: Record<DataSource, QueryAdditionalFilter[]> = {
|
||||
@ -78,6 +85,7 @@ export const initialHavingValues: HavingForm = {
|
||||
};
|
||||
|
||||
export const initialAggregateAttribute: IBuilderQuery['aggregateAttribute'] = {
|
||||
id: uuid(),
|
||||
dataType: null,
|
||||
key: '',
|
||||
isColumn: null,
|
||||
|
304
frontend/src/constants/queryBuilderOperators.ts
Normal file
304
frontend/src/constants/queryBuilderOperators.ts
Normal 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',
|
||||
},
|
||||
];
|
@ -2,14 +2,19 @@
|
||||
import { AutoComplete, Spin } from 'antd';
|
||||
// ** Api
|
||||
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 { 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 { DataSource } from 'types/common/queryBuilder';
|
||||
import { ExtendedSelectOption } from 'types/common/select';
|
||||
import { transformToUpperCase } from 'utils/transformToUpperCase';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { selectStyle } from '../QueryBuilderSearch/config';
|
||||
// ** Types
|
||||
@ -19,57 +24,60 @@ export const AggregatorFilter = memo(function AggregatorFilter({
|
||||
onChange,
|
||||
query,
|
||||
}: AgregatorFilterProps): JSX.Element {
|
||||
const [searchText, setSearchText] = useState<string>('');
|
||||
|
||||
const [optionsData, setOptionsData] = useState<ExtendedSelectOption[]>([]);
|
||||
const { data, isFetching } = useQuery(
|
||||
[
|
||||
'GET_AGGREGATE_ATTRIBUTE',
|
||||
searchText,
|
||||
QueryBuilderKeys.GET_AGGREGATE_ATTRIBUTE,
|
||||
query.aggregateAttribute.key,
|
||||
query.aggregateOperator,
|
||||
query.dataSource,
|
||||
],
|
||||
async () =>
|
||||
getAggregateAttribute({
|
||||
searchText,
|
||||
searchText: query.aggregateAttribute.key,
|
||||
aggregateOperator: query.aggregateOperator,
|
||||
dataSource: query.dataSource,
|
||||
}),
|
||||
{ enabled: !!query.aggregateOperator && !!query.dataSource },
|
||||
);
|
||||
|
||||
const handleSearchAttribute = (searchText: string): void => {
|
||||
const { key } = getFilterObjectValue(searchText);
|
||||
setSearchText(key);
|
||||
};
|
||||
|
||||
const optionsData: ExtendedSelectOption[] =
|
||||
{
|
||||
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({
|
||||
value: `${transformStringWithPrefix({
|
||||
str: item.key,
|
||||
prefix: item.type || '',
|
||||
condition: !item.isColumn,
|
||||
}),
|
||||
key: transformStringWithPrefix({
|
||||
str: item.key,
|
||||
prefix: item.type || '',
|
||||
condition: !item.isColumn,
|
||||
}),
|
||||
})}${selectValueDivider}${item.id || uuid()}`,
|
||||
key: item.id || uuid(),
|
||||
})) || [];
|
||||
|
||||
const handleChangeAttribute = (value: string): void => {
|
||||
const { key, isColumn } = getFilterObjectValue(value);
|
||||
setOptionsData(options);
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const handleChangeAttribute = useCallback(
|
||||
(
|
||||
value: string,
|
||||
option: ExtendedSelectOption | ExtendedSelectOption[],
|
||||
): void => {
|
||||
const currentOption = option as ExtendedSelectOption;
|
||||
|
||||
const { key } = getFilterObjectValue(value);
|
||||
|
||||
const currentAttributeObj = data?.payload?.attributeKeys?.find(
|
||||
(item) => item.key === key && isColumn === item.isColumn,
|
||||
(item) => currentOption.key === item.id,
|
||||
) || { ...initialAggregateAttribute, key };
|
||||
|
||||
setSearchText('');
|
||||
onChange(currentAttributeObj);
|
||||
};
|
||||
},
|
||||
[data, onChange],
|
||||
);
|
||||
|
||||
const value = useMemo(
|
||||
() =>
|
||||
@ -88,12 +96,10 @@ export const AggregatorFilter = memo(function AggregatorFilter({
|
||||
|
||||
return (
|
||||
<AutoComplete
|
||||
showSearch
|
||||
placeholder={placeholder}
|
||||
style={selectStyle}
|
||||
showArrow={false}
|
||||
filterOption={false}
|
||||
onSearch={handleSearchAttribute}
|
||||
notFoundContent={isFetching ? <Spin size="small" /> : null}
|
||||
options={optionsData}
|
||||
value={value}
|
||||
|
@ -1,15 +1,16 @@
|
||||
import { Select, Spin } from 'antd';
|
||||
import { getAggregateKeys } from 'api/queryBuilder/getAttributeKeys';
|
||||
// ** Constants
|
||||
import { QueryBuilderKeys } from 'constants/queryBuilder';
|
||||
import { QueryBuilderKeys, selectValueDivider } from 'constants/queryBuilder';
|
||||
import { getFilterObjectValue } from 'lib/newQueryBuilder/getFilterObjectValue';
|
||||
// ** Components
|
||||
// ** Helpers
|
||||
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 { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { ExtendedSelectOption } from 'types/common/select';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { selectStyle } from '../QueryBuilderSearch/config';
|
||||
import { GroupByFilterProps } from './GroupByFilter.interfaces';
|
||||
@ -20,6 +21,7 @@ export const GroupByFilter = memo(function GroupByFilter({
|
||||
disabled,
|
||||
}: GroupByFilterProps): JSX.Element {
|
||||
const [searchText, setSearchText] = useState<string>('');
|
||||
const [optionsData, setOptionsData] = useState<ExtendedSelectOption[]>([]);
|
||||
const [isFocused, setIsFocused] = useState<boolean>(false);
|
||||
|
||||
const { data, isFetching } = useQuery(
|
||||
@ -31,7 +33,38 @@ export const GroupByFilter = memo(function GroupByFilter({
|
||||
aggregateOperator: query.aggregateOperator,
|
||||
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 => {
|
||||
@ -46,51 +79,27 @@ export const GroupByFilter = memo(function GroupByFilter({
|
||||
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 groupByValues: BaseAutocompleteData[] = values.map((item) => {
|
||||
const responseKeys = data?.payload?.attributeKeys || [];
|
||||
const { key, isColumn } = getFilterObjectValue(item.value);
|
||||
const { key } = getFilterObjectValue(item.value);
|
||||
|
||||
const existGroupResponse = responseKeys.find(
|
||||
(group) => group.key === key && group.isColumn === isColumn,
|
||||
(group) => group.id === item.key,
|
||||
);
|
||||
|
||||
if (existGroupResponse) {
|
||||
return existGroupResponse;
|
||||
}
|
||||
|
||||
const existGroupQuery = query.groupBy.find(
|
||||
(group) => group.key === key && group.isColumn === isColumn,
|
||||
);
|
||||
const existGroupQuery = query.groupBy.find((group) => group.id === item.key);
|
||||
|
||||
if (existGroupQuery) {
|
||||
return existGroupQuery;
|
||||
}
|
||||
|
||||
return {
|
||||
id: uuid(),
|
||||
isColumn: null,
|
||||
key,
|
||||
dataType: null,
|
||||
@ -98,7 +107,6 @@ export const GroupByFilter = memo(function GroupByFilter({
|
||||
};
|
||||
});
|
||||
|
||||
setSearchText('');
|
||||
onChange(groupByValues);
|
||||
};
|
||||
|
||||
@ -108,16 +116,12 @@ export const GroupByFilter = memo(function GroupByFilter({
|
||||
prefix: item.type || '',
|
||||
condition: !item.isColumn,
|
||||
}),
|
||||
key: transformStringWithPrefix({
|
||||
key: item.id || uuid(),
|
||||
value: `${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()}`,
|
||||
}));
|
||||
|
||||
return (
|
||||
|
@ -204,7 +204,9 @@ export function HavingFilter({
|
||||
|
||||
const handleDeselect = (value: string): void => {
|
||||
const result = localValues.filter((item) => item !== value);
|
||||
setLocalValues(result);
|
||||
const having: Having[] = result.map(transformFromStringToHaving);
|
||||
onChange(having);
|
||||
resetChanges();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { SelectProps } from 'antd';
|
||||
import { SelectOption } from 'types/common/select';
|
||||
|
||||
export type OperatorsSelectProps = Omit<SelectProps, 'onChange' | 'value'> & {
|
||||
operators: string[];
|
||||
operators: SelectOption<string, string>[];
|
||||
onChange: (value: string) => void;
|
||||
value: string;
|
||||
};
|
||||
|
@ -1,10 +1,7 @@
|
||||
import { Select } from 'antd';
|
||||
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 { OperatorsSelectProps } from './OperatorsSelect.interfaces';
|
||||
|
||||
@ -14,16 +11,9 @@ export const OperatorsSelect = memo(function OperatorsSelect({
|
||||
onChange,
|
||||
...props
|
||||
}: OperatorsSelectProps): JSX.Element {
|
||||
const operatorsOptions: SelectOption<string, string>[] = operators.map(
|
||||
(operator) => ({
|
||||
label: transformToUpperCase(operator),
|
||||
value: operator,
|
||||
}),
|
||||
);
|
||||
|
||||
return (
|
||||
<Select
|
||||
options={operatorsOptions}
|
||||
options={operators}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
style={selectStyle}
|
||||
|
@ -14,6 +14,7 @@ import {
|
||||
UseQueryOperations,
|
||||
} from 'types/common/operations.types';
|
||||
import { DataSource } from 'types/common/queryBuilder';
|
||||
import { SelectOption } from 'types/common/select';
|
||||
|
||||
export const useQueryOperations: UseQueryOperations = ({ query, index }) => {
|
||||
const {
|
||||
@ -21,7 +22,7 @@ export const useQueryOperations: UseQueryOperations = ({ query, index }) => {
|
||||
removeEntityByIndex,
|
||||
panelType,
|
||||
} = useQueryBuilder();
|
||||
const [operators, setOperators] = useState<string[]>([]);
|
||||
const [operators, setOperators] = useState<SelectOption<string, string>[]>([]);
|
||||
const [listOfAdditionalFilters, setListOfAdditionalFilters] = useState<
|
||||
string[]
|
||||
>([]);
|
||||
@ -90,7 +91,7 @@ export const useQueryOperations: UseQueryOperations = ({ query, index }) => {
|
||||
...query,
|
||||
...initCopyResult,
|
||||
dataSource: nextSource,
|
||||
aggregateOperator: newOperators[0],
|
||||
aggregateOperator: newOperators[0].value,
|
||||
};
|
||||
|
||||
setOperators(newOperators);
|
||||
|
@ -4,28 +4,30 @@ import {
|
||||
BaseAutocompleteData,
|
||||
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
|
||||
const isTypeExist = (str: string): boolean => {
|
||||
const getType = (str: string): AutocompleteType | null => {
|
||||
const types: AutocompleteType[] = ['tag', 'resource'];
|
||||
let isExist = false;
|
||||
|
||||
let currentType: AutocompleteType | null = null;
|
||||
|
||||
types.forEach((type) => {
|
||||
if (str.includes(type)) {
|
||||
isExist = true;
|
||||
currentType = type;
|
||||
}
|
||||
});
|
||||
|
||||
return isExist;
|
||||
return currentType;
|
||||
};
|
||||
|
||||
export const getFilterObjectValue = (
|
||||
value: string,
|
||||
): Omit<BaseAutocompleteData, 'dataType' | 'type'> => {
|
||||
const isExist = isTypeExist(value);
|
||||
): Omit<BaseAutocompleteData, 'dataType' | 'id'> => {
|
||||
const type = getType(value);
|
||||
|
||||
if (!isExist) {
|
||||
return { isColumn: true, key: value };
|
||||
if (!type) {
|
||||
return { isColumn: true, key: value, type: null };
|
||||
}
|
||||
|
||||
const splittedValue = value.split(TYPE_ADDON_REGEXP);
|
||||
|
||||
return { isColumn: false, key: splittedValue[1] };
|
||||
return { isColumn: false, key: splittedValue[1], type };
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { mapOfOperators, PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
||||
import { DataSource, StringOperators } from 'types/common/queryBuilder';
|
||||
import { SelectOption } from 'types/common/select';
|
||||
|
||||
type GetQueryOperatorsParams = {
|
||||
dataSource: DataSource;
|
||||
@ -11,12 +12,12 @@ type GetQueryOperatorsParams = {
|
||||
export const getOperatorsBySourceAndPanelType = ({
|
||||
dataSource,
|
||||
panelType,
|
||||
}: GetQueryOperatorsParams): string[] => {
|
||||
}: GetQueryOperatorsParams): SelectOption<string, string>[] => {
|
||||
let operatorsByDataSource = mapOfOperators[dataSource];
|
||||
|
||||
if (dataSource !== DataSource.METRICS && panelType !== PANEL_TYPES.LIST) {
|
||||
operatorsByDataSource = operatorsByDataSource.filter(
|
||||
(operator) => operator !== StringOperators.NOOP,
|
||||
(operator) => operator.value !== StringOperators.NOOP,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ export function QueryBuilderProvider({
|
||||
aggregateOperator: getOperatorsBySourceAndPanelType({
|
||||
dataSource: initialDataSource,
|
||||
panelType,
|
||||
})[0],
|
||||
})[0].value,
|
||||
}
|
||||
: {}),
|
||||
};
|
||||
|
@ -5,6 +5,7 @@ export type DataType = 'int64' | 'float64' | 'string' | 'bool';
|
||||
export type AutocompleteType = 'tag' | 'resource';
|
||||
|
||||
export interface BaseAutocompleteData {
|
||||
id?: string;
|
||||
dataType: DataType | null;
|
||||
isColumn: boolean | null;
|
||||
key: string;
|
||||
@ -12,5 +13,5 @@ export interface BaseAutocompleteData {
|
||||
}
|
||||
|
||||
export interface IQueryAutocompleteResponse {
|
||||
attributeKeys: BaseAutocompleteData[];
|
||||
attributeKeys: BaseAutocompleteData[] | null;
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteRe
|
||||
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { DataSource } from 'types/common/queryBuilder';
|
||||
|
||||
import { SelectOption } from './select';
|
||||
|
||||
type UseQueryOperationsParams = Pick<QueryProps, 'index' | 'query'>;
|
||||
|
||||
export type HandleChangeQueryData = <
|
||||
@ -17,7 +19,7 @@ export type UseQueryOperations = (
|
||||
params: UseQueryOperationsParams,
|
||||
) => {
|
||||
isMetricsDataSource: boolean;
|
||||
operators: string[];
|
||||
operators: SelectOption<string, string>[];
|
||||
listOfAdditionalFilters: string[];
|
||||
handleChangeOperator: (value: string) => void;
|
||||
handleChangeAggregatorAttribute: (value: BaseAutocompleteData) => void;
|
||||
|
Loading…
x
Reference in New Issue
Block a user