import { Col, Input, Row } from 'antd'; // ** Constants import { initialAggregateAttribute, initialQueryBuilderFormValues, mapOfFilters, mapOfOperators, } from 'constants/queryBuilder'; // ** Components import { AdditionalFiltersToggler, DataSourceDropdown, FilterLabel, ListMarker, } from 'container/QueryBuilder/components'; import { AggregatorFilter, GroupByFilter, OperatorsSelect, ReduceToFilter, } from 'container/QueryBuilder/filters'; import AggregateEveryFilter from 'container/QueryBuilder/filters/AggregateEveryFilter'; import LimitFilter from 'container/QueryBuilder/filters/LimitFilter/LimitFilter'; import { OrderByFilter } from 'container/QueryBuilder/filters/OrderByFilter'; import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch'; import { useQueryBuilder } from 'hooks/useQueryBuilder'; import { findDataTypeOfOperator } from 'lib/query/findDataTypeOfOperator'; // ** Hooks import React, { memo, useCallback, useMemo } from 'react'; import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse'; import { IBuilderQueryForm, TagFilter, } from 'types/api/queryBuilder/queryBuilderData'; import { DataSource } from 'types/common/queryBuilder'; import { transformToUpperCase } from 'utils/transformToUpperCase'; // ** Types import { QueryProps } from './Query.interfaces'; // ** Styles import { StyledDeleteEntity, StyledFilterRow, StyledRow } from './Query.styled'; export const Query = memo(function Query({ index, isAvailableToDisable, queryVariant, query, panelType, }: QueryProps): JSX.Element { const { handleSetQueryData, removeEntityByIndex, initialDataSource, } = useQueryBuilder(); const currentListOfOperators = useMemo( () => mapOfOperators[query.dataSource], [query], ); const listOfAdditionalFilters = useMemo(() => mapOfFilters[query.dataSource], [ query, ]); const handleChangeOperator = useCallback( (value: string): void => { const aggregateDataType: BaseAutocompleteData['dataType'] = query.aggregateAttribute.dataType; const newQuery: IBuilderQueryForm = { ...query, aggregateOperator: value, having: [], groupBy: [], orderBy: [], limit: null, tagFilters: { items: [], op: 'AND' }, }; if (!aggregateDataType) { handleSetQueryData(index, newQuery); return; } switch (aggregateDataType) { case 'string': case 'bool': { const typeOfValue = findDataTypeOfOperator(value); handleSetQueryData(index, { ...newQuery, ...(typeOfValue === 'number' ? { aggregateAttribute: initialAggregateAttribute } : {}), }); break; } case 'float64': case 'int64': { handleSetQueryData(index, newQuery); break; } default: { handleSetQueryData(index, newQuery); break; } } }, [index, query, handleSetQueryData], ); const handleChangeAggregatorAttribute = useCallback( (value: BaseAutocompleteData): void => { const newQuery: IBuilderQueryForm = { ...query, aggregateAttribute: value, }; handleSetQueryData(index, newQuery); }, [index, query, handleSetQueryData], ); const handleChangeDataSource = useCallback( (nextSource: DataSource): void => { let newQuery: IBuilderQueryForm = { ...query, dataSource: nextSource, }; if (nextSource !== query.dataSource) { const initCopy = { ...(initialQueryBuilderFormValues as Partial), }; delete initCopy.queryName; newQuery = { ...newQuery, ...initCopy, dataSource: initialDataSource || nextSource, aggregateOperator: mapOfOperators[nextSource][0], }; } handleSetQueryData(index, newQuery); }, [index, query, initialDataSource, handleSetQueryData], ); const handleToggleDisableQuery = useCallback((): void => { const newQuery: IBuilderQueryForm = { ...query, disabled: !query.disabled, }; handleSetQueryData(index, newQuery); }, [index, query, handleSetQueryData]); const handleChangeGroupByKeys = useCallback( (values: BaseAutocompleteData[]): void => { const newQuery: IBuilderQueryForm = { ...query, groupBy: values, }; handleSetQueryData(index, newQuery); }, [index, query, handleSetQueryData], ); const handleChangeQueryLegend = useCallback( (e: React.ChangeEvent): void => { const newQuery: IBuilderQueryForm = { ...query, legend: e.target.value, }; handleSetQueryData(index, newQuery); }, [index, query, handleSetQueryData], ); const handleChangeReduceTo = useCallback( (value: string): void => { const newQuery: IBuilderQueryForm = { ...query, reduceTo: value, }; handleSetQueryData(index, newQuery); }, [index, query, handleSetQueryData], ); const handleDeleteQuery = useCallback(() => { removeEntityByIndex('queryData', index); }, [removeEntityByIndex, index]); const isMatricsDataSource = useMemo( () => query.dataSource === DataSource.METRICS, [query.dataSource], ); const handleChangeOrderByKeys = useCallback( (values: BaseAutocompleteData[]): void => { const newQuery: IBuilderQueryForm = { ...query, orderBy: values, }; handleSetQueryData(index, newQuery); }, [handleSetQueryData, index, query], ); const handleChangeLimit = useCallback( (value: number | null): void => { const newQuery: IBuilderQueryForm = { ...query, limit: value, }; handleSetQueryData(index, newQuery); }, [index, query, handleSetQueryData], ); const handleChangeAggregateEvery = useCallback( (value: number): void => { const newQuery: IBuilderQueryForm = { ...query, stepInterval: value, }; handleSetQueryData(index, newQuery); }, [index, query, handleSetQueryData], ); const handleChangeTagFilters = useCallback( (value: TagFilter): void => { const newQuery: IBuilderQueryForm = { ...query, tagFilters: value, }; handleSetQueryData(index, newQuery); }, [index, query, handleSetQueryData], ); return ( {queryVariant === 'dropdown' ? ( ) : ( )} {isMatricsDataSource && } {panelType === 'VALUE' ? ( ) : ( )} {!isMatricsDataSource && ( )} ); });