feat: added dynamic variable suggestion in where clause

This commit is contained in:
SagarRajput-7 2025-05-14 02:49:11 +05:30
parent 4fe1d1b3f7
commit dbbd7c24ac
4 changed files with 96 additions and 2 deletions

View File

@ -12,6 +12,7 @@ import {
} from 'constants/queryBuilder';
import { DEBOUNCE_DELAY } from 'constants/queryBuilderFilterConfig';
import { LogsExplorerShortcuts } from 'constants/shortcuts/logsExplorerShortcuts';
import { useGetDynamicVariables } from 'hooks/dashboard/useGetDynamicVariables';
import { useKeyboardHotkeys } from 'hooks/hotkeys/useKeyboardHotkeys';
import { WhereClauseConfig } from 'hooks/queryBuilder/useAutoComplete';
import { useGetAggregateKeys } from 'hooks/queryBuilder/useGetAggregateKeys';
@ -246,6 +247,8 @@ function QueryBuilderSearchV2(
return false;
}, [currentState, query.aggregateAttribute?.dataType, query.dataSource]);
const { dynamicVariables } = useGetDynamicVariables();
const { data, isFetching } = useGetAggregateKeys(
{
searchText: searchValue?.split(' ')[0],
@ -800,6 +803,19 @@ function QueryBuilderSearchV2(
const dataType = currentFilterItem?.key?.dataType || DataTypes.String;
const key = DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY[dataType];
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(
(variable) =>
variable?.dynamicVariablesAttribute === currentFilterItem?.key?.key,
)?.name;
if (variableName) {
const variableValue = `$${variableName}`;
if (!values.includes(variableValue)) {
values.unshift(variableValue);
}
}
}
setDropdownOptions(
@ -819,6 +835,8 @@ function QueryBuilderSearchV2(
searchValue,
suggestionsData?.payload?.attributes,
operatorConfigKey,
currentFilterItem?.key?.key,
dynamicVariables,
]);
// keep the query in sync with the selected tags in logs explorer page

View File

@ -0,0 +1,55 @@
import getDashboard from 'api/dashboard/get';
import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
import { useDashboard } from 'providers/Dashboard/Dashboard';
import { useMemo } from 'react';
import { useQuery } from 'react-query';
import { IDashboardVariable } from 'types/api/dashboard/getAll';
export interface DynamicVariable extends IDashboardVariable {
dashboardName: string;
dashboardId: string;
}
interface UseGetDynamicVariablesProps {
dashboardId?: string;
}
export const useGetDynamicVariables = (
props?: UseGetDynamicVariablesProps,
): {
dynamicVariables: DynamicVariable[];
isLoading: boolean;
isError: boolean;
refetch: () => void;
} => {
const { dashboardId: dashboardIdFromProps } = props || {};
const { dashboardId: dashboardIdFromDashboard } = useDashboard();
const dashboardId = dashboardIdFromProps || dashboardIdFromDashboard;
const { data: dashboard, isLoading, isError, refetch } = useQuery({
queryFn: () => getDashboard({ uuid: dashboardId }),
queryKey: [REACT_QUERY_KEY.DASHBOARD_BY_ID, dashboardId],
});
const dynamicVariables = useMemo(() => {
if (!dashboard?.data?.variables) return [];
const variables: DynamicVariable[] = [];
Object.entries(dashboard.data.variables).forEach(([, variable]) => {
if (variable.type === 'DYNAMIC') {
variables.push({
...variable,
dashboardName: dashboard.data.title,
dashboardId: dashboard.uuid,
});
}
});
return variables;
}, [dashboard]);
return { dynamicVariables, isLoading, isError, refetch };
};

View File

@ -3,6 +3,7 @@ import {
getTagToken,
} from 'container/QueryBuilder/filters/QueryBuilderSearch/utils';
import { Option } from 'container/QueryBuilder/type';
import { useGetDynamicVariables } from 'hooks/dashboard/useGetDynamicVariables';
import { transformStringWithPrefix } from 'lib/query/transformStringWithPrefix';
import { isEmpty } from 'lodash-es';
import { useCallback, useEffect, useMemo, useState } from 'react';
@ -25,10 +26,19 @@ export const useOptions = (
result: string[],
isFetching: boolean,
whereClauseConfig?: WhereClauseConfig,
// eslint-disable-next-line sonarjs/cognitive-complexity
): Option[] => {
const [options, setOptions] = useState<Option[]>([]);
const operators = useOperators(key, keys);
// get matching dynamic variables to suggest
const { dynamicVariables } = useGetDynamicVariables();
const variableName = dynamicVariables.find(
(variable) => variable?.dynamicVariablesAttribute === key,
)?.name;
const variableAsValue = variableName ? `$${variableName}` : '';
const getLabel = useCallback(
(data: BaseAutocompleteData): Option['label'] =>
transformStringWithPrefix({
@ -63,6 +73,11 @@ export const useOptions = (
const getOptionsWithValidOperator = useCallback(
(key: string, results: string[], searchValue: string) => {
const hasAllResults = results.every((value) => result.includes(value));
if (!isEmpty(variableAsValue)) {
results.unshift(variableAsValue);
}
const values = getKeyOpValue(results);
return hasAllResults
@ -80,7 +95,7 @@ export const useOptions = (
...values,
];
},
[getKeyOpValue, result],
[getKeyOpValue, result, variableAsValue],
);
const getKeyOperatorOptions = useCallback(
@ -128,7 +143,10 @@ export const useOptions = (
newOptions = getKeyOperatorOptions(key);
} else if (key && operator) {
if (isMulti) {
newOptions = results.map((item) => ({
const resultsWithVariable = isEmpty(variableAsValue)
? results
: [variableAsValue, ...results];
newOptions = resultsWithVariable.map((item) => ({
label: checkCommaInValue(String(item)),
value: String(item),
}));
@ -161,6 +179,7 @@ export const useOptions = (
getKeyOperatorOptions,
getOptionsWithValidOperator,
isFetching,
variableAsValue,
]);
return useMemo(

View File

@ -26,6 +26,8 @@ export const getDashboardVariables = (
variablesTuple[value.name] =
value?.type === 'DYNAMIC' &&
value?.allSelected &&
value?.showALLOption &&
value?.multiSelect &&
!value?.haveCustomValuesSelected
? '__all__'
: value?.selectedValue;