signoz/frontend/src/hooks/queryBuilder/useQueryBuilderOperations.ts
Rajat Dabade ecd5ce92c2
List View for Dashboard (#4517)
* refactor: initial setup for list view logs

* feat: done with basic functionality panel view logs

* feat: added panel view

* fix: discard and edit issue

* refactor: removed not required params from uselogdata

* feat: trace list view

* fix: loader

* refactor: traces table component css update

* refactor: added open san font and udpated css

* fix: full view traces issue and search column css update

* refactor: remove consoles

* refactor: removed commented code and updated logic

* chore: build failure

* refactor: icons change for apdd panels

* refactor: rebased to develop

* refactor: added support for light mode

* refactor: fix tsc

* fix: query select issue

* chore: table column to lower case

* refactor: updated styling for both log and traces tables

* chore: removed comment code

* chore: remove the resizable block from table header traces

* refactor: log table header and body stayling updated

* fix: query range on every column add

* refactor: styling updates

* fix: query range log respect global time

* refactor: css update log table header

* refactor: removed unnecessary code

* refactor: log query range respect globaltime

* refactor: dropdown support to qb

* refactor: remove creating alert for list view

* refactor: fix the height of column select dropdown

* fix: dropdown suggestion for orderby

* refactor: remove the commented code

* refactor: full view respect global time

* refactor: css updates

* refactor: should fire query range on variable change

* refactor: css updates for log list view

* refactor: removed the unused changes

* refactor: handle error state for exploere columns

* refactor: handle error state for explorer columns

* chore: generate yarn lock file

* refactor: pagination for order by timestamp

* fix: full text body contain issue

* refactor: inverted the operator for next and previous button config

* refactor: rename variable handle light mode

* fix: no log issue

* chore: renamed variables

---------

Co-authored-by: Vikrant Gupta <vikrant.thomso@gmail.com>
2024-02-20 16:21:07 +05:30

249 lines
6.6 KiB
TypeScript

import { LEGEND } from 'constants/global';
import {
initialAutocompleteData,
initialQueryBuilderFormValuesMap,
mapOfFormulaToFilters,
mapOfQueryFilters,
PANEL_TYPES,
} from 'constants/queryBuilder';
import {
listViewInitialLogQuery,
listViewInitialTraceQuery,
} from 'container/NewDashboard/ComponentsSlider/constants';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { getOperatorsBySourceAndPanelType } from 'lib/newQueryBuilder/getOperatorsBySourceAndPanelType';
import { findDataTypeOfOperator } from 'lib/query/findDataTypeOfOperator';
import { useCallback, useEffect, useState } from 'react';
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
import {
IBuilderFormula,
IBuilderQuery,
} from 'types/api/queryBuilder/queryBuilderData';
import {
HandleChangeFormulaData,
HandleChangeQueryData,
UseQueryOperations,
} from 'types/common/operations.types';
import { DataSource } from 'types/common/queryBuilder';
import { SelectOption } from 'types/common/select';
import { getFormatedLegend } from 'utils/getFormatedLegend';
export const useQueryOperations: UseQueryOperations = ({
query,
index,
filterConfigs,
formula,
isListViewPanel = false,
}) => {
const {
handleSetQueryData,
handleSetFormulaData,
removeQueryBuilderEntityByIndex,
panelType,
initialDataSource,
currentQuery,
redirectWithQueryBuilderData,
} = useQueryBuilder();
const [operators, setOperators] = useState<SelectOption<string, string>[]>([]);
const { dataSource, aggregateOperator } = query;
const getNewListOfAdditionalFilters = useCallback(
(dataSource: DataSource, isQuery: boolean): string[] => {
const additionalFiltersKeys: (keyof Pick<
IBuilderQuery,
'orderBy' | 'limit' | 'having' | 'stepInterval'
>)[] = ['having', 'limit', 'orderBy', 'stepInterval'];
const mapsOfFilters = isQuery ? mapOfQueryFilters : mapOfFormulaToFilters;
const result: string[] = mapsOfFilters[dataSource]?.reduce<string[]>(
(acc, item) => {
if (
filterConfigs &&
filterConfigs[item.field as typeof additionalFiltersKeys[number]]
?.isHidden
) {
return acc;
}
acc.push(item.text);
return acc;
},
[],
);
return result;
},
[filterConfigs],
);
const [listOfAdditionalFilters, setListOfAdditionalFilters] = useState<
string[]
>(getNewListOfAdditionalFilters(dataSource, true));
const [
listOfAdditionalFormulaFilters,
setListOfAdditionalFormulaFilters,
] = useState<string[]>(getNewListOfAdditionalFilters(dataSource, false));
const handleChangeOperator = useCallback(
(value: string): void => {
const aggregateDataType: BaseAutocompleteData['dataType'] =
query.aggregateAttribute.dataType;
const typeOfValue = findDataTypeOfOperator(value);
const shouldResetAggregateAttribute =
(aggregateDataType === 'string' || aggregateDataType === 'bool') &&
typeOfValue === 'number';
const newQuery: IBuilderQuery = {
...query,
aggregateOperator: value,
having: [],
limit: null,
...(shouldResetAggregateAttribute
? { aggregateAttribute: initialAutocompleteData }
: {}),
};
handleSetQueryData(index, newQuery);
},
[index, query, handleSetQueryData],
);
const handleChangeAggregatorAttribute = useCallback(
(value: BaseAutocompleteData): void => {
const newQuery: IBuilderQuery = {
...query,
aggregateAttribute: value,
having: [],
};
handleSetQueryData(index, newQuery);
},
[index, query, handleSetQueryData],
);
const handleChangeDataSource = useCallback(
(nextSource: DataSource): void => {
if (isListViewPanel) {
if (nextSource === DataSource.LOGS) {
redirectWithQueryBuilderData(listViewInitialLogQuery);
} else if (nextSource === DataSource.TRACES) {
redirectWithQueryBuilderData(listViewInitialTraceQuery);
}
}
const newOperators = getOperatorsBySourceAndPanelType({
dataSource: nextSource,
panelType: panelType || PANEL_TYPES.TIME_SERIES,
});
const entries = Object.entries(
initialQueryBuilderFormValuesMap.metrics,
).filter(([key]) => key !== 'queryName' && key !== 'expression');
const initCopyResult = Object.fromEntries(entries);
const newQuery: IBuilderQuery = {
...query,
...initCopyResult,
dataSource: nextSource,
aggregateOperator: newOperators[0].value,
};
setOperators(newOperators);
handleSetQueryData(index, newQuery);
},
[
isListViewPanel,
panelType,
query,
handleSetQueryData,
index,
redirectWithQueryBuilderData,
],
);
const handleDeleteQuery = useCallback(() => {
if (currentQuery.builder.queryData.length > 1) {
removeQueryBuilderEntityByIndex('queryData', index);
}
}, [removeQueryBuilderEntityByIndex, index, currentQuery]);
const handleChangeQueryData: HandleChangeQueryData = useCallback(
(key, value) => {
const newQuery: IBuilderQuery = {
...query,
[key]:
key === LEGEND && typeof value === 'string'
? getFormatedLegend(value)
: value,
};
handleSetQueryData(index, newQuery);
},
[query, index, handleSetQueryData],
);
const handleChangeFormulaData: HandleChangeFormulaData = useCallback(
(key, value) => {
const newFormula: IBuilderFormula = {
...(formula || ({} as IBuilderFormula)),
[key]: value,
};
handleSetFormulaData(index, newFormula);
},
[formula, handleSetFormulaData, index],
);
const isMetricsDataSource = query.dataSource === DataSource.METRICS;
const isTracePanelType = panelType === PANEL_TYPES.TRACE;
useEffect(() => {
if (initialDataSource && dataSource !== initialDataSource) return;
const initialOperators = getOperatorsBySourceAndPanelType({
dataSource,
panelType: panelType || PANEL_TYPES.TIME_SERIES,
});
if (JSON.stringify(operators) === JSON.stringify(initialOperators)) return;
setOperators(initialOperators);
}, [dataSource, initialDataSource, panelType, operators]);
useEffect(() => {
const additionalFilters = getNewListOfAdditionalFilters(dataSource, true);
setListOfAdditionalFilters(additionalFilters);
}, [dataSource, aggregateOperator, getNewListOfAdditionalFilters]);
useEffect(() => {
const additionalFilters = getNewListOfAdditionalFilters(dataSource, false);
setListOfAdditionalFormulaFilters(additionalFilters);
}, [dataSource, aggregateOperator, getNewListOfAdditionalFilters]);
return {
isTracePanelType,
isMetricsDataSource,
operators,
listOfAdditionalFilters,
handleChangeOperator,
handleChangeAggregatorAttribute,
handleChangeDataSource,
handleDeleteQuery,
handleChangeQueryData,
listOfAdditionalFormulaFilters,
handleChangeFormulaData,
};
};