From 32d144845aaab2a9236f9be5bfa4de4dba1bfede Mon Sep 17 00:00:00 2001 From: Shaheer Kochai Date: Fri, 14 Mar 2025 07:20:04 +0430 Subject: [PATCH] fix: update the auto-complete API reading logic (#7254) --- .../useGetCeleryFilters.ts | 11 ++++-- .../FilterRenderers/Checkbox/Checkbox.tsx | 17 +++++---- frontend/src/constants/queryBuilder.ts | 16 ++++++++ .../QueryBuilderSearchV2.tsx | 9 +++-- .../queryBuilder/useFetchKeysAndValues.ts | 37 ++++++++++++++++++- .../MQGraph/useGetAllConfigOptions.ts | 2 +- .../TracesExplorer/Filter/filterUtils.ts | 6 ++- 7 files changed, 80 insertions(+), 18 deletions(-) diff --git a/frontend/src/components/CeleryTask/CeleryTaskConfigOptions/useGetCeleryFilters.ts b/frontend/src/components/CeleryTask/CeleryTaskConfigOptions/useGetCeleryFilters.ts index 70570a167c..640ddd0cab 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 1051a47c3d..6f00073cec 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 60b38480b4..359f4a22de 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 48ee2d0a60..59fcb085d5 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 b3b7cbae03..1953b67b62 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 c11c0f85f5..f3370512bc 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 ea82bc52ef..b04d638342 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);