mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-29 16:14:42 +00:00
feat: added dynamic variable suggestion in where clause
This commit is contained in:
parent
4fe1d1b3f7
commit
dbbd7c24ac
@ -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
|
||||
|
||||
55
frontend/src/hooks/dashboard/useGetDynamicVariables.tsx
Normal file
55
frontend/src/hooks/dashboard/useGetDynamicVariables.tsx
Normal 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 };
|
||||
};
|
||||
@ -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(
|
||||
|
||||
@ -26,6 +26,8 @@ export const getDashboardVariables = (
|
||||
variablesTuple[value.name] =
|
||||
value?.type === 'DYNAMIC' &&
|
||||
value?.allSelected &&
|
||||
value?.showALLOption &&
|
||||
value?.multiSelect &&
|
||||
!value?.haveCustomValuesSelected
|
||||
? '__all__'
|
||||
: value?.selectedValue;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user