From 858cd287fac6cad20d515a0cc7e1141221dd7d62 Mon Sep 17 00:00:00 2001 From: Ashwin Bhatkal Date: Tue, 3 Feb 2026 09:33:02 +0530 Subject: [PATCH] chore: query builder / hooks to use new variable store (#10148) * chore: query builder / hooks to use new variable store * chore: fix tests --- .../QueryV2/QuerySearch/QuerySearch.tsx | 16 +++------ .../QueryBuilderSearchV2.tsx | 18 ++++------ .../__test__/QueryBuilderSearchV2.test.tsx | 34 +++++++++---------- .../Drilldown/useDashboardVarConfig.tsx | 16 +++------ .../hooks/dashboard/useDashboardVariables.ts | 6 ++-- .../hooks/queryBuilder/useCreateAlerts.tsx | 24 ++++++------- .../hooks/queryBuilder/useGetQueryRange.ts | 16 +++------ .../queryBuilder/useGetWidgetQueryRange.ts | 6 ++-- frontend/src/hooks/queryBuilder/useOptions.ts | 17 ++++------ .../getDashboardVariables.ts | 4 +-- 10 files changed, 63 insertions(+), 94 deletions(-) diff --git a/frontend/src/components/QueryBuilderV2/QueryV2/QuerySearch/QuerySearch.tsx b/frontend/src/components/QueryBuilderV2/QueryV2/QuerySearch/QuerySearch.tsx index 1aef55129e..4c91dc8495 100644 --- a/frontend/src/components/QueryBuilderV2/QueryV2/QuerySearch/QuerySearch.tsx +++ b/frontend/src/components/QueryBuilderV2/QueryV2/QuerySearch/QuerySearch.tsx @@ -28,17 +28,16 @@ import { QUERY_BUILDER_OPERATORS_BY_KEY_TYPE, queryOperatorSuggestions, } from 'constants/antlrQueryConstants'; +import { useDashboardVariablesByType } from 'hooks/dashboard/useDashboardVariablesByType'; import { useIsDarkMode } from 'hooks/useDarkMode'; import useDebounce from 'hooks/useDebounce'; import { debounce, isNull } from 'lodash-es'; import { Info, TriangleAlert } from 'lucide-react'; -import { useDashboard } from 'providers/Dashboard/Dashboard'; import { IDetailedError, IQueryContext, IValidationResult, } from 'types/antlrQueryTypes'; -import { IDashboardVariable } from 'types/api/dashboard/getAll'; import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData'; import { QueryKeyDataSuggestionsProps } from 'types/api/querySuggestions/types'; import { DataSource } from 'types/common/queryBuilder'; @@ -207,14 +206,9 @@ function QuerySearch({ const lastValueRef = useRef(''); const isMountedRef = useRef(true); - const { selectedDashboard } = useDashboard(); - - const dynamicVariables = useMemo( - () => - Object.values(selectedDashboard?.data?.variables || {})?.filter( - (variable: IDashboardVariable) => variable.type === 'DYNAMIC', - ), - [selectedDashboard], + const dashboardDynamicVariables = useDashboardVariablesByType( + 'DYNAMIC', + 'values', ); // Add back the generateOptions function and useEffect @@ -1069,7 +1063,7 @@ function QuerySearch({ ); // Add dynamic variables suggestions for the current key - const variableName = dynamicVariables?.find( + const variableName = dashboardDynamicVariables?.find( (variable) => variable?.dynamicVariablesAttribute === keyName, )?.name; diff --git a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2.tsx b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2.tsx index f1bce57d04..c5770398e9 100644 --- a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2.tsx +++ b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2.tsx @@ -19,6 +19,7 @@ import { } from 'constants/queryBuilder'; import { DEBOUNCE_DELAY } from 'constants/queryBuilderFilterConfig'; import { LogsExplorerShortcuts } from 'constants/shortcuts/logsExplorerShortcuts'; +import { useDashboardVariablesByType } from 'hooks/dashboard/useDashboardVariablesByType'; import { useKeyboardHotkeys } from 'hooks/hotkeys/useKeyboardHotkeys'; import { WhereClauseConfig } from 'hooks/queryBuilder/useAutoComplete'; import { useGetAggregateKeys } from 'hooks/queryBuilder/useGetAggregateKeys'; @@ -38,9 +39,7 @@ import { unset, } from 'lodash-es'; import { ChevronDown, ChevronUp } from 'lucide-react'; -import { useDashboard } from 'providers/Dashboard/Dashboard'; import type { BaseSelectRef } from 'rc-select'; -import { IDashboardVariable } from 'types/api/dashboard/getAll'; import { BaseAutocompleteData, DataTypes, @@ -248,14 +247,9 @@ function QueryBuilderSearchV2( return false; }, [currentState, query.aggregateAttribute?.dataType, query.dataSource]); - const { selectedDashboard } = useDashboard(); - - const dynamicVariables = useMemo( - () => - Object.values(selectedDashboard?.data?.variables || {})?.filter( - (variable: IDashboardVariable) => variable.type === 'DYNAMIC', - ), - [selectedDashboard], + const dashboardDynamicVariables = useDashboardVariablesByType( + 'DYNAMIC', + 'values', ); const { data, isFetching } = useGetAggregateKeys( @@ -806,7 +800,7 @@ function QueryBuilderSearchV2( values.push(...(attributeValues?.payload?.[key] || [])); // here we want to suggest the variable name matching with the key here, we will go over the dynamic variables for the keys - const variableName = dynamicVariables?.find( + const variableName = dashboardDynamicVariables?.find( (variable) => variable?.dynamicVariablesAttribute === currentFilterItem?.key?.key, )?.name; @@ -837,7 +831,7 @@ function QueryBuilderSearchV2( suggestionsData?.payload?.attributes, operatorConfigKey, currentFilterItem?.key?.key, - dynamicVariables, + dashboardDynamicVariables, ]); // keep the query in sync with the selected tags in logs explorer page diff --git a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/__test__/QueryBuilderSearchV2.test.tsx b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/__test__/QueryBuilderSearchV2.test.tsx index 2dec50a99b..34abf69c11 100644 --- a/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/__test__/QueryBuilderSearchV2.test.tsx +++ b/frontend/src/container/QueryBuilder/filters/QueryBuilderSearchV2/__test__/QueryBuilderSearchV2.test.tsx @@ -12,7 +12,9 @@ import { initialQueriesMap, initialQueryBuilderFormValues, } from 'constants/queryBuilder'; +import { IUseDashboardVariablesReturn } from 'hooks/dashboard/useDashboardVariables'; import { QueryBuilderContext } from 'providers/QueryBuilder'; +import { IDashboardVariable } from 'types/api/dashboard/getAll'; import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse'; import { DataSource } from 'types/common/queryBuilder'; @@ -145,27 +147,23 @@ jest.mock('hooks/useSafeNavigate', () => ({ }), })); -// Mock dashboard provider with dynamic variables -const mockDashboard = { - data: { - variables: { - service: { - id: 'service', - name: 'service', - type: 'DYNAMIC', - dynamicVariablesAttribute: 'service.name', - description: '', - sort: 'DISABLED', - multiSelect: false, - showALLOption: false, - }, - }, +// Mock dashboard variables +const dashboardVariables = { + service: { + id: 'service', + name: 'service', + type: 'DYNAMIC' as IDashboardVariable['type'], + dynamicVariablesAttribute: 'service.name', + description: '', + sort: 'DISABLED' as IDashboardVariable['sort'], + multiSelect: false, + showALLOption: false, }, }; -jest.mock('providers/Dashboard/Dashboard', () => ({ - useDashboard: (): any => ({ - selectedDashboard: mockDashboard, +jest.mock('hooks/dashboard/useDashboardVariables', () => ({ + useDashboardVariables: (): IUseDashboardVariablesReturn => ({ + dashboardVariables: dashboardVariables, }), })); diff --git a/frontend/src/container/QueryTable/Drilldown/useDashboardVarConfig.tsx b/frontend/src/container/QueryTable/Drilldown/useDashboardVarConfig.tsx index 850fae3114..5910edffa8 100644 --- a/frontend/src/container/QueryTable/Drilldown/useDashboardVarConfig.tsx +++ b/frontend/src/container/QueryTable/Drilldown/useDashboardVarConfig.tsx @@ -1,8 +1,8 @@ import { useCallback, useMemo } from 'react'; import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar'; +import { useDashboardVariablesByType } from 'hooks/dashboard/useDashboardVariablesByType'; import { ArrowLeft, Plus, Settings, X } from 'lucide-react'; import ContextMenu from 'periscope/components/ContextMenu'; -import { useDashboard } from 'providers/Dashboard/Dashboard'; import { IDashboardVariable } from 'types/api/dashboard/getAll'; // import { PANEL_TYPES } from 'constants/queryBuilder'; import { Query } from 'types/api/queryBuilder/queryBuilderData'; @@ -33,17 +33,9 @@ const useDashboardVarConfig = ({ }; // contextItems: React.ReactNode; } => { - const { selectedDashboard } = useDashboard(); + const dashboardDynamicVariables = useDashboardVariablesByType('DYNAMIC'); const { onValueUpdate, createVariable } = useDashboardVariableUpdate(); - const dynamicDashboardVariables = useMemo( - (): [string, IDashboardVariable][] => - Object.entries(selectedDashboard?.data?.variables || {}).filter( - ([, value]) => value.name && value.type === 'DYNAMIC', - ), - [selectedDashboard], - ); - // Function to determine the source from query data const getSourceFromQuery = useCallback((): | 'logs' @@ -116,7 +108,7 @@ const useDashboardVarConfig = ({ <> {' '} {Object.entries(fieldVariables).map(([fieldName, value]) => { - const dashboardVar = dynamicDashboardVariables.find( + const dashboardVar = dashboardDynamicVariables.find( ([, dynamicValue]) => dynamicValue.dynamicVariablesAttribute === fieldName, ); @@ -178,7 +170,7 @@ const useDashboardVarConfig = ({ ), [ fieldVariables, - dynamicDashboardVariables, + dashboardDynamicVariables, handleSetVariable, handleUnsetVariable, handleCreateVariable, diff --git a/frontend/src/hooks/dashboard/useDashboardVariables.ts b/frontend/src/hooks/dashboard/useDashboardVariables.ts index 5ceb8b1e1f..57055f2fe5 100644 --- a/frontend/src/hooks/dashboard/useDashboardVariables.ts +++ b/frontend/src/hooks/dashboard/useDashboardVariables.ts @@ -5,9 +5,11 @@ import { IDashboardVariables, } from '../../providers/Dashboard/store/dashboardVariablesStore'; -export const useDashboardVariables = (): { +export interface IUseDashboardVariablesReturn { dashboardVariables: IDashboardVariables; -} => { +} + +export const useDashboardVariables = (): IUseDashboardVariablesReturn => { const dashboardVariables = useSyncExternalStore( dashboardVariablesStore.subscribe, dashboardVariablesStore.getSnapshot, diff --git a/frontend/src/hooks/queryBuilder/useCreateAlerts.tsx b/frontend/src/hooks/queryBuilder/useCreateAlerts.tsx index bcf2778147..ce39a02c2d 100644 --- a/frontend/src/hooks/queryBuilder/useCreateAlerts.tsx +++ b/frontend/src/hooks/queryBuilder/useCreateAlerts.tsx @@ -1,4 +1,4 @@ -import { useCallback, useMemo } from 'react'; +import { useCallback } from 'react'; import { useMutation } from 'react-query'; import { useSelector } from 'react-redux'; import logEvent from 'api/common/logEvent'; @@ -10,13 +10,15 @@ import { ENTITY_VERSION_V5 } from 'constants/app'; import { QueryParams } from 'constants/query'; import ROUTES from 'constants/routes'; import { MenuItemKeys } from 'container/GridCardLayout/WidgetHeader/contants'; +import { useDashboardVariables } from 'hooks/dashboard/useDashboardVariables'; +import { useDashboardVariablesByType } from 'hooks/dashboard/useDashboardVariablesByType'; import { useNotifications } from 'hooks/useNotifications'; import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariables'; import { mapQueryDataFromApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataFromApi'; import { isEmpty } from 'lodash-es'; import { useDashboard } from 'providers/Dashboard/Dashboard'; import { AppState } from 'store/reducers'; -import { IDashboardVariable, Widgets } from 'types/api/dashboard/getAll'; +import { Widgets } from 'types/api/dashboard/getAll'; import { GlobalReducer } from 'types/reducer/globalTime'; import { getGraphType } from 'utils/getGraphType'; @@ -32,12 +34,10 @@ const useCreateAlerts = (widget?: Widgets, caller?: string): VoidFunction => { const { selectedDashboard } = useDashboard(); - const dynamicVariables = useMemo( - () => - Object.values(selectedDashboard?.data?.variables || {})?.filter( - (variable: IDashboardVariable) => variable.type === 'DYNAMIC', - ), - [selectedDashboard], + const { dashboardVariables } = useDashboardVariables(); + const dashboardDynamicVariables = useDashboardVariablesByType( + 'DYNAMIC', + 'values', ); return useCallback(() => { @@ -68,9 +68,9 @@ const useCreateAlerts = (widget?: Widgets, caller?: string): VoidFunction => { globalSelectedInterval, graphType: getGraphType(widget.panelTypes), selectedTime: widget.timePreferance, - variables: getDashboardVariables(selectedDashboard?.data.variables), + variables: getDashboardVariables(dashboardVariables), originalGraphType: widget.panelTypes, - dynamicVariables, + dynamicVariables: dashboardDynamicVariables, }); queryRangeMutation.mutate(queryPayload, { onSuccess: (data) => { @@ -104,10 +104,10 @@ const useCreateAlerts = (widget?: Widgets, caller?: string): VoidFunction => { globalSelectedInterval, notifications, queryRangeMutation, - selectedDashboard?.data.variables, + dashboardVariables, + dashboardDynamicVariables, selectedDashboard?.data.version, widget, - dynamicVariables, ]); }; diff --git a/frontend/src/hooks/queryBuilder/useGetQueryRange.ts b/frontend/src/hooks/queryBuilder/useGetQueryRange.ts index f57cb09f3a..5651d3491e 100644 --- a/frontend/src/hooks/queryBuilder/useGetQueryRange.ts +++ b/frontend/src/hooks/queryBuilder/useGetQueryRange.ts @@ -4,14 +4,13 @@ import { isAxiosError } from 'axios'; import { PANEL_TYPES } from 'constants/queryBuilder'; import { REACT_QUERY_KEY } from 'constants/reactQueryKeys'; import { updateBarStepInterval } from 'container/GridCardLayout/utils'; +import { useDashboardVariablesByType } from 'hooks/dashboard/useDashboardVariablesByType'; import { GetMetricQueryRange, GetQueryResultsProps, } from 'lib/dashboard/getQueryResults'; import getStartEndRangeTime from 'lib/getStartEndRangeTime'; -import { useDashboard } from 'providers/Dashboard/Dashboard'; import { SuccessResponse, Warning } from 'types/api'; -import { IDashboardVariable } from 'types/api/dashboard/getAll'; import APIError from 'types/api/error'; import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange'; import { DataSource } from 'types/common/queryBuilder'; @@ -43,14 +42,9 @@ export const useGetQueryRange: UseGetQueryRange = ( headers, publicQueryMeta, ) => { - const { selectedDashboard } = useDashboard(); - - const dynamicVariables = useMemo( - () => - Object.values(selectedDashboard?.data?.variables || {})?.filter( - (variable: IDashboardVariable) => variable.type === 'DYNAMIC', - ), - [selectedDashboard], + const dashboardDynamicVariables = useDashboardVariablesByType( + 'DYNAMIC', + 'values', ); const newRequestData: GetQueryResultsProps = useMemo(() => { @@ -159,7 +153,7 @@ export const useGetQueryRange: UseGetQueryRange = ( GetMetricQueryRange( modifiedRequestData, version, - dynamicVariables, + dashboardDynamicVariables, signal, headers, undefined, diff --git a/frontend/src/hooks/queryBuilder/useGetWidgetQueryRange.ts b/frontend/src/hooks/queryBuilder/useGetWidgetQueryRange.ts index 0d25ef520e..b9ee86fd75 100644 --- a/frontend/src/hooks/queryBuilder/useGetWidgetQueryRange.ts +++ b/frontend/src/hooks/queryBuilder/useGetWidgetQueryRange.ts @@ -2,9 +2,9 @@ import { UseQueryOptions, UseQueryResult } from 'react-query'; import { useSelector } from 'react-redux'; import { initialQueriesMap } from 'constants/queryBuilder'; import { REACT_QUERY_KEY } from 'constants/reactQueryKeys'; +import { useDashboardVariables } from 'hooks/dashboard/useDashboardVariables'; import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariables'; import { GetQueryResultsProps } from 'lib/dashboard/getQueryResults'; -import { useDashboard } from 'providers/Dashboard/Dashboard'; import { AppState } from 'store/reducers'; import { SuccessResponse } from 'types/api'; import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange'; @@ -28,7 +28,7 @@ export const useGetWidgetQueryRange = ( const { stagedQuery } = useQueryBuilder(); - const { selectedDashboard } = useDashboard(); + const { dashboardVariables } = useDashboardVariables(); return useGetQueryRange( { @@ -36,7 +36,7 @@ export const useGetWidgetQueryRange = ( selectedTime, globalSelectedInterval, query: stagedQuery || initialQueriesMap.metrics, - variables: getDashboardVariables(selectedDashboard?.data.variables), + variables: getDashboardVariables(dashboardVariables), }, version, { diff --git a/frontend/src/hooks/queryBuilder/useOptions.ts b/frontend/src/hooks/queryBuilder/useOptions.ts index eba800d3b1..76df8d04c2 100644 --- a/frontend/src/hooks/queryBuilder/useOptions.ts +++ b/frontend/src/hooks/queryBuilder/useOptions.ts @@ -4,9 +4,8 @@ import { getTagToken, } from 'container/QueryBuilder/filters/QueryBuilderSearch/utils'; import { Option } from 'container/QueryBuilder/type'; +import { useDashboardVariablesByType } from 'hooks/dashboard/useDashboardVariablesByType'; import { isEmpty } from 'lodash-es'; -import { useDashboard } from 'providers/Dashboard/Dashboard'; -import { IDashboardVariable } from 'types/api/dashboard/getAll'; import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse'; import { WhereClauseConfig } from './useAutoComplete'; @@ -32,16 +31,12 @@ export const useOptions = ( const operators = useOperators(key, keys); // get matching dynamic variables to suggest - const { selectedDashboard } = useDashboard(); - - const dynamicVariables = useMemo( - () => - Object.values(selectedDashboard?.data?.variables || {})?.filter( - (variable: IDashboardVariable) => variable.type === 'DYNAMIC', - ), - [selectedDashboard], + const dashboardDynamicVariables = useDashboardVariablesByType( + 'DYNAMIC', + 'values', ); - const variableName = dynamicVariables?.find( + + const variableName = dashboardDynamicVariables?.find( (variable) => variable?.dynamicVariablesAttribute === key, )?.name; diff --git a/frontend/src/lib/dashbaordVariables/getDashboardVariables.ts b/frontend/src/lib/dashbaordVariables/getDashboardVariables.ts index aa083f0e9e..c2bad4e5ca 100644 --- a/frontend/src/lib/dashbaordVariables/getDashboardVariables.ts +++ b/frontend/src/lib/dashbaordVariables/getDashboardVariables.ts @@ -1,9 +1,9 @@ import getStartEndRangeTime from 'lib/getStartEndRangeTime'; +import { IDashboardVariables } from 'providers/Dashboard/store/dashboardVariablesStore'; import store from 'store'; -import { Dashboard } from 'types/api/dashboard/getAll'; export const getDashboardVariables = ( - variables?: Dashboard['data']['variables'], + variables?: IDashboardVariables, ): Record => { if (!variables) { return {};