diff --git a/frontend/src/components/CeleryTask/CeleryTaskConfigOptions/useGetCeleryFilters.ts b/frontend/src/components/CeleryTask/CeleryTaskConfigOptions/useGetCeleryFilters.ts index 70570a167cac..640ddd0cabf6 100644 --- a/frontend/src/components/CeleryTask/CeleryTaskConfigOptions/useGetCeleryFilters.ts +++ b/frontend/src/components/CeleryTask/CeleryTaskConfigOptions/useGetCeleryFilters.ts @@ -1,6 +1,7 @@ /* eslint-disable react-hooks/exhaustive-deps */ import { DefaultOptionType } from 'antd/es/select'; import { getAttributesValues } from 'api/queryBuilder/getAttributesValues'; +import { DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY } from 'constants/queryBuilder'; import { REACT_QUERY_KEY } from 'constants/reactQueryKeys'; import { useQuery } from 'react-query'; import { useSelector } from 'react-redux'; @@ -67,9 +68,13 @@ export function useGetAllFilters(props: Filters): GetAllFiltersResponse { const uniqueValues = [ ...new Set( - responses.flatMap( - ({ payload }) => Object.values(payload || {}).find((el) => !!el) || [], - ), + responses.flatMap(({ payload }) => { + if (!payload) return []; + + const dataType = filterAttributeKeyDataType || DataTypes.String; + const key = DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY[dataType]; + return key ? payload[key] || [] : []; + }), ), ]; diff --git a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx index 1051a47c3d7f..6f00073cecd2 100644 --- a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx +++ b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx @@ -10,7 +10,10 @@ import { IQuickFiltersConfig, QuickFiltersSource, } from 'components/QuickFilters/types'; -import { OPERATORS } from 'constants/queryBuilder'; +import { + DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY, + OPERATORS, +} from 'constants/queryBuilder'; import { DEBOUNCE_DELAY } from 'constants/queryBuilderFilterConfig'; import { getOperatorValue } from 'container/QueryBuilder/filters/QueryBuilderSearch/utils'; import { useGetAggregateValues } from 'hooks/queryBuilder/useGetAggregateValues'; @@ -76,12 +79,12 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element { }, ); - const attributeValues: string[] = useMemo( - () => - ((Object.values(data?.payload || {}).find((el) => !!el) || - []) as string[]).filter((val) => !isEmpty(val)), - [data?.payload], - ); + const attributeValues: string[] = useMemo(() => { + const dataType = filter.attributeKey.dataType || DataTypes.String; + const key = DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY[dataType]; + return (data?.payload?.[key] || []).filter((val) => !isEmpty(val)); + }, [data?.payload, filter.attributeKey.dataType]); + const currentAttributeKeys = attributeValues.slice(0, visibleItemsCount); const setSearchTextDebounced = useDebouncedFn((...args) => { diff --git a/frontend/src/constants/queryBuilder.ts b/frontend/src/constants/queryBuilder.ts index 60b38480b4d8..359f4a22de54 100644 --- a/frontend/src/constants/queryBuilder.ts +++ b/frontend/src/constants/queryBuilder.ts @@ -1,6 +1,7 @@ // ** Helpers import { createIdFromObjectFields } from 'lib/createIdFromObjectFields'; import { createNewBuilderItemName } from 'lib/newQueryBuilder/createNewBuilderItemName'; +import { IAttributeValuesResponse } from 'types/api/queryBuilder/getAttributesValues'; import { AutocompleteType, BaseAutocompleteData, @@ -417,3 +418,18 @@ export enum PanelDisplay { PIE = 'Pie', HISTOGRAM = 'Histogram', } + +export const DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY: Record< + DataTypes, + keyof IAttributeValuesResponse +> = { + [DataTypes.String]: 'stringAttributeValues', + [DataTypes.Float64]: 'numberAttributeValues', + [DataTypes.Int64]: 'numberAttributeValues', + [DataTypes.bool]: 'boolAttributeValues', + [DataTypes.ArrayFloat64]: 'numberAttributeValues', + [DataTypes.ArrayInt64]: 'numberAttributeValues', + [DataTypes.ArrayString]: 'stringAttributeValues', + [DataTypes.ArrayBool]: 'boolAttributeValues', + [DataTypes.EMPTY]: 'stringAttributeValues', +}; diff --git a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2.tsx b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2.tsx index 48ee2d0a6041..59fcb085d52e 100644 --- a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2.tsx +++ b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2.tsx @@ -4,6 +4,7 @@ import './QueryBuilderSearchV2.styles.scss'; import { Select, Spin, Tag, Tooltip } from 'antd'; import cx from 'classnames'; import { + DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY, OPERATORS, QUERY_BUILDER_OPERATORS_BY_TYPES, QUERY_BUILDER_SEARCH_VALUES, @@ -737,9 +738,11 @@ function QueryBuilderSearchV2( values.push(tagValue[tagValue.length - 1]); } else if (!isEmpty(tagValue)) values.push(tagValue); - values.push( - ...(Object.values(attributeValues?.payload || {}).find((el) => !!el) || []), - ); + if (attributeValues?.payload) { + const dataType = currentFilterItem?.key?.dataType || DataTypes.String; + const key = DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY[dataType]; + values.push(...(attributeValues?.payload?.[key] || [])); + } setDropdownOptions( values.map((val) => ({ diff --git a/frontend/src/hooks/queryBuilder/useFetchKeysAndValues.ts b/frontend/src/hooks/queryBuilder/useFetchKeysAndValues.ts index b3b7cbae034b..1953b67b62f4 100644 --- a/frontend/src/hooks/queryBuilder/useFetchKeysAndValues.ts +++ b/frontend/src/hooks/queryBuilder/useFetchKeysAndValues.ts @@ -1,6 +1,7 @@ /* eslint-disable sonarjs/cognitive-complexity */ import { getMetricsListFilterValues } from 'api/metricsExplorer/getMetricsListFilterValues'; import { getAttributesValues } from 'api/queryBuilder/getAttributesValues'; +import { DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY } from 'constants/queryBuilder'; import { DEBOUNCE_DELAY } from 'constants/queryBuilderFilterConfig'; import { K8sCategory, @@ -16,6 +17,7 @@ import useDebounceValue from 'hooks/useDebounce'; import { cloneDeep, isEqual, uniqWith, unset } from 'lodash-es'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useDebounce } from 'react-use'; +import { IAttributeValuesResponse } from 'types/api/queryBuilder/getAttributesValues'; import { BaseAutocompleteData, DataTypes, @@ -157,6 +159,28 @@ export const useFetchKeysAndValues = ( enabled: isMetricsExplorer && isQueryEnabled && !shouldUseSuggestions, }); + function isAttributeValuesResponse( + payload: any, + ): payload is IAttributeValuesResponse { + return ( + payload && + (Array.isArray(payload.stringAttributeValues) || + payload.stringAttributeValues === null || + Array.isArray(payload.numberAttributeValues) || + payload.numberAttributeValues === null || + Array.isArray(payload.boolAttributeValues) || + payload.boolAttributeValues === null) + ); + } + + function isMetricsListFilterValuesData( + payload: any, + ): payload is { filterValues: string[] } { + return ( + payload && 'filterValues' in payload && Array.isArray(payload.filterValues) + ); + } + /** * Fetches the options to be displayed based on the selected value * @param value - the selected value @@ -226,8 +250,17 @@ export const useFetchKeysAndValues = ( } if (payload) { - const values = Object.values(payload).find((el) => !!el) || []; - setResults(values); + if (isAttributeValuesResponse(payload)) { + const dataType = filterAttributeKey?.dataType ?? DataTypes.String; + const key = DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY[dataType]; + setResults(key ? payload[key] || [] : []); + return; + } + + if (isMetricsExplorer && isMetricsListFilterValuesData(payload)) { + setResults(payload.filterValues || []); + return; + } } } catch (e) { console.error(e); diff --git a/frontend/src/pages/MessagingQueues/MQGraph/useGetAllConfigOptions.ts b/frontend/src/pages/MessagingQueues/MQGraph/useGetAllConfigOptions.ts index c11c0f85f528..f3370512bc8f 100644 --- a/frontend/src/pages/MessagingQueues/MQGraph/useGetAllConfigOptions.ts +++ b/frontend/src/pages/MessagingQueues/MQGraph/useGetAllConfigOptions.ts @@ -34,7 +34,7 @@ export function useGetAllConfigOptions( }); if (payload) { - const values = Object.values(payload).find((el) => !!el) || []; + const values = payload.stringAttributeValues || []; const options: DefaultOptionType[] = values.map((val: string) => ({ label: val, value: val, diff --git a/frontend/src/pages/TracesExplorer/Filter/filterUtils.ts b/frontend/src/pages/TracesExplorer/Filter/filterUtils.ts index ea82bc52ef48..b04d6383420a 100644 --- a/frontend/src/pages/TracesExplorer/Filter/filterUtils.ts +++ b/frontend/src/pages/TracesExplorer/Filter/filterUtils.ts @@ -1,5 +1,6 @@ /* eslint-disable react-hooks/exhaustive-deps */ import { getAttributesValues } from 'api/queryBuilder/getAttributesValues'; +import { DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY } from 'constants/queryBuilder'; import { Dispatch, SetStateAction, useEffect, useState } from 'react'; import { BaseAutocompleteData, @@ -327,8 +328,9 @@ export function useGetAggregateValues( }); if (payload) { - const values = Object.values(payload).find((el) => !!el) || []; - setResults(values); + const key = + DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY[keyData.dataType as Partial]; + setResults(key ? payload[key] || [] : []); } } catch (e) { console.error(e);