mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-07-30 21:21:59 +08:00
refactor(query_builder): remove old codebase (#2686)
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
This commit is contained in:
parent
76331001b7
commit
9da399023b
@ -1,5 +1,3 @@
|
||||
import { EAggregateOperator, EReduceOperator } from 'types/common/dashboard';
|
||||
|
||||
export const PromQLQueryTemplate = {
|
||||
query: '',
|
||||
legend: '',
|
||||
@ -11,24 +9,3 @@ export const ClickHouseQueryTemplate = {
|
||||
legend: '',
|
||||
disabled: false,
|
||||
};
|
||||
|
||||
export const QueryBuilderQueryTemplate = {
|
||||
metricName: null,
|
||||
aggregateOperator: EAggregateOperator.NOOP,
|
||||
tagFilters: {
|
||||
op: 'AND',
|
||||
items: [],
|
||||
},
|
||||
legend: '',
|
||||
disabled: false,
|
||||
// Specific to TIME_SERIES type graph
|
||||
groupBy: [],
|
||||
// Specific to VALUE type graph
|
||||
reduceTo: EReduceOperator['Latest of values in timeframe'],
|
||||
};
|
||||
|
||||
export const QueryBuilderFormulaTemplate = {
|
||||
expression: '',
|
||||
disabled: false,
|
||||
legend: '',
|
||||
};
|
||||
|
@ -1,18 +0,0 @@
|
||||
import { EAggregateOperator } from 'types/common/dashboard';
|
||||
|
||||
export const AggregateFunctions = Object.keys(EAggregateOperator)
|
||||
.filter((key) => Number.isNaN(parseInt(key, 10)))
|
||||
.map((key) => ({
|
||||
label: key,
|
||||
value: EAggregateOperator[key as keyof typeof EAggregateOperator],
|
||||
}));
|
||||
|
||||
export const TagKeyOperator = [
|
||||
{ label: 'In', value: 'IN' },
|
||||
{ label: 'Not In', value: 'NIN' },
|
||||
{ label: 'Like', value: 'LIKE' },
|
||||
{ label: 'Not Like', value: 'NLIKE' },
|
||||
// { label: 'Equal', value: 'EQ' },
|
||||
// { label: 'Not Equal', value: 'NEQ' },
|
||||
// { label: 'REGEX', value: 'REGEX' },
|
||||
];
|
@ -3,8 +3,8 @@ import { ClickHouseQueryTemplate } from 'constants/dashboard';
|
||||
import GetQueryName from 'lib/query/GetQueryName';
|
||||
import React from 'react';
|
||||
import { Query } from 'types/api/dashboard/getAll';
|
||||
import { EQueryType } from 'types/common/dashboard';
|
||||
|
||||
import { WIDGET_CLICKHOUSE_QUERY_KEY_NAME } from '../../constants';
|
||||
import { QueryButton } from '../../styles';
|
||||
import { IHandleUpdatedQuery } from '../../types';
|
||||
import ClickHouseQueryBuilder from './query';
|
||||
@ -35,7 +35,7 @@ function ClickHouseQueryContainer({
|
||||
// hence, this method is only applies when queryIndex is in number format.
|
||||
|
||||
if (typeof queryIndex === 'number') {
|
||||
const allQueries = queryData[WIDGET_CLICKHOUSE_QUERY_KEY_NAME];
|
||||
const allQueries = queryData[EQueryType.CLICKHOUSE];
|
||||
|
||||
const currentIndexQuery = allQueries[queryIndex];
|
||||
|
||||
@ -57,8 +57,8 @@ function ClickHouseQueryContainer({
|
||||
}
|
||||
};
|
||||
const addQueryHandler = (): void => {
|
||||
queryData[WIDGET_CLICKHOUSE_QUERY_KEY_NAME].push({
|
||||
name: GetQueryName(queryData[WIDGET_CLICKHOUSE_QUERY_KEY_NAME]) || '',
|
||||
queryData[EQueryType.CLICKHOUSE].push({
|
||||
name: GetQueryName(queryData[EQueryType.CLICKHOUSE]) || '',
|
||||
...ClickHouseQueryTemplate,
|
||||
});
|
||||
updateQueryData({ updatedQuery: { ...queryData } });
|
||||
|
@ -3,8 +3,8 @@ import { PromQLQueryTemplate } from 'constants/dashboard';
|
||||
import GetQueryName from 'lib/query/GetQueryName';
|
||||
import React from 'react';
|
||||
import { IPromQLQuery, Query } from 'types/api/dashboard/getAll';
|
||||
import { EQueryType } from 'types/common/dashboard';
|
||||
|
||||
import { WIDGET_PROMQL_QUERY_KEY_NAME } from '../../constants';
|
||||
import { QueryButton } from '../../styles';
|
||||
import { IHandleUpdatedQuery } from '../../types';
|
||||
import PromQLQueryBuilder from './query';
|
||||
@ -28,7 +28,7 @@ function PromQLQueryContainer({
|
||||
toggleDisable,
|
||||
toggleDelete,
|
||||
}: IPromQLQueryHandleChange): void => {
|
||||
const allQueries = queryData[WIDGET_PROMQL_QUERY_KEY_NAME];
|
||||
const allQueries = queryData[EQueryType.PROM];
|
||||
const currentIndexQuery = allQueries[queryIndex as number];
|
||||
if (query !== undefined) currentIndexQuery.query = query;
|
||||
if (legend !== undefined) currentIndexQuery.legend = legend;
|
||||
@ -42,8 +42,8 @@ function PromQLQueryContainer({
|
||||
updateQueryData({ updatedQuery: { ...queryData } });
|
||||
};
|
||||
const addQueryHandler = (): void => {
|
||||
queryData[WIDGET_PROMQL_QUERY_KEY_NAME].push({
|
||||
name: GetQueryName(queryData[WIDGET_PROMQL_QUERY_KEY_NAME]) || '',
|
||||
queryData[EQueryType.PROM].push({
|
||||
name: GetQueryName(queryData[EQueryType.PROM]) || '',
|
||||
...PromQLQueryTemplate,
|
||||
});
|
||||
updateQueryData({ updatedQuery: { ...queryData } });
|
||||
|
@ -1,61 +0,0 @@
|
||||
import { createMachine } from 'xstate';
|
||||
|
||||
export const ResourceAttributesFilterMachine =
|
||||
/** @xstate-layout N4IgpgJg5mDOIC5QBECGsAWAjA9qgThAAQDKYBAxhkQIIB2xAYgJYA2ALmPgHQAqqUANJgAngGIAcgFEAGr0SgADjljN2zHHQUgAHogAcAFgAM3AOz6ATAEYAzJdsA2Y4cOWAnABoQIxAFpDR2tuQ319AFYTcKdbFycAX3jvNExcAmIySmp6JjZOHn4hUTFNACFWAFd8bWVVdU1tPQQzY1MXY2tDdzNHM3dHd0NvXwR7biMTa313S0i+63DE5PRsPEJScnwqWgYiFg4uPgFhcQAlKRIpeSQQWrUNLRumx3Czbg8TR0sbS31jfUcw38fW47gBHmm4XCVms3SWIBSq3SGyyO1yBx4AHlFFxUOwcPhJLJrkoVPcGk9ENYFuF3i5YR0wtEHECEAEgiEmV8zH1DLYzHZ4Yi0utMltsrt9vluNjcfjCWVKtUbnd6o9QE1rMYBtxbGFvsZ3NrZj1WdYOfotUZLX0XEFHEKViKMpttjk9nlDrL8HiCWJzpcSbcyWrGoh3NCQj0zK53P1ph1WeFLLqnJZ2s5vmZLA6kginWsXaj3VLDoUAGqoSpgEp0cpVGohh5hhDWDy0sz8zruakzamWVm-Qyg362V5-AZOayO1KFlHitEejFHKCV6v+i5XRt1ZuU1s52zjNOOaZfdOWIY+RDZ0Hc6ZmKEXqyLPPCudit2Sz08ACSEFYNbSHI27kuquiIOEjiONwjJgrM3RWJYZisgEIJgnYPTmuEdi2OaiR5nQOAQHA2hvsiH4Sui0qFCcIGhnuLSmP0YJuJ2xjJsmKELG8XZTK0tjdHG06vgW5GupRS7St6vrKqSO4UhqVL8TBWp8o4eqdl0A5Xmy3G6gK56-B4uERDOSKiuJi6lgUAhrhUYB0buimtrEKZBDYrxaS0OZca8+ltheybOI4hivGZzrzp+VGHH+AGOQp4EIHy+ghNYnawtG4TsbYvk8QKfHGAJfQ9uF76WSW37xWBTSGJ0qXpd0vRZdEKGPqC2YeO2-zfO4+HxEAA */
|
||||
createMachine({
|
||||
tsTypes: {} as import('./MetricTagKey.machine.typegen').Typegen0,
|
||||
initial: 'Idle',
|
||||
states: {
|
||||
TagKey: {
|
||||
on: {
|
||||
NEXT: {
|
||||
actions: 'onSelectOperator',
|
||||
target: 'Operator',
|
||||
},
|
||||
onBlur: {
|
||||
actions: 'onBlurPurge',
|
||||
target: 'Idle',
|
||||
},
|
||||
RESET: {
|
||||
target: 'Idle',
|
||||
},
|
||||
},
|
||||
},
|
||||
Operator: {
|
||||
on: {
|
||||
NEXT: {
|
||||
actions: 'onSelectTagValue',
|
||||
target: 'TagValue',
|
||||
},
|
||||
// onBlur: {
|
||||
// actions: 'onBlurPurge',
|
||||
// target: 'Idle',
|
||||
// },
|
||||
RESET: {
|
||||
target: 'Idle',
|
||||
},
|
||||
},
|
||||
},
|
||||
TagValue: {
|
||||
on: {
|
||||
onBlur: {
|
||||
actions: ['onValidateQuery'],
|
||||
// target: 'Idle',
|
||||
},
|
||||
RESET: {
|
||||
target: 'Idle',
|
||||
},
|
||||
},
|
||||
},
|
||||
Idle: {
|
||||
on: {
|
||||
NEXT: {
|
||||
actions: 'onSelectTagKey',
|
||||
description: 'Select Category',
|
||||
target: 'TagKey',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
id: 'Dashboard Search And Filter',
|
||||
});
|
@ -1,32 +0,0 @@
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
'xstate.init': { type: 'xstate.init' };
|
||||
};
|
||||
invokeSrcNameMap: {};
|
||||
missingImplementations: {
|
||||
actions:
|
||||
| 'onBlurPurge'
|
||||
| 'onSelectOperator'
|
||||
| 'onSelectTagKey'
|
||||
| 'onSelectTagValue'
|
||||
| 'onValidateQuery';
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
onBlurPurge: 'onBlur';
|
||||
onSelectOperator: 'NEXT';
|
||||
onSelectTagKey: 'NEXT';
|
||||
onSelectTagValue: 'NEXT';
|
||||
onValidateQuery: 'onBlur';
|
||||
};
|
||||
eventsCausingDelays: {};
|
||||
eventsCausingGuards: {};
|
||||
eventsCausingServices: {};
|
||||
matchesStates: 'Idle' | 'Operator' | 'TagKey' | 'TagValue';
|
||||
tags: never;
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import { QueryChipContainer, QueryChipItem } from './styles';
|
||||
import { ITagKeyValueQuery } from './types';
|
||||
|
||||
interface IQueryChipProps {
|
||||
queryData: ITagKeyValueQuery;
|
||||
onClose: (id: string) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export default function QueryChip({
|
||||
queryData,
|
||||
onClose,
|
||||
disabled,
|
||||
}: IQueryChipProps): JSX.Element {
|
||||
return (
|
||||
<QueryChipContainer>
|
||||
<QueryChipItem>{queryData.key}</QueryChipItem>
|
||||
<QueryChipItem>{queryData.op}</QueryChipItem>
|
||||
<QueryChipItem
|
||||
closable={!disabled}
|
||||
onClose={(): void => {
|
||||
if (!disabled) onClose(queryData.id);
|
||||
}}
|
||||
>
|
||||
{queryData.value.join(', ')}
|
||||
</QueryChipItem>
|
||||
</QueryChipContainer>
|
||||
);
|
||||
}
|
||||
QueryChip.defaultProps = {
|
||||
disabled: false,
|
||||
};
|
@ -1,209 +0,0 @@
|
||||
import { CloseCircleFilled } from '@ant-design/icons';
|
||||
import { useMachine } from '@xstate/react';
|
||||
import { Button, Select, Spin } from 'antd';
|
||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
import { map } from 'lodash-es';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { IMetricsBuilderQuery } from 'types/api/dashboard/getAll';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { ResourceAttributesFilterMachine } from './MetricTagKey.machine';
|
||||
import QueryChip from './QueryChip';
|
||||
import { QueryChipItem, SearchContainer } from './styles';
|
||||
import { IOption, ITagKeyValueQuery } from './types';
|
||||
import {
|
||||
createQuery,
|
||||
GetTagKeys,
|
||||
GetTagValues,
|
||||
OperatorSchema,
|
||||
SingleValueOperators,
|
||||
} from './utils';
|
||||
|
||||
interface IMetricTagKeyFilterProps {
|
||||
metricName: IMetricsBuilderQuery['metricName'];
|
||||
onSetQuery: (args: IMetricsBuilderQuery['tagFilters']['items']) => void;
|
||||
selectedTagFilters: IMetricsBuilderQuery['tagFilters']['items'];
|
||||
}
|
||||
|
||||
function MetricTagKeyFilter({
|
||||
metricName,
|
||||
onSetQuery,
|
||||
selectedTagFilters: selectedTagQueries,
|
||||
}: IMetricTagKeyFilterProps): JSX.Element | null {
|
||||
const isDarkMode = useIsDarkMode();
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [selectedValues, setSelectedValues] = useState<string[]>([]);
|
||||
const [staging, setStaging] = useState<string[]>([]);
|
||||
const [queries, setQueries] = useState<ITagKeyValueQuery[]>([]);
|
||||
const [optionsData, setOptionsData] = useState<{
|
||||
mode: undefined | 'tags' | 'multiple';
|
||||
options: IOption[];
|
||||
}>({
|
||||
mode: undefined,
|
||||
options: [],
|
||||
});
|
||||
|
||||
const dispatchQueries = (
|
||||
updatedQueries: IMetricsBuilderQuery['tagFilters']['items'],
|
||||
): void => {
|
||||
onSetQuery(updatedQueries);
|
||||
setQueries(updatedQueries);
|
||||
};
|
||||
const handleLoading = (isLoading: boolean): void => {
|
||||
setLoading(isLoading);
|
||||
if (isLoading) {
|
||||
setOptionsData({ mode: undefined, options: [] });
|
||||
}
|
||||
};
|
||||
const [state, send] = useMachine(ResourceAttributesFilterMachine, {
|
||||
actions: {
|
||||
onSelectTagKey: () => {
|
||||
handleLoading(true);
|
||||
GetTagKeys(metricName || '')
|
||||
.then((tagKeys) => setOptionsData({ options: tagKeys, mode: undefined }))
|
||||
.finally(() => {
|
||||
handleLoading(false);
|
||||
});
|
||||
},
|
||||
onSelectOperator: () => {
|
||||
setOptionsData({ options: OperatorSchema, mode: undefined });
|
||||
},
|
||||
onSelectTagValue: () => {
|
||||
handleLoading(true);
|
||||
|
||||
GetTagValues(staging[0], metricName || '')
|
||||
.then((tagValuesOptions) =>
|
||||
setOptionsData({ options: tagValuesOptions, mode: 'tags' }),
|
||||
)
|
||||
.finally(() => {
|
||||
handleLoading(false);
|
||||
});
|
||||
},
|
||||
onBlurPurge: () => {
|
||||
setSelectedValues([]);
|
||||
setStaging([]);
|
||||
},
|
||||
onValidateQuery: (): void => {
|
||||
if (staging.length < 2 || selectedValues.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const generatedQuery = createQuery([...staging, selectedValues]);
|
||||
|
||||
if (generatedQuery) {
|
||||
dispatchQueries([...queries, generatedQuery]);
|
||||
setSelectedValues([]);
|
||||
setStaging([]);
|
||||
send('RESET');
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setQueries(selectedTagQueries);
|
||||
}, [selectedTagQueries]);
|
||||
|
||||
const handleFocus = (): void => {
|
||||
if (state.value === 'Idle') {
|
||||
send('NEXT');
|
||||
}
|
||||
};
|
||||
|
||||
const handleBlur = useCallback((): void => {
|
||||
send('onBlur');
|
||||
}, [send]);
|
||||
|
||||
useEffect(() => {
|
||||
handleBlur();
|
||||
}, [handleBlur, metricName]);
|
||||
|
||||
const handleChange = (value: never | string[]): void => {
|
||||
if (!optionsData.mode) {
|
||||
setStaging((prevStaging) => [...prevStaging, String(value)]);
|
||||
setSelectedValues([]);
|
||||
send('NEXT');
|
||||
return;
|
||||
}
|
||||
if (
|
||||
state.value === 'TagValue' &&
|
||||
SingleValueOperators.includes(staging[staging.length - 1]) &&
|
||||
Array.isArray(value)
|
||||
) {
|
||||
setSelectedValues([value[value.length - 1]]);
|
||||
return;
|
||||
}
|
||||
|
||||
setSelectedValues([...value]);
|
||||
};
|
||||
|
||||
const handleClose = (id: string): void => {
|
||||
dispatchQueries(queries.filter((queryData) => queryData.id !== id));
|
||||
};
|
||||
|
||||
const handleClearAll = (): void => {
|
||||
send('RESET');
|
||||
dispatchQueries([]);
|
||||
setStaging([]);
|
||||
setSelectedValues([]);
|
||||
};
|
||||
|
||||
return (
|
||||
<SearchContainer isDarkMode={isDarkMode}>
|
||||
<div style={{ display: 'inline-flex', flexWrap: 'wrap' }}>
|
||||
{queries.length > 0 &&
|
||||
map(
|
||||
queries,
|
||||
(query): JSX.Element => (
|
||||
<QueryChip key={query.id} queryData={query} onClose={handleClose} />
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
{map(staging, (item) => (
|
||||
<QueryChipItem key={uuid()}>{item}</QueryChipItem>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', width: '100%' }}>
|
||||
<Select
|
||||
disabled={!metricName}
|
||||
placeholder={`Select ${
|
||||
state.value === 'Idle' ? 'Tag Key Pair' : state.value
|
||||
}`}
|
||||
onChange={handleChange}
|
||||
bordered={false}
|
||||
value={selectedValues as never}
|
||||
style={{ flex: 1 }}
|
||||
options={optionsData.options}
|
||||
mode={optionsData?.mode}
|
||||
showArrow={false}
|
||||
onFocus={handleFocus}
|
||||
onBlur={handleBlur}
|
||||
notFoundContent={
|
||||
loading ? (
|
||||
<span>
|
||||
<Spin size="small" /> Loading...{' '}
|
||||
</span>
|
||||
) : (
|
||||
<span>
|
||||
No resource attributes available to filter. Please refer docs to send
|
||||
attributes.
|
||||
</span>
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
{queries.length || staging.length || selectedValues.length ? (
|
||||
<Button
|
||||
onClick={handleClearAll}
|
||||
icon={<CloseCircleFilled />}
|
||||
type="text"
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
</SearchContainer>
|
||||
);
|
||||
}
|
||||
|
||||
export default MetricTagKeyFilter;
|
@ -1,30 +0,0 @@
|
||||
import { grey } from '@ant-design/colors';
|
||||
import { Tag } from 'antd';
|
||||
import styled from 'styled-components';
|
||||
|
||||
export const SearchContainer = styled.div<{
|
||||
isDarkMode: boolean;
|
||||
disabled?: boolean;
|
||||
}>`
|
||||
background: ${({ isDarkMode }): string => (isDarkMode ? '#000' : '#fff')};
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0.2rem;
|
||||
border: 1px solid #ccc5;
|
||||
${({ disabled }): string => (disabled ? `cursor: not-allowed;` : '')}
|
||||
`;
|
||||
export const QueryChipContainer = styled.span`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 0.5rem;
|
||||
&:hover {
|
||||
& > * {
|
||||
background: ${grey.primary}44;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const QueryChipItem = styled(Tag)`
|
||||
margin-right: 0.1rem;
|
||||
`;
|
@ -1,18 +0,0 @@
|
||||
export interface IOption {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface IMetricBuilderTagKeyQuery {
|
||||
id: string;
|
||||
tagKey: string;
|
||||
operator: string;
|
||||
tagValue: string[];
|
||||
}
|
||||
|
||||
export interface ITagKeyValueQuery {
|
||||
id: string;
|
||||
key: string;
|
||||
op: string;
|
||||
value: string[];
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
import {
|
||||
getResourceAttributesTagKeys,
|
||||
getResourceAttributesTagValues,
|
||||
} from 'api/metrics/getResourceAttributes';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { TagKeyOperator } from '../../Options';
|
||||
import { IOption, ITagKeyValueQuery } from './types';
|
||||
|
||||
export const OperatorSchema: IOption[] = TagKeyOperator;
|
||||
|
||||
export const GetTagKeys = async (metricName: string): Promise<IOption[]> => {
|
||||
const { payload } = await getResourceAttributesTagKeys({ metricName });
|
||||
if (!payload || !payload?.data) {
|
||||
return [];
|
||||
}
|
||||
return payload.data.map((tagKey: string) => ({
|
||||
label: tagKey,
|
||||
value: tagKey,
|
||||
}));
|
||||
};
|
||||
|
||||
export const GetTagValues = async (
|
||||
tagKey: string,
|
||||
metricName: string,
|
||||
): Promise<IOption[]> => {
|
||||
const { payload } = await getResourceAttributesTagValues({
|
||||
tagKey,
|
||||
metricName,
|
||||
});
|
||||
|
||||
if (!payload || !payload?.data) {
|
||||
return [];
|
||||
}
|
||||
return payload.data.map((tagValue: string) => ({
|
||||
label: tagValue,
|
||||
value: tagValue,
|
||||
}));
|
||||
};
|
||||
|
||||
export const createQuery = (
|
||||
selectedItems: Array<string | string[]> = [],
|
||||
): ITagKeyValueQuery | null => {
|
||||
if (selectedItems.length === 3) {
|
||||
return {
|
||||
id: uuid().slice(0, 8),
|
||||
key: typeof selectedItems[0] === 'string' ? selectedItems[0] : '',
|
||||
op: typeof selectedItems[1] === 'string' ? selectedItems[1] : '',
|
||||
value: selectedItems[2] as string[],
|
||||
};
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const SingleValueOperators = ['LIKE', 'NLIKE'];
|
@ -1,52 +0,0 @@
|
||||
import { Input } from 'antd';
|
||||
import React from 'react';
|
||||
import { IMetricsBuilderFormula } from 'types/api/dashboard/getAll';
|
||||
|
||||
import QueryHeader from '../QueryHeader';
|
||||
import { IQueryBuilderFormulaHandleChange } from './types';
|
||||
|
||||
const { TextArea } = Input;
|
||||
|
||||
interface IMetricsBuilderFormulaProps {
|
||||
formulaData: IMetricsBuilderFormula;
|
||||
formulaIndex: number | string;
|
||||
handleFormulaChange: (args: IQueryBuilderFormulaHandleChange) => void;
|
||||
}
|
||||
function MetricsBuilderFormula({
|
||||
formulaData,
|
||||
formulaIndex,
|
||||
handleFormulaChange,
|
||||
}: IMetricsBuilderFormulaProps): JSX.Element {
|
||||
return (
|
||||
<QueryHeader
|
||||
name={formulaData.name}
|
||||
disabled={formulaData.disabled}
|
||||
onDisable={(): void =>
|
||||
handleFormulaChange({ formulaIndex, toggleDisable: true })
|
||||
}
|
||||
onDelete={(): void => {
|
||||
handleFormulaChange({ formulaIndex, toggleDelete: true });
|
||||
}}
|
||||
>
|
||||
<TextArea
|
||||
onChange={(event): void =>
|
||||
handleFormulaChange({ formulaIndex, expression: event.target.value })
|
||||
}
|
||||
size="middle"
|
||||
defaultValue={formulaData.expression}
|
||||
style={{ marginBottom: '0.5rem' }}
|
||||
rows={2}
|
||||
/>
|
||||
<Input
|
||||
onChange={(event): void => {
|
||||
handleFormulaChange({ formulaIndex, legend: event.target.value });
|
||||
}}
|
||||
size="middle"
|
||||
defaultValue={formulaData.legend}
|
||||
addonBefore="Legend Format"
|
||||
/>
|
||||
</QueryHeader>
|
||||
);
|
||||
}
|
||||
|
||||
export default MetricsBuilderFormula;
|
@ -1,191 +0,0 @@
|
||||
/* eslint-disable */
|
||||
// TODO: fix it after merge actual functionality
|
||||
// @ts-nocheck
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
QueryBuilderFormulaTemplate,
|
||||
QueryBuilderQueryTemplate,
|
||||
} from 'constants/dashboard';
|
||||
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
||||
import { useNotifications } from 'hooks/useNotifications';
|
||||
import GetFormulaName from 'lib/query/GetFormulaName';
|
||||
import GetQueryName from 'lib/query/GetQueryName';
|
||||
import React from 'react';
|
||||
import { Query } from 'types/api/dashboard/getAll';
|
||||
|
||||
import {
|
||||
WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME,
|
||||
WIDGET_QUERY_BUILDER_QUERY_KEY_NAME,
|
||||
} from '../../constants';
|
||||
import { QueryButton } from '../../styles';
|
||||
import { IHandleUpdatedQuery } from '../../types';
|
||||
import MetricsBuilderFormula from './formula';
|
||||
import MetricsBuilder from './query';
|
||||
import {
|
||||
IQueryBuilderFormulaHandleChange,
|
||||
IQueryBuilderQueryHandleChange,
|
||||
} from './types';
|
||||
import { canCreateQueryAndFormula } from './utils';
|
||||
|
||||
interface IQueryBuilderQueryContainerProps {
|
||||
queryData: Query;
|
||||
updateQueryData: (args: IHandleUpdatedQuery) => void;
|
||||
metricsBuilderQueries: Query['metricsBuilder'];
|
||||
selectedGraph: GRAPH_TYPES;
|
||||
}
|
||||
|
||||
function QueryBuilderQueryContainer({
|
||||
queryData,
|
||||
updateQueryData,
|
||||
metricsBuilderQueries,
|
||||
selectedGraph,
|
||||
}: IQueryBuilderQueryContainerProps): JSX.Element | null {
|
||||
const { notifications } = useNotifications();
|
||||
const handleQueryBuilderQueryChange = ({
|
||||
queryIndex,
|
||||
aggregateFunction,
|
||||
metricName,
|
||||
tagFilters,
|
||||
groupBy,
|
||||
legend,
|
||||
toggleDisable,
|
||||
toggleDelete,
|
||||
reduceTo,
|
||||
}: IQueryBuilderQueryHandleChange): void => {
|
||||
const allQueries =
|
||||
queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME].queryBuilder;
|
||||
const currentIndexQuery = allQueries[queryIndex as number];
|
||||
if (aggregateFunction) {
|
||||
currentIndexQuery.aggregateOperator = aggregateFunction;
|
||||
}
|
||||
|
||||
if (metricName !== undefined) {
|
||||
currentIndexQuery.metricName = metricName;
|
||||
}
|
||||
|
||||
if (tagFilters) {
|
||||
currentIndexQuery.tagFilters.items = tagFilters;
|
||||
}
|
||||
|
||||
if (groupBy) {
|
||||
currentIndexQuery.groupBy = groupBy;
|
||||
}
|
||||
|
||||
if (reduceTo) {
|
||||
currentIndexQuery.reduceTo = reduceTo;
|
||||
}
|
||||
|
||||
if (legend !== undefined) {
|
||||
currentIndexQuery.legend = legend;
|
||||
}
|
||||
if (toggleDisable) {
|
||||
currentIndexQuery.disabled = !currentIndexQuery.disabled;
|
||||
}
|
||||
if (toggleDelete) {
|
||||
allQueries.splice(queryIndex as number, 1);
|
||||
}
|
||||
updateQueryData({ updatedQuery: { ...queryData } });
|
||||
};
|
||||
const handleQueryBuilderFormulaChange = ({
|
||||
formulaIndex,
|
||||
expression,
|
||||
legend,
|
||||
toggleDisable,
|
||||
toggleDelete,
|
||||
}: IQueryBuilderFormulaHandleChange): void => {
|
||||
const allFormulas =
|
||||
queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME][
|
||||
WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME
|
||||
];
|
||||
const currentIndexFormula = allFormulas[formulaIndex as number];
|
||||
|
||||
if (expression !== undefined) {
|
||||
currentIndexFormula.expression = expression;
|
||||
}
|
||||
if (legend !== undefined) {
|
||||
currentIndexFormula.legend = legend;
|
||||
}
|
||||
|
||||
if (toggleDisable) {
|
||||
currentIndexFormula.disabled = !currentIndexFormula.disabled;
|
||||
}
|
||||
|
||||
if (toggleDelete) {
|
||||
allFormulas.splice(formulaIndex as number, 1);
|
||||
}
|
||||
updateQueryData({ updatedQuery: { ...queryData } });
|
||||
};
|
||||
const addQueryHandler = (): void => {
|
||||
if (!canCreateQueryAndFormula(queryData)) {
|
||||
notifications.error({
|
||||
message:
|
||||
'Unable to create query. You can create at max 10 queries and formulae.',
|
||||
});
|
||||
return;
|
||||
}
|
||||
queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME].queryBuilder.push({
|
||||
name:
|
||||
GetQueryName(queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME].queryBuilder) ||
|
||||
'',
|
||||
...QueryBuilderQueryTemplate,
|
||||
});
|
||||
updateQueryData({ updatedQuery: { ...queryData } });
|
||||
};
|
||||
|
||||
const addFormulaHandler = (): void => {
|
||||
if (!canCreateQueryAndFormula(queryData)) {
|
||||
notifications.error({
|
||||
message:
|
||||
'Unable to create formula. You can create at max 10 queries and formulae.',
|
||||
});
|
||||
return;
|
||||
}
|
||||
queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME][
|
||||
WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME
|
||||
].push({
|
||||
name:
|
||||
GetFormulaName(
|
||||
queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME][
|
||||
WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME
|
||||
],
|
||||
) || '',
|
||||
...QueryBuilderFormulaTemplate,
|
||||
});
|
||||
updateQueryData({ updatedQuery: { ...queryData } });
|
||||
};
|
||||
|
||||
if (!metricsBuilderQueries) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{metricsBuilderQueries.queryBuilder.map((q, idx) => (
|
||||
<MetricsBuilder
|
||||
key={q.name}
|
||||
queryIndex={idx}
|
||||
queryData={q}
|
||||
handleQueryChange={handleQueryBuilderQueryChange}
|
||||
selectedGraph={selectedGraph}
|
||||
/>
|
||||
))}
|
||||
<QueryButton onClick={addQueryHandler} icon={<PlusOutlined />}>
|
||||
Query
|
||||
</QueryButton>
|
||||
<div style={{ marginTop: '1rem' }}>
|
||||
{metricsBuilderQueries.formulas.map((f, idx) => (
|
||||
<MetricsBuilderFormula
|
||||
key={f.name}
|
||||
formulaIndex={idx}
|
||||
formulaData={f}
|
||||
handleFormulaChange={handleQueryBuilderFormulaChange}
|
||||
/>
|
||||
))}
|
||||
<QueryButton onClick={addFormulaHandler} icon={<PlusOutlined />}>
|
||||
Formula
|
||||
</QueryButton>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default QueryBuilderQueryContainer;
|
@ -1,215 +0,0 @@
|
||||
import { AutoComplete, Col, Input, Row, Select, Spin } from 'antd';
|
||||
import { getMetricName } from 'api/metrics/getMetricName';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { IMetricsBuilderQuery } from 'types/api/dashboard/getAll';
|
||||
import { EReduceOperator } from 'types/common/dashboard';
|
||||
|
||||
import { AggregateFunctions } from '../Options';
|
||||
import QueryHeader from '../QueryHeader';
|
||||
import MetricTagKeyFilter from './MetricTagKeyFilter';
|
||||
import { IOption } from './MetricTagKeyFilter/types';
|
||||
import { GetTagKeys } from './MetricTagKeyFilter/utils';
|
||||
import { IQueryBuilderQueryHandleChange } from './types';
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
interface IMetricsBuilderProps {
|
||||
queryIndex: number | string;
|
||||
selectedGraph: GRAPH_TYPES;
|
||||
queryData: IMetricsBuilderQuery;
|
||||
handleQueryChange: (args: IQueryBuilderQueryHandleChange) => void;
|
||||
}
|
||||
|
||||
function MetricsBuilder({
|
||||
queryIndex,
|
||||
selectedGraph,
|
||||
queryData,
|
||||
handleQueryChange,
|
||||
}: IMetricsBuilderProps): JSX.Element {
|
||||
const [groupByOptions, setGroupByOptions] = useState<IOption[]>([]);
|
||||
const [metricName, setMetricName] = useState<string | null>(
|
||||
queryData.metricName,
|
||||
);
|
||||
|
||||
const [metricNameList, setMetricNameList] = useState<string[]>([]);
|
||||
const [metricNameLoading, setMetricNameLoading] = useState(false);
|
||||
|
||||
const handleMetricNameSelect = (e: string): void => {
|
||||
handleQueryChange({ queryIndex, metricName: e });
|
||||
setMetricName(e);
|
||||
};
|
||||
|
||||
const handleMetricNameSearch = async (searchQuery = ''): Promise<void> => {
|
||||
handleMetricNameSelect(searchQuery);
|
||||
setMetricNameList([]);
|
||||
setMetricNameLoading(true);
|
||||
const { payload } = await getMetricName(searchQuery);
|
||||
setMetricNameLoading(false);
|
||||
if (!payload || !payload.data) {
|
||||
return;
|
||||
}
|
||||
setMetricNameList(payload.data);
|
||||
};
|
||||
const [aggregateFunctionList, setAggregateFunctionList] = useState(
|
||||
AggregateFunctions,
|
||||
);
|
||||
const handleAggregateFunctionsSearch = (searchQuery = ''): void => {
|
||||
setAggregateFunctionList(
|
||||
AggregateFunctions.filter(({ label }) =>
|
||||
label.includes(searchQuery.toUpperCase()),
|
||||
) || [],
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
GetTagKeys(metricName || '').then((tagKeys) => {
|
||||
setGroupByOptions(tagKeys);
|
||||
});
|
||||
}, [metricName]);
|
||||
|
||||
return (
|
||||
<QueryHeader
|
||||
name={queryData.name}
|
||||
disabled={queryData.disabled}
|
||||
onDisable={(): void =>
|
||||
handleQueryChange({ queryIndex, toggleDisable: true })
|
||||
}
|
||||
onDelete={(): void => {
|
||||
handleQueryChange({ queryIndex, toggleDelete: true });
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', padding: '0.5rem' }}>
|
||||
<div>
|
||||
<Select
|
||||
onChange={(e): void =>
|
||||
handleQueryChange({ queryIndex, aggregateFunction: e })
|
||||
}
|
||||
defaultValue={queryData.aggregateOperator || AggregateFunctions[0]}
|
||||
style={{ minWidth: 150 }}
|
||||
options={aggregateFunctionList}
|
||||
showSearch
|
||||
onSearch={handleAggregateFunctionsSearch}
|
||||
filterOption={false}
|
||||
/>
|
||||
</div>
|
||||
<Row style={{ gap: '3%', margin: '0.5rem 0' }}>
|
||||
<Row style={{ flex: 2, gap: '3%' }}>
|
||||
<Select
|
||||
defaultValue="metrics"
|
||||
showArrow={false}
|
||||
dropdownStyle={{ display: 'none' }}
|
||||
>
|
||||
<Option value="metrics">Metrics</Option>
|
||||
</Select>
|
||||
|
||||
<AutoComplete
|
||||
showSearch
|
||||
placeholder="Metric Name (Start typing to get suggestions)"
|
||||
style={{ flex: 1, minWidth: 200 }}
|
||||
showArrow={false}
|
||||
filterOption={false}
|
||||
onSearch={handleMetricNameSearch}
|
||||
notFoundContent={metricNameLoading ? <Spin size="small" /> : null}
|
||||
options={metricNameList.map((option) => ({
|
||||
label: option,
|
||||
value: option,
|
||||
}))}
|
||||
defaultValue={queryData.metricName}
|
||||
value={metricName}
|
||||
onSelect={handleMetricNameSelect}
|
||||
/>
|
||||
</Row>
|
||||
<Col style={{ flex: 3 }}>
|
||||
<Row style={{ gap: '3%', marginBottom: '1rem' }}>
|
||||
<Select
|
||||
defaultValue="WHERE"
|
||||
showArrow={false}
|
||||
dropdownStyle={{ display: 'none' }}
|
||||
>
|
||||
<Option value="WHERE">WHERE</Option>
|
||||
</Select>
|
||||
<MetricTagKeyFilter
|
||||
metricName={metricName}
|
||||
selectedTagFilters={queryData.tagFilters.items}
|
||||
onSetQuery={(
|
||||
updatedTagFilters: IMetricsBuilderQuery['tagFilters']['items'],
|
||||
): void =>
|
||||
handleQueryChange({ queryIndex, tagFilters: updatedTagFilters })
|
||||
}
|
||||
/>
|
||||
</Row>
|
||||
<Row style={{ gap: '3%', marginBottom: '1rem' }}>
|
||||
{selectedGraph === PANEL_TYPES.TIME_SERIES ? (
|
||||
<>
|
||||
{' '}
|
||||
<Select
|
||||
defaultValue="GROUP BY"
|
||||
showArrow={false}
|
||||
dropdownStyle={{ display: 'none' }}
|
||||
>
|
||||
<Option value="GROUP BY">GROUP BY</Option>
|
||||
</Select>
|
||||
<Select
|
||||
mode="multiple"
|
||||
showSearch
|
||||
style={{ flex: 1 }}
|
||||
defaultActiveFirstOption={false}
|
||||
filterOption={false}
|
||||
notFoundContent={metricNameLoading ? <Spin size="small" /> : null}
|
||||
options={groupByOptions}
|
||||
defaultValue={queryData.groupBy}
|
||||
onChange={(e): void => {
|
||||
handleQueryChange({ queryIndex, groupBy: e });
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Select
|
||||
defaultValue="REDUCE TO"
|
||||
showArrow={false}
|
||||
dropdownStyle={{ display: 'none' }}
|
||||
>
|
||||
<Option value="GROUP BY">REDUCE TO</Option>
|
||||
</Select>
|
||||
<Select
|
||||
placeholder="Latest of values in timeframe"
|
||||
style={{ flex: 1 }}
|
||||
options={Object.keys(EReduceOperator)
|
||||
.filter((op) => !(parseInt(op, 10) >= 0))
|
||||
.map((op) => ({
|
||||
label: op,
|
||||
value: EReduceOperator[op as keyof typeof EReduceOperator],
|
||||
}))}
|
||||
defaultValue={
|
||||
EReduceOperator[
|
||||
(queryData.reduceTo as unknown) as keyof typeof EReduceOperator
|
||||
]
|
||||
}
|
||||
onChange={(e): void => {
|
||||
handleQueryChange({ queryIndex, reduceTo: e });
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{ margin: '0.5rem 0' }}>
|
||||
<Input
|
||||
onChange={(e): void => {
|
||||
handleQueryChange({ queryIndex, legend: e.target.value });
|
||||
}}
|
||||
size="middle"
|
||||
defaultValue={queryData.legend}
|
||||
addonBefore="Legend Format"
|
||||
/>
|
||||
</Row>
|
||||
</div>
|
||||
</QueryHeader>
|
||||
);
|
||||
}
|
||||
|
||||
export default MetricsBuilder;
|
@ -1,24 +0,0 @@
|
||||
import {
|
||||
IMetricsBuilderFormula,
|
||||
IMetricsBuilderQuery,
|
||||
} from 'types/api/dashboard/getAll';
|
||||
|
||||
export interface IQueryBuilderQueryHandleChange {
|
||||
queryIndex: number | string;
|
||||
aggregateFunction?: IMetricsBuilderQuery['aggregateOperator'];
|
||||
metricName?: IMetricsBuilderQuery['metricName'];
|
||||
tagFilters?: IMetricsBuilderQuery['tagFilters']['items'];
|
||||
groupBy?: IMetricsBuilderQuery['groupBy'];
|
||||
legend?: IMetricsBuilderQuery['legend'];
|
||||
toggleDisable?: boolean;
|
||||
toggleDelete?: boolean;
|
||||
reduceTo?: IMetricsBuilderQuery['reduceTo'];
|
||||
}
|
||||
|
||||
export interface IQueryBuilderFormulaHandleChange {
|
||||
formulaIndex: number | string;
|
||||
expression?: IMetricsBuilderFormula['expression'];
|
||||
toggleDisable?: IMetricsBuilderFormula['disabled'];
|
||||
legend?: IMetricsBuilderFormula['legend'];
|
||||
toggleDelete?: boolean;
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import { Query } from 'types/api/dashboard/getAll';
|
||||
|
||||
import { WIDGET_QUERY_BUILDER_QUERY_KEY_NAME } from '../../constants';
|
||||
|
||||
const QUERY_AND_FORMULA_LIMIT = 10;
|
||||
|
||||
export const canCreateQueryAndFormula = (query: Query): boolean => {
|
||||
const queries = query[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME].queryData;
|
||||
const formulas = query[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME].queryFormulas;
|
||||
|
||||
return queries.length + formulas.length < QUERY_AND_FORMULA_LIMIT;
|
||||
};
|
@ -1,10 +0,0 @@
|
||||
import { EQueryType } from 'types/common/dashboard';
|
||||
|
||||
export const WIDGET_PROMQL_QUERY_KEY_NAME = EQueryType.PROM;
|
||||
|
||||
export const WIDGET_CLICKHOUSE_QUERY_KEY_NAME = EQueryType.CLICKHOUSE;
|
||||
|
||||
export const WIDGET_QUERY_BUILDER_QUERY_KEY_NAME = EQueryType.QUERY_BUILDER;
|
||||
|
||||
type TFormulas = 'formulas';
|
||||
export const WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME: TFormulas = 'formulas';
|
@ -20,10 +20,6 @@ import { EQueryType } from 'types/common/dashboard';
|
||||
import DashboardReducer from 'types/reducer/dashboards';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import {
|
||||
WIDGET_CLICKHOUSE_QUERY_KEY_NAME,
|
||||
WIDGET_PROMQL_QUERY_KEY_NAME,
|
||||
} from './constants';
|
||||
import ClickHouseQueryContainer from './QueryBuilder/clickHouse';
|
||||
import PromQLQueryContainer from './QueryBuilder/promQL';
|
||||
import { IHandleUpdatedQuery } from './types';
|
||||
@ -126,7 +122,7 @@ function QuerySection({ updateQuery, selectedGraph }: QueryProps): JSX.Element {
|
||||
updateQueryData={({ updatedQuery }: IHandleUpdatedQuery): void => {
|
||||
handleLocalQueryUpdate({ updatedQuery });
|
||||
}}
|
||||
clickHouseQueries={localQueryChanges[WIDGET_CLICKHOUSE_QUERY_KEY_NAME]}
|
||||
clickHouseQueries={localQueryChanges[EQueryType.CLICKHOUSE]}
|
||||
/>
|
||||
),
|
||||
},
|
||||
@ -141,7 +137,7 @@ function QuerySection({ updateQuery, selectedGraph }: QueryProps): JSX.Element {
|
||||
updateQueryData={({ updatedQuery }: IHandleUpdatedQuery): void => {
|
||||
handleLocalQueryUpdate({ updatedQuery });
|
||||
}}
|
||||
promQLQueries={localQueryChanges[WIDGET_PROMQL_QUERY_KEY_NAME]}
|
||||
promQLQueries={localQueryChanges[EQueryType.PROM]}
|
||||
/>
|
||||
),
|
||||
},
|
||||
|
@ -1,12 +1,6 @@
|
||||
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
||||
import {
|
||||
IClickHouseQuery,
|
||||
IMetricsBuilderFormula,
|
||||
IMetricsBuilderQuery,
|
||||
IPromQLQuery,
|
||||
IQueryBuilderTagFilters,
|
||||
} from 'types/api/dashboard/getAll';
|
||||
import { EAggregateOperator, EQueryType } from 'types/common/dashboard';
|
||||
import { IClickHouseQuery, IPromQLQuery } from 'types/api/dashboard/getAll';
|
||||
import { EQueryType } from 'types/common/dashboard';
|
||||
import { QueryDataResourse } from 'types/common/queryBuilderMappers.types';
|
||||
|
||||
export interface ICompositeMetricQuery {
|
||||
@ -32,44 +26,3 @@ export interface IPromQuery extends IPromQLQuery {
|
||||
export interface IPromQueries {
|
||||
[key: string]: IPromQuery;
|
||||
}
|
||||
export interface IBuilderQueries {
|
||||
[key: string]: IBuilderQuery;
|
||||
}
|
||||
|
||||
// IBuilderQuery combines IMetricQuery and IFormulaQuery
|
||||
// for api calls
|
||||
export interface IBuilderQuery
|
||||
extends Omit<
|
||||
IMetricQuery,
|
||||
'aggregateOperator' | 'legend' | 'metricName' | 'tagFilters'
|
||||
> {
|
||||
aggregateOperator: EAggregateOperator | undefined;
|
||||
disabled: boolean;
|
||||
name: string;
|
||||
legend?: string;
|
||||
metricName: string | null;
|
||||
groupBy?: string[];
|
||||
expression?: string;
|
||||
tagFilters?: IQueryBuilderTagFilters;
|
||||
toggleDisable?: boolean;
|
||||
toggleDelete?: boolean;
|
||||
}
|
||||
|
||||
export interface IFormulaQueries {
|
||||
[key: string]: IFormulaQuery;
|
||||
}
|
||||
|
||||
export interface IFormulaQuery extends IMetricsBuilderFormula {
|
||||
formulaOnly: boolean;
|
||||
queryName: string;
|
||||
}
|
||||
|
||||
export interface IMetricQueries {
|
||||
[key: string]: IMetricQuery;
|
||||
}
|
||||
|
||||
export interface IMetricQuery extends IMetricsBuilderQuery {
|
||||
formulaOnly: boolean;
|
||||
expression?: string;
|
||||
queryName: string;
|
||||
}
|
||||
|
@ -1,11 +1,7 @@
|
||||
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
||||
import { timePreferenceType } from 'container/NewWidget/RightContainer/timeItems';
|
||||
import { Layout } from 'react-grid-layout';
|
||||
import {
|
||||
EAggregateOperator,
|
||||
EQueryType,
|
||||
EReduceOperator,
|
||||
} from 'types/common/dashboard';
|
||||
import { EQueryType } from 'types/common/dashboard';
|
||||
import { QueryBuilderData } from 'types/common/queryBuilder';
|
||||
|
||||
import { QueryData } from '../widgets/getQuery';
|
||||
@ -97,28 +93,6 @@ export interface Query {
|
||||
clickhouse_sql: IClickHouseQuery[];
|
||||
}
|
||||
|
||||
export interface IMetricsBuilderFormula {
|
||||
expression: string;
|
||||
disabled: boolean;
|
||||
name: string;
|
||||
legend: string;
|
||||
}
|
||||
export interface IMetricsBuilderQuery {
|
||||
aggregateOperator: EAggregateOperator;
|
||||
disabled: boolean;
|
||||
name: string;
|
||||
legend: string;
|
||||
metricName: string | null;
|
||||
groupBy?: string[];
|
||||
tagFilters: IQueryBuilderTagFilters;
|
||||
reduceTo?: EReduceOperator;
|
||||
}
|
||||
|
||||
export interface IQueryBuilderTagFilters {
|
||||
op: string;
|
||||
items: IQueryBuilderTagFilterItems[] | [];
|
||||
}
|
||||
|
||||
export interface IClickHouseQuery {
|
||||
name: string;
|
||||
rawQuery: string;
|
||||
|
@ -3,47 +3,3 @@ export enum EQueryType {
|
||||
CLICKHOUSE = 'clickhouse_sql',
|
||||
PROM = 'promql',
|
||||
}
|
||||
|
||||
export enum EAggregateOperator {
|
||||
NOOP = 1,
|
||||
COUNT = 2,
|
||||
COUNT_DISTINCT = 3,
|
||||
SUM = 4,
|
||||
AVG = 5,
|
||||
MAX = 6,
|
||||
MIN = 7,
|
||||
P05 = 8,
|
||||
P10 = 9,
|
||||
P20 = 10,
|
||||
P25 = 11,
|
||||
P50 = 12,
|
||||
P75 = 13,
|
||||
P90 = 14,
|
||||
P95 = 15,
|
||||
P99 = 16,
|
||||
RATE = 17,
|
||||
SUM_RATE = 18,
|
||||
// leaving gap for possible future {X}_RATE
|
||||
RATE_SUM = 22,
|
||||
RATE_AVG = 23,
|
||||
RATE_MAX = 24,
|
||||
RATE_MIN = 25,
|
||||
HIST_QUANTILE_50 = 26,
|
||||
HIST_QUANTILE_75 = 27,
|
||||
HIST_QUANTILE_90 = 28,
|
||||
HIST_QUANTILE_95 = 29,
|
||||
HIST_QUANTILE_99 = 30,
|
||||
}
|
||||
|
||||
export enum EPanelType {
|
||||
GRAPH = 'graph',
|
||||
VALUE = 'value',
|
||||
}
|
||||
|
||||
export enum EReduceOperator {
|
||||
'Latest of values in timeframe' = 1, // LAST
|
||||
'Sum of values in timeframe', // SUM
|
||||
'Average of values in timeframe', // AVG
|
||||
'Max of values in timeframe', // MAX
|
||||
'Min of values in timeframe', // MIN
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user