import './QueryFunctions.styles.scss'; import { Button, Tooltip, Typography } from 'antd'; import cx from 'classnames'; import { useIsDarkMode } from 'hooks/useDarkMode'; import { cloneDeep, pullAt } from 'lodash-es'; import { Plus } from 'lucide-react'; import { useState } from 'react'; import { IBuilderQuery, QueryFunctionProps, } from 'types/api/queryBuilder/queryBuilderData'; import { DataSource, QueryFunctionsTypes } from 'types/common/queryBuilder'; import Function from './Function'; import { toFloat64 } from './utils'; const defaultMetricFunctionStruct: QueryFunctionProps = { name: QueryFunctionsTypes.CUTOFF_MIN, args: [], }; const defaultLogFunctionStruct: QueryFunctionProps = { name: QueryFunctionsTypes.TIME_SHIFT, args: [], }; interface QueryFunctionsProps { query: IBuilderQuery; queryFunctions: QueryFunctionProps[]; onChange: (functions: QueryFunctionProps[]) => void; maxFunctions: number; } // SVG component function FunctionIcon({ fillColor = 'white', className, }: { fillColor: string; className: string; }): JSX.Element { return ( ); } export default function QueryFunctions({ query, queryFunctions, onChange, maxFunctions = 3, }: QueryFunctionsProps): JSX.Element { const [functions, setFunctions] = useState( queryFunctions, ); const isDarkMode = useIsDarkMode(); const hasAnomalyFunction = functions.some((func) => func.name === 'anomaly'); const handleAddNewFunction = (): void => { const defaultFunctionStruct = query.dataSource === DataSource.LOGS ? defaultLogFunctionStruct : defaultMetricFunctionStruct; const updatedFunctionsArr = [ ...functions, { ...defaultFunctionStruct, }, ]; const functionsCopy = cloneDeep(updatedFunctionsArr); const anomalyFuncIndex = functionsCopy.findIndex( (func) => func.name === 'anomaly', ); if (anomalyFuncIndex !== -1) { const anomalyFunc = functionsCopy[anomalyFuncIndex]; functionsCopy.splice(anomalyFuncIndex, 1); functionsCopy.push(anomalyFunc); } setFunctions(functionsCopy); onChange(functionsCopy); }; const handleDeleteFunction = ( queryFunction: QueryFunctionProps, index: number, ): void => { const clonedFunctions = cloneDeep(functions); pullAt(clonedFunctions, index); setFunctions(clonedFunctions); onChange(clonedFunctions); }; const handleUpdateFunctionName = ( func: QueryFunctionProps, index: number, value: string, ): void => { const updateFunctions = cloneDeep(functions); if (updateFunctions && updateFunctions.length > 0 && updateFunctions[index]) { updateFunctions[index].name = value; setFunctions(updateFunctions); onChange(updateFunctions); } }; const handleUpdateFunctionArgs = ( func: QueryFunctionProps, index: number, value: string, ): void => { const updateFunctions = cloneDeep(functions); if (updateFunctions && updateFunctions.length > 0 && updateFunctions[index]) { updateFunctions[index].args = [ // timeShift expects a float64 value, so we convert the string to a number // For other functions, we keep the value as a string updateFunctions[index].name === QueryFunctionsTypes.TIME_SHIFT ? toFloat64(value) : value, ]; setFunctions(updateFunctions); onChange(updateFunctions); } }; return (
0 ? 'hasFunctions' : '', )} >
{functions.map((func, index) => ( ))}
= 3 ? ( `Functions are in early access. You can add a maximum of ${ hasAnomalyFunction ? 2 : 3 } function as of now.` ) : (
Add new function {' '}
Learn more
) } placement="right" >
); }