mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-15 20:15:53 +08:00
feat: add share url (#2778)
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
This commit is contained in:
parent
7fd27ec09d
commit
ad5a9dcd6a
@ -8,6 +8,7 @@ import {
|
|||||||
IBuilderQuery,
|
IBuilderQuery,
|
||||||
IClickHouseQuery,
|
IClickHouseQuery,
|
||||||
IPromQLQuery,
|
IPromQLQuery,
|
||||||
|
Query,
|
||||||
QueryState,
|
QueryState,
|
||||||
} from 'types/api/queryBuilder/queryBuilderData';
|
} from 'types/api/queryBuilder/queryBuilderData';
|
||||||
import { EQueryType } from 'types/common/dashboard';
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
@ -158,6 +159,11 @@ export const initialQuery: QueryState = {
|
|||||||
promql: [initialQueryPromQLData],
|
promql: [initialQueryPromQLData],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const initialQueryWithType: Query = {
|
||||||
|
...initialQuery,
|
||||||
|
queryType: EQueryType.QUERY_BUILDER,
|
||||||
|
};
|
||||||
|
|
||||||
export const operatorsByTypes: Record<LocalDataType, string[]> = {
|
export const operatorsByTypes: Record<LocalDataType, string[]> = {
|
||||||
string: Object.values(StringOperators),
|
string: Object.values(StringOperators),
|
||||||
number: Object.values(NumberOperators),
|
number: Object.values(NumberOperators),
|
||||||
|
1
frontend/src/constants/queryBuilderQueryNames.ts
Normal file
1
frontend/src/constants/queryBuilderQueryNames.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const COMPOSITE_QUERY = 'compositeQuery';
|
@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
initialQueryBuilderFormValues,
|
initialQueryBuilderFormValues,
|
||||||
|
initialQueryPromQLData,
|
||||||
PANEL_TYPES,
|
PANEL_TYPES,
|
||||||
} from 'constants/queryBuilder';
|
} from 'constants/queryBuilder';
|
||||||
import { AlertTypes } from 'types/api/alerts/alertTypes';
|
import { AlertTypes } from 'types/api/alerts/alertTypes';
|
||||||
@ -31,11 +32,9 @@ export const alertDefaults: AlertDef = {
|
|||||||
condition: {
|
condition: {
|
||||||
compositeQuery: {
|
compositeQuery: {
|
||||||
builderQueries: {
|
builderQueries: {
|
||||||
A: {
|
A: initialQueryBuilderFormValues,
|
||||||
...initialQueryBuilderFormValues,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
promQueries: {},
|
promQueries: { A: initialQueryPromQLData },
|
||||||
chQueries: {
|
chQueries: {
|
||||||
A: {
|
A: {
|
||||||
name: 'A',
|
name: 'A',
|
||||||
@ -69,7 +68,7 @@ export const logAlertDefaults: AlertDef = {
|
|||||||
dataSource: DataSource.LOGS,
|
dataSource: DataSource.LOGS,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
promQueries: {},
|
promQueries: { A: initialQueryPromQLData },
|
||||||
chQueries: {
|
chQueries: {
|
||||||
A: {
|
A: {
|
||||||
name: 'A',
|
name: 'A',
|
||||||
@ -104,7 +103,7 @@ export const traceAlertDefaults: AlertDef = {
|
|||||||
dataSource: DataSource.TRACES,
|
dataSource: DataSource.TRACES,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
promQueries: {},
|
promQueries: { A: initialQueryPromQLData },
|
||||||
chQueries: {
|
chQueries: {
|
||||||
A: {
|
A: {
|
||||||
name: 'A',
|
name: 'A',
|
||||||
@ -139,7 +138,7 @@ export const exceptionAlertDefaults: AlertDef = {
|
|||||||
dataSource: DataSource.TRACES,
|
dataSource: DataSource.TRACES,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
promQueries: {},
|
promQueries: { A: initialQueryPromQLData },
|
||||||
chQueries: {
|
chQueries: {
|
||||||
A: {
|
A: {
|
||||||
name: 'A',
|
name: 'A',
|
||||||
@ -162,3 +161,10 @@ export const exceptionAlertDefaults: AlertDef = {
|
|||||||
annotations: defaultAnnotations,
|
annotations: defaultAnnotations,
|
||||||
evalWindow: defaultEvalWindow,
|
evalWindow: defaultEvalWindow,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ALERTS_VALUES_MAP: Record<AlertTypes, AlertDef> = {
|
||||||
|
[AlertTypes.METRICS_BASED_ALERT]: alertDefaults,
|
||||||
|
[AlertTypes.LOGS_BASED_ALERT]: logAlertDefaults,
|
||||||
|
[AlertTypes.TRACES_BASED_ALERT]: traceAlertDefaults,
|
||||||
|
[AlertTypes.EXCEPTIONS_BASED_ALERT]: exceptionAlertDefaults,
|
||||||
|
};
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
import { Form, Row } from 'antd';
|
import { Form, Row } from 'antd';
|
||||||
|
import { COMPOSITE_QUERY } from 'constants/queryBuilderQueryNames';
|
||||||
import FormAlertRules from 'container/FormAlertRules';
|
import FormAlertRules from 'container/FormAlertRules';
|
||||||
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
|
import { mapQueryDataFromApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataFromApi';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { AlertTypes } from 'types/api/alerts/alertTypes';
|
import { AlertTypes } from 'types/api/alerts/alertTypes';
|
||||||
|
import { AlertDef } from 'types/api/alerts/def';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
alertDefaults,
|
alertDefaults,
|
||||||
|
ALERTS_VALUES_MAP,
|
||||||
exceptionAlertDefaults,
|
exceptionAlertDefaults,
|
||||||
logAlertDefaults,
|
logAlertDefaults,
|
||||||
traceAlertDefaults,
|
traceAlertDefaults,
|
||||||
@ -12,13 +18,18 @@ import {
|
|||||||
import SelectAlertType from './SelectAlertType';
|
import SelectAlertType from './SelectAlertType';
|
||||||
|
|
||||||
function CreateRules(): JSX.Element {
|
function CreateRules(): JSX.Element {
|
||||||
const [initValues, setInitValues] = useState(alertDefaults);
|
const [initValues, setInitValues] = useState<AlertDef>(alertDefaults);
|
||||||
const [step, setStep] = useState(0);
|
|
||||||
const [alertType, setAlertType] = useState<AlertTypes>(
|
const [alertType, setAlertType] = useState<AlertTypes>(
|
||||||
AlertTypes.METRICS_BASED_ALERT,
|
AlertTypes.METRICS_BASED_ALERT,
|
||||||
);
|
);
|
||||||
const [formInstance] = Form.useForm();
|
const [formInstance] = Form.useForm();
|
||||||
|
|
||||||
|
const urlQuery = useUrlQuery();
|
||||||
|
|
||||||
|
const compositeQuery = urlQuery.get(COMPOSITE_QUERY);
|
||||||
|
|
||||||
|
const { redirectWithQueryBuilderData } = useQueryBuilder();
|
||||||
|
|
||||||
const onSelectType = (typ: AlertTypes): void => {
|
const onSelectType = (typ: AlertTypes): void => {
|
||||||
setAlertType(typ);
|
setAlertType(typ);
|
||||||
switch (typ) {
|
switch (typ) {
|
||||||
@ -34,16 +45,22 @@ function CreateRules(): JSX.Element {
|
|||||||
default:
|
default:
|
||||||
setInitValues(alertDefaults);
|
setInitValues(alertDefaults);
|
||||||
}
|
}
|
||||||
setStep(1);
|
|
||||||
|
const value = ALERTS_VALUES_MAP[typ].condition.compositeQuery;
|
||||||
|
|
||||||
|
const compositeQuery = mapQueryDataFromApi(value);
|
||||||
|
|
||||||
|
redirectWithQueryBuilderData(compositeQuery);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (step === 0) {
|
if (!compositeQuery) {
|
||||||
return (
|
return (
|
||||||
<Row wrap={false}>
|
<Row wrap={false}>
|
||||||
<SelectAlertType onSelect={onSelectType} />
|
<SelectAlertType onSelect={onSelectType} />
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormAlertRules
|
<FormAlertRules
|
||||||
alertType={alertType}
|
alertType={alertType}
|
||||||
|
@ -7,11 +7,13 @@ import ROUTES from 'constants/routes';
|
|||||||
import QueryTypeTag from 'container/NewWidget/LeftContainer/QueryTypeTag';
|
import QueryTypeTag from 'container/NewWidget/LeftContainer/QueryTypeTag';
|
||||||
import PlotTag from 'container/NewWidget/LeftContainer/WidgetGraph/PlotTag';
|
import PlotTag from 'container/NewWidget/LeftContainer/WidgetGraph/PlotTag';
|
||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
|
import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl';
|
||||||
import { MESSAGE, useIsFeatureDisabled } from 'hooks/useFeatureFlag';
|
import { MESSAGE, useIsFeatureDisabled } from 'hooks/useFeatureFlag';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
|
import { mapQueryDataFromApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataFromApi';
|
||||||
import { mapQueryDataToApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataToApi';
|
import { mapQueryDataToApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataToApi';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useQueryClient } from 'react-query';
|
import { useQueryClient } from 'react-query';
|
||||||
import { AlertTypes } from 'types/api/alerts/alertTypes';
|
import { AlertTypes } from 'types/api/alerts/alertTypes';
|
||||||
@ -35,7 +37,7 @@ import {
|
|||||||
StyledLeftContainer,
|
StyledLeftContainer,
|
||||||
} from './styles';
|
} from './styles';
|
||||||
import UserGuide from './UserGuide';
|
import UserGuide from './UserGuide';
|
||||||
import { prepareStagedQuery, toChartInterval } from './utils';
|
import { toChartInterval } from './utils';
|
||||||
|
|
||||||
function FormAlertRules({
|
function FormAlertRules({
|
||||||
alertType,
|
alertType,
|
||||||
@ -46,12 +48,7 @@ function FormAlertRules({
|
|||||||
// init namespace for translations
|
// init namespace for translations
|
||||||
const { t } = useTranslation('alerts');
|
const { t } = useTranslation('alerts');
|
||||||
|
|
||||||
const {
|
const { currentQuery, redirectWithQueryBuilderData } = useQueryBuilder();
|
||||||
currentQuery,
|
|
||||||
queryType,
|
|
||||||
handleSetQueryType,
|
|
||||||
initQueryBuilderData,
|
|
||||||
} = useQueryBuilder();
|
|
||||||
|
|
||||||
// use query client
|
// use query client
|
||||||
const ruleCache = useQueryClient();
|
const ruleCache = useQueryClient();
|
||||||
@ -62,7 +59,11 @@ function FormAlertRules({
|
|||||||
const [alertDef, setAlertDef] = useState<AlertDef>(initialValue);
|
const [alertDef, setAlertDef] = useState<AlertDef>(initialValue);
|
||||||
|
|
||||||
// initQuery contains initial query when component was mounted
|
// initQuery contains initial query when component was mounted
|
||||||
const initQuery = initialValue.condition.compositeQuery;
|
const initQuery = useMemo(() => initialValue.condition.compositeQuery, [
|
||||||
|
initialValue,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const sq = useMemo(() => mapQueryDataFromApi(initQuery), [initQuery]);
|
||||||
|
|
||||||
// manualStagedQuery requires manual staging of query
|
// manualStagedQuery requires manual staging of query
|
||||||
// when user clicks run query button. Useful for clickhouse tab where
|
// when user clicks run query button. Useful for clickhouse tab where
|
||||||
@ -73,26 +74,26 @@ function FormAlertRules({
|
|||||||
// other queries based on server data.
|
// other queries based on server data.
|
||||||
// useful when fetching of initial values (from api)
|
// useful when fetching of initial values (from api)
|
||||||
// is delayed
|
// is delayed
|
||||||
|
|
||||||
|
const { compositeQuery } = useShareBuilderUrl({ defaultValue: sq });
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const type = initQuery.queryType;
|
if (compositeQuery && !manualStagedQuery) {
|
||||||
|
setManualStagedQuery(compositeQuery);
|
||||||
// prepare staged query
|
}
|
||||||
const sq = prepareStagedQuery(
|
|
||||||
type,
|
|
||||||
initQuery?.builderQueries,
|
|
||||||
initQuery?.promQueries,
|
|
||||||
initQuery?.chQueries,
|
|
||||||
);
|
|
||||||
|
|
||||||
initQueryBuilderData(sq, type);
|
|
||||||
|
|
||||||
setManualStagedQuery(sq);
|
|
||||||
|
|
||||||
setAlertDef(initialValue);
|
setAlertDef(initialValue);
|
||||||
}, [initialValue, initQueryBuilderData, initQuery]);
|
}, [
|
||||||
|
initialValue,
|
||||||
|
initQuery,
|
||||||
|
redirectWithQueryBuilderData,
|
||||||
|
currentQuery,
|
||||||
|
manualStagedQuery,
|
||||||
|
compositeQuery,
|
||||||
|
]);
|
||||||
|
|
||||||
const onRunQuery = (): void => {
|
const onRunQuery = (): void => {
|
||||||
setManualStagedQuery({ ...currentQuery, queryType });
|
setManualStagedQuery(currentQuery);
|
||||||
|
redirectWithQueryBuilderData(currentQuery);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCancelHandler = useCallback(() => {
|
const onCancelHandler = useCallback(() => {
|
||||||
@ -102,7 +103,6 @@ function FormAlertRules({
|
|||||||
// onQueryCategoryChange handles changes to query category
|
// onQueryCategoryChange handles changes to query category
|
||||||
// in state as well as sets additional defaults
|
// in state as well as sets additional defaults
|
||||||
const onQueryCategoryChange = (val: EQueryType): void => {
|
const onQueryCategoryChange = (val: EQueryType): void => {
|
||||||
handleSetQueryType(val);
|
|
||||||
if (val === EQueryType.PROM) {
|
if (val === EQueryType.PROM) {
|
||||||
setAlertDef({
|
setAlertDef({
|
||||||
...alertDef,
|
...alertDef,
|
||||||
@ -113,14 +113,17 @@ function FormAlertRules({
|
|||||||
evalWindow: defaultEvalWindow,
|
evalWindow: defaultEvalWindow,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
const query: Query = { ...currentQuery, queryType: val };
|
||||||
|
|
||||||
setManualStagedQuery({ ...currentQuery, queryType: val });
|
setManualStagedQuery(query);
|
||||||
|
|
||||||
|
redirectWithQueryBuilderData(query);
|
||||||
};
|
};
|
||||||
const { notifications } = useNotifications();
|
const { notifications } = useNotifications();
|
||||||
|
|
||||||
const validatePromParams = useCallback((): boolean => {
|
const validatePromParams = useCallback((): boolean => {
|
||||||
let retval = true;
|
let retval = true;
|
||||||
if (queryType !== EQueryType.PROM) return retval;
|
if (currentQuery.queryType !== EQueryType.PROM) return retval;
|
||||||
|
|
||||||
if (!currentQuery.promql || currentQuery.promql.length === 0) {
|
if (!currentQuery.promql || currentQuery.promql.length === 0) {
|
||||||
notifications.error({
|
notifications.error({
|
||||||
@ -141,11 +144,11 @@ function FormAlertRules({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}, [t, currentQuery, queryType, notifications]);
|
}, [t, currentQuery, notifications]);
|
||||||
|
|
||||||
const validateChQueryParams = useCallback((): boolean => {
|
const validateChQueryParams = useCallback((): boolean => {
|
||||||
let retval = true;
|
let retval = true;
|
||||||
if (queryType !== EQueryType.CLICKHOUSE) return retval;
|
if (currentQuery.queryType !== EQueryType.CLICKHOUSE) return retval;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!currentQuery.clickhouse_sql ||
|
!currentQuery.clickhouse_sql ||
|
||||||
@ -169,10 +172,10 @@ function FormAlertRules({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}, [t, queryType, currentQuery, notifications]);
|
}, [t, currentQuery, notifications]);
|
||||||
|
|
||||||
const validateQBParams = useCallback((): boolean => {
|
const validateQBParams = useCallback((): boolean => {
|
||||||
if (queryType !== EQueryType.QUERY_BUILDER) return true;
|
if (currentQuery.queryType !== EQueryType.QUERY_BUILDER) return true;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!currentQuery.builder.queryData ||
|
!currentQuery.builder.queryData ||
|
||||||
@ -194,7 +197,7 @@ function FormAlertRules({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}, [t, alertDef, queryType, currentQuery, notifications]);
|
}, [t, alertDef, currentQuery, notifications]);
|
||||||
|
|
||||||
const isFormValid = useCallback((): boolean => {
|
const isFormValid = useCallback((): boolean => {
|
||||||
if (!alertDef.alert || alertDef.alert === '') {
|
if (!alertDef.alert || alertDef.alert === '') {
|
||||||
@ -228,7 +231,10 @@ function FormAlertRules({
|
|||||||
...alertDef,
|
...alertDef,
|
||||||
alertType,
|
alertType,
|
||||||
source: window?.location.toString(),
|
source: window?.location.toString(),
|
||||||
ruleType: queryType === EQueryType.PROM ? 'promql_rule' : 'threshold_rule',
|
ruleType:
|
||||||
|
currentQuery.queryType === EQueryType.PROM
|
||||||
|
? 'promql_rule'
|
||||||
|
: 'threshold_rule',
|
||||||
condition: {
|
condition: {
|
||||||
...alertDef.condition,
|
...alertDef.condition,
|
||||||
compositeQuery: {
|
compositeQuery: {
|
||||||
@ -239,7 +245,7 @@ function FormAlertRules({
|
|||||||
},
|
},
|
||||||
promQueries: mapQueryDataToApi(currentQuery.promql, 'name').data,
|
promQueries: mapQueryDataToApi(currentQuery.promql, 'name').data,
|
||||||
chQueries: mapQueryDataToApi(currentQuery.clickhouse_sql, 'name').data,
|
chQueries: mapQueryDataToApi(currentQuery.clickhouse_sql, 'name').data,
|
||||||
queryType,
|
queryType: currentQuery.queryType,
|
||||||
panelType: initQuery.panelType,
|
panelType: initQuery.panelType,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -248,7 +254,6 @@ function FormAlertRules({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const memoizedPreparePostData = useCallback(preparePostData, [
|
const memoizedPreparePostData = useCallback(preparePostData, [
|
||||||
queryType,
|
|
||||||
currentQuery,
|
currentQuery,
|
||||||
alertDef,
|
alertDef,
|
||||||
alertType,
|
alertType,
|
||||||
@ -313,7 +318,8 @@ function FormAlertRules({
|
|||||||
const content = (
|
const content = (
|
||||||
<Typography.Text>
|
<Typography.Text>
|
||||||
{' '}
|
{' '}
|
||||||
{t('confirm_save_content_part1')} <QueryTypeTag queryType={queryType} />{' '}
|
{t('confirm_save_content_part1')}{' '}
|
||||||
|
<QueryTypeTag queryType={currentQuery.queryType} />{' '}
|
||||||
{t('confirm_save_content_part2')}
|
{t('confirm_save_content_part2')}
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
);
|
);
|
||||||
@ -326,7 +332,7 @@ function FormAlertRules({
|
|||||||
saveRule();
|
saveRule();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}, [t, saveRule, queryType]);
|
}, [t, saveRule, currentQuery]);
|
||||||
|
|
||||||
const onTestRuleHandler = useCallback(async () => {
|
const onTestRuleHandler = useCallback(async () => {
|
||||||
if (!isFormValid()) {
|
if (!isFormValid()) {
|
||||||
@ -372,7 +378,7 @@ function FormAlertRules({
|
|||||||
|
|
||||||
const renderQBChartPreview = (): JSX.Element => (
|
const renderQBChartPreview = (): JSX.Element => (
|
||||||
<ChartPreview
|
<ChartPreview
|
||||||
headline={<PlotTag queryType={queryType} />}
|
headline={<PlotTag queryType={currentQuery.queryType} />}
|
||||||
name=""
|
name=""
|
||||||
threshold={alertDef.condition?.target}
|
threshold={alertDef.condition?.target}
|
||||||
query={manualStagedQuery}
|
query={manualStagedQuery}
|
||||||
@ -382,7 +388,7 @@ function FormAlertRules({
|
|||||||
|
|
||||||
const renderPromChartPreview = (): JSX.Element => (
|
const renderPromChartPreview = (): JSX.Element => (
|
||||||
<ChartPreview
|
<ChartPreview
|
||||||
headline={<PlotTag queryType={queryType} />}
|
headline={<PlotTag queryType={currentQuery.queryType} />}
|
||||||
name="Chart Preview"
|
name="Chart Preview"
|
||||||
threshold={alertDef.condition?.target}
|
threshold={alertDef.condition?.target}
|
||||||
query={manualStagedQuery}
|
query={manualStagedQuery}
|
||||||
@ -391,7 +397,7 @@ function FormAlertRules({
|
|||||||
|
|
||||||
const renderChQueryChartPreview = (): JSX.Element => (
|
const renderChQueryChartPreview = (): JSX.Element => (
|
||||||
<ChartPreview
|
<ChartPreview
|
||||||
headline={<PlotTag queryType={queryType} />}
|
headline={<PlotTag queryType={currentQuery.queryType} />}
|
||||||
name="Chart Preview"
|
name="Chart Preview"
|
||||||
threshold={alertDef.condition?.target}
|
threshold={alertDef.condition?.target}
|
||||||
query={manualStagedQuery}
|
query={manualStagedQuery}
|
||||||
@ -402,7 +408,9 @@ function FormAlertRules({
|
|||||||
const isNewRule = ruleId === 0;
|
const isNewRule = ruleId === 0;
|
||||||
|
|
||||||
const isAlertAvialableToSave =
|
const isAlertAvialableToSave =
|
||||||
isAlertAvialable && isNewRule && queryType === EQueryType.QUERY_BUILDER;
|
isAlertAvialable &&
|
||||||
|
isNewRule &&
|
||||||
|
currentQuery.queryType === EQueryType.QUERY_BUILDER;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -414,18 +422,20 @@ function FormAlertRules({
|
|||||||
layout="vertical"
|
layout="vertical"
|
||||||
form={formInstance}
|
form={formInstance}
|
||||||
>
|
>
|
||||||
{queryType === EQueryType.QUERY_BUILDER && renderQBChartPreview()}
|
{currentQuery.queryType === EQueryType.QUERY_BUILDER &&
|
||||||
{queryType === EQueryType.PROM && renderPromChartPreview()}
|
renderQBChartPreview()}
|
||||||
{queryType === EQueryType.CLICKHOUSE && renderChQueryChartPreview()}
|
{currentQuery.queryType === EQueryType.PROM && renderPromChartPreview()}
|
||||||
|
{currentQuery.queryType === EQueryType.CLICKHOUSE &&
|
||||||
|
renderChQueryChartPreview()}
|
||||||
<QuerySection
|
<QuerySection
|
||||||
queryCategory={queryType}
|
queryCategory={currentQuery.queryType}
|
||||||
setQueryCategory={onQueryCategoryChange}
|
setQueryCategory={onQueryCategoryChange}
|
||||||
alertType={alertType || AlertTypes.METRICS_BASED_ALERT}
|
alertType={alertType || AlertTypes.METRICS_BASED_ALERT}
|
||||||
runQuery={onRunQuery}
|
runQuery={onRunQuery}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<RuleOptions
|
<RuleOptions
|
||||||
queryCategory={queryType}
|
queryCategory={currentQuery.queryType}
|
||||||
alertDef={alertDef}
|
alertDef={alertDef}
|
||||||
setAlertDef={setAlertDef}
|
setAlertDef={setAlertDef}
|
||||||
/>
|
/>
|
||||||
@ -464,7 +474,7 @@ function FormAlertRules({
|
|||||||
</MainFormContainer>
|
</MainFormContainer>
|
||||||
</StyledLeftContainer>
|
</StyledLeftContainer>
|
||||||
<Col flex="1 1 300px">
|
<Col flex="1 1 300px">
|
||||||
<UserGuide queryType={queryType} />
|
<UserGuide queryType={currentQuery.queryType} />
|
||||||
</Col>
|
</Col>
|
||||||
</PanelContainer>
|
</PanelContainer>
|
||||||
</>
|
</>
|
||||||
|
@ -1,43 +1,4 @@
|
|||||||
import { Time } from 'container/TopNav/DateTimeSelection/config';
|
import { Time } from 'container/TopNav/DateTimeSelection/config';
|
||||||
import { mapQueryDataFromApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataFromApi';
|
|
||||||
import {
|
|
||||||
BuilderClickHouseResource,
|
|
||||||
BuilderPromQLResource,
|
|
||||||
BuilderQueryDataResourse,
|
|
||||||
IClickHouseQuery,
|
|
||||||
IPromQLQuery,
|
|
||||||
Query,
|
|
||||||
} from 'types/api/queryBuilder/queryBuilderData';
|
|
||||||
import { EQueryType } from 'types/common/dashboard';
|
|
||||||
|
|
||||||
export const prepareStagedQuery = (
|
|
||||||
t: EQueryType,
|
|
||||||
b: BuilderQueryDataResourse,
|
|
||||||
p: BuilderPromQLResource,
|
|
||||||
c: BuilderClickHouseResource,
|
|
||||||
): Query => {
|
|
||||||
const promList: IPromQLQuery[] = [];
|
|
||||||
const chQueryList: IClickHouseQuery[] = [];
|
|
||||||
|
|
||||||
const builder = mapQueryDataFromApi(b);
|
|
||||||
if (p) {
|
|
||||||
Object.keys(p).forEach((key) => {
|
|
||||||
promList.push({ ...p[key], name: key });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (c) {
|
|
||||||
Object.keys(c).forEach((key) => {
|
|
||||||
chQueryList.push({ ...c[key], name: key, rawQuery: c[key].query });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
queryType: t,
|
|
||||||
promql: promList,
|
|
||||||
builder,
|
|
||||||
clickhouse_sql: chQueryList,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// toChartInterval converts eval window to chart selection time interval
|
// toChartInterval converts eval window to chart selection time interval
|
||||||
export const toChartInterval = (evalWindow: string | undefined): Time => {
|
export const toChartInterval = (evalWindow: string | undefined): Time => {
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
import { Dropdown, MenuProps, Tooltip, Typography } from 'antd';
|
import { Dropdown, MenuProps, Tooltip, Typography } from 'antd';
|
||||||
import { MenuItemType } from 'antd/es/menu/hooks/useItems';
|
import { MenuItemType } from 'antd/es/menu/hooks/useItems';
|
||||||
import Spinner from 'components/Spinner';
|
import Spinner from 'components/Spinner';
|
||||||
|
import { COMPOSITE_QUERY } from 'constants/queryBuilderQueryNames';
|
||||||
import useComponentPermission from 'hooks/useComponentPermission';
|
import useComponentPermission from 'hooks/useComponentPermission';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
@ -58,9 +59,11 @@ function WidgetHeader({
|
|||||||
const onEditHandler = useCallback((): void => {
|
const onEditHandler = useCallback((): void => {
|
||||||
const widgetId = widget.id;
|
const widgetId = widget.id;
|
||||||
history.push(
|
history.push(
|
||||||
`${window.location.pathname}/new?widgetId=${widgetId}&graphType=${widget.panelTypes}`,
|
`${window.location.pathname}/new?widgetId=${widgetId}&graphType=${
|
||||||
|
widget.panelTypes
|
||||||
|
}&${COMPOSITE_QUERY}=${JSON.stringify(widget.query)}`,
|
||||||
);
|
);
|
||||||
}, [widget.id, widget.panelTypes]);
|
}, [widget.id, widget.panelTypes, widget.query]);
|
||||||
|
|
||||||
const keyMethodMapping: {
|
const keyMethodMapping: {
|
||||||
[K in TWidgetOptions]: { key: TWidgetOptions; method: VoidFunction };
|
[K in TWidgetOptions]: { key: TWidgetOptions; method: VoidFunction };
|
||||||
|
@ -4,11 +4,13 @@ import { Typography } from 'antd';
|
|||||||
import { ColumnsType } from 'antd/lib/table';
|
import { ColumnsType } from 'antd/lib/table';
|
||||||
import { ResizeTable } from 'components/ResizeTable';
|
import { ResizeTable } from 'components/ResizeTable';
|
||||||
import TextToolTip from 'components/TextToolTip';
|
import TextToolTip from 'components/TextToolTip';
|
||||||
|
import { COMPOSITE_QUERY } from 'constants/queryBuilderQueryNames';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import useComponentPermission from 'hooks/useComponentPermission';
|
import useComponentPermission from 'hooks/useComponentPermission';
|
||||||
import useInterval from 'hooks/useInterval';
|
import useInterval from 'hooks/useInterval';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
|
import { mapQueryDataFromApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataFromApi';
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { UseQueryResult } from 'react-query';
|
import { UseQueryResult } from 'react-query';
|
||||||
@ -65,11 +67,19 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element {
|
|||||||
.catch(handleError);
|
.catch(handleError);
|
||||||
}, [featureResponse, handleError]);
|
}, [featureResponse, handleError]);
|
||||||
|
|
||||||
const onEditHandler = (id: string): void => {
|
const onEditHandler = (record: GettableAlert): void => {
|
||||||
featureResponse
|
featureResponse
|
||||||
.refetch()
|
.refetch()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
history.push(`${ROUTES.EDIT_ALERTS}?ruleId=${id}`);
|
const compositeQuery = mapQueryDataFromApi(record.condition.compositeQuery);
|
||||||
|
|
||||||
|
history.push(
|
||||||
|
`${
|
||||||
|
ROUTES.EDIT_ALERTS
|
||||||
|
}?ruleId=${record.id.toString()}&${COMPOSITE_QUERY}=${JSON.stringify(
|
||||||
|
compositeQuery,
|
||||||
|
)}`,
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.catch(handleError);
|
.catch(handleError);
|
||||||
};
|
};
|
||||||
@ -94,9 +104,7 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element {
|
|||||||
(a.alert ? a.alert.charCodeAt(0) : 1000) -
|
(a.alert ? a.alert.charCodeAt(0) : 1000) -
|
||||||
(b.alert ? b.alert.charCodeAt(0) : 1000),
|
(b.alert ? b.alert.charCodeAt(0) : 1000),
|
||||||
render: (value, record): JSX.Element => (
|
render: (value, record): JSX.Element => (
|
||||||
<Typography.Link
|
<Typography.Link onClick={(): void => onEditHandler(record)}>
|
||||||
onClick={(): void => onEditHandler(record.id ? record.id.toString() : '')}
|
|
||||||
>
|
|
||||||
{value}
|
{value}
|
||||||
</Typography.Link>
|
</Typography.Link>
|
||||||
),
|
),
|
||||||
@ -154,10 +162,7 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element {
|
|||||||
<>
|
<>
|
||||||
<ToggleAlertState disabled={record.disabled} setData={setData} id={id} />
|
<ToggleAlertState disabled={record.disabled} setData={setData} id={id} />
|
||||||
|
|
||||||
<ColumnButton
|
<ColumnButton onClick={(): void => onEditHandler(record)} type="link">
|
||||||
onClick={(): void => onEditHandler(id.toString())}
|
|
||||||
type="link"
|
|
||||||
>
|
|
||||||
Edit
|
Edit
|
||||||
</ColumnButton>
|
</ColumnButton>
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
/* eslint-disable @typescript-eslint/naming-convention */
|
/* eslint-disable @typescript-eslint/naming-convention */
|
||||||
|
|
||||||
|
import { initialQueryWithType } from 'constants/queryBuilder';
|
||||||
|
import { COMPOSITE_QUERY } from 'constants/queryBuilderQueryNames';
|
||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
@ -43,7 +45,9 @@ function DashboardGraphSlider({ toggleAddWidget }: Props): JSX.Element {
|
|||||||
toggleAddWidget(false);
|
toggleAddWidget(false);
|
||||||
|
|
||||||
history.push(
|
history.push(
|
||||||
`${history.location.pathname}/new?graphType=${name}&widgetId=${emptyLayout.i}`,
|
`${history.location.pathname}/new?graphType=${name}&widgetId=${
|
||||||
|
emptyLayout.i
|
||||||
|
}&${COMPOSITE_QUERY}=${JSON.stringify(initialQueryWithType)}`,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notifications.error({
|
notifications.error({
|
||||||
|
@ -3,9 +3,10 @@ import TextToolTip from 'components/TextToolTip';
|
|||||||
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
||||||
import { QueryBuilder } from 'container/QueryBuilder';
|
import { QueryBuilder } from 'container/QueryBuilder';
|
||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
import { useCallback, useEffect, useMemo } from 'react';
|
import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl';
|
||||||
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { connect, useSelector } from 'react-redux';
|
import { connect, useSelector } from 'react-redux';
|
||||||
import { useLocation } from 'react-router-dom';
|
|
||||||
import { bindActionCreators, Dispatch } from 'redux';
|
import { bindActionCreators, Dispatch } from 'redux';
|
||||||
import { ThunkDispatch } from 'redux-thunk';
|
import { ThunkDispatch } from 'redux-thunk';
|
||||||
import {
|
import {
|
||||||
@ -15,6 +16,7 @@ import {
|
|||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import AppActions from 'types/actions';
|
import AppActions from 'types/actions';
|
||||||
import { Widgets } from 'types/api/dashboard/getAll';
|
import { Widgets } from 'types/api/dashboard/getAll';
|
||||||
|
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
import { EQueryType } from 'types/common/dashboard';
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
import DashboardReducer from 'types/reducer/dashboards';
|
import DashboardReducer from 'types/reducer/dashboards';
|
||||||
|
|
||||||
@ -22,12 +24,10 @@ import ClickHouseQueryContainer from './QueryBuilder/clickHouse';
|
|||||||
import PromQLQueryContainer from './QueryBuilder/promQL';
|
import PromQLQueryContainer from './QueryBuilder/promQL';
|
||||||
|
|
||||||
function QuerySection({ updateQuery, selectedGraph }: QueryProps): JSX.Element {
|
function QuerySection({ updateQuery, selectedGraph }: QueryProps): JSX.Element {
|
||||||
const {
|
const { currentQuery, redirectWithQueryBuilderData } = useQueryBuilder();
|
||||||
currentQuery,
|
const urlQuery = useUrlQuery();
|
||||||
queryType,
|
|
||||||
handleSetQueryType,
|
const [isInit, setIsInit] = useState<boolean>(false);
|
||||||
initQueryBuilderData,
|
|
||||||
} = useQueryBuilder();
|
|
||||||
|
|
||||||
const { dashboards, isLoadingQueryResult } = useSelector<
|
const { dashboards, isLoadingQueryResult } = useSelector<
|
||||||
AppState,
|
AppState,
|
||||||
@ -35,11 +35,8 @@ function QuerySection({ updateQuery, selectedGraph }: QueryProps): JSX.Element {
|
|||||||
>((state) => state.dashboards);
|
>((state) => state.dashboards);
|
||||||
|
|
||||||
const [selectedDashboards] = dashboards;
|
const [selectedDashboards] = dashboards;
|
||||||
const { search } = useLocation();
|
|
||||||
const { widgets } = selectedDashboards.data;
|
const { widgets } = selectedDashboards.data;
|
||||||
|
|
||||||
const urlQuery = useMemo(() => new URLSearchParams(search), [search]);
|
|
||||||
|
|
||||||
const getWidget = useCallback(() => {
|
const getWidget = useCallback(() => {
|
||||||
const widgetId = urlQuery.get('widgetId');
|
const widgetId = urlQuery.get('widgetId');
|
||||||
return widgets?.find((e) => e.id === widgetId);
|
return widgets?.find((e) => e.id === widgetId);
|
||||||
@ -47,32 +44,43 @@ function QuerySection({ updateQuery, selectedGraph }: QueryProps): JSX.Element {
|
|||||||
|
|
||||||
const selectedWidget = getWidget() as Widgets;
|
const selectedWidget = getWidget() as Widgets;
|
||||||
|
|
||||||
const { query } = selectedWidget || {};
|
const { query } = selectedWidget;
|
||||||
|
|
||||||
|
const { compositeQuery } = useShareBuilderUrl({ defaultValue: query });
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initQueryBuilderData(query, selectedWidget.query.queryType);
|
if (!isInit && compositeQuery) {
|
||||||
}, [query, initQueryBuilderData, selectedWidget]);
|
setIsInit(true);
|
||||||
|
updateQuery({
|
||||||
|
updatedQuery: compositeQuery,
|
||||||
|
widgetId: urlQuery.get('widgetId') || '',
|
||||||
|
yAxisUnit: selectedWidget.yAxisUnit,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [isInit, compositeQuery, selectedWidget, urlQuery, updateQuery]);
|
||||||
|
|
||||||
const handleStageQuery = (): void => {
|
const handleStageQuery = useCallback(
|
||||||
updateQuery({
|
(updatedQuery: Query): void => {
|
||||||
updatedQuery: {
|
updateQuery({
|
||||||
...currentQuery,
|
updatedQuery,
|
||||||
queryType,
|
widgetId: urlQuery.get('widgetId') || '',
|
||||||
},
|
yAxisUnit: selectedWidget.yAxisUnit,
|
||||||
widgetId: urlQuery.get('widgetId') || '',
|
});
|
||||||
yAxisUnit: selectedWidget.yAxisUnit,
|
|
||||||
});
|
redirectWithQueryBuilderData(updatedQuery);
|
||||||
};
|
},
|
||||||
|
|
||||||
|
[urlQuery, selectedWidget, updateQuery, redirectWithQueryBuilderData],
|
||||||
|
);
|
||||||
|
|
||||||
const handleQueryCategoryChange = (qCategory: string): void => {
|
const handleQueryCategoryChange = (qCategory: string): void => {
|
||||||
const currentQueryType = qCategory as EQueryType;
|
const currentQueryType = qCategory as EQueryType;
|
||||||
|
|
||||||
handleSetQueryType(currentQueryType);
|
handleStageQuery({ ...currentQuery, queryType: currentQueryType });
|
||||||
updateQuery({
|
};
|
||||||
updatedQuery: { ...currentQuery, queryType: currentQueryType },
|
|
||||||
widgetId: urlQuery.get('widgetId') || '',
|
const handleRunQuery = (): void => {
|
||||||
yAxisUnit: selectedWidget.yAxisUnit,
|
handleStageQuery(currentQuery);
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const items = [
|
const items = [
|
||||||
@ -100,8 +108,8 @@ function QuerySection({ updateQuery, selectedGraph }: QueryProps): JSX.Element {
|
|||||||
<Tabs
|
<Tabs
|
||||||
type="card"
|
type="card"
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
defaultActiveKey={queryType}
|
defaultActiveKey={currentQuery.queryType}
|
||||||
activeKey={queryType}
|
activeKey={currentQuery.queryType}
|
||||||
onChange={handleQueryCategoryChange}
|
onChange={handleQueryCategoryChange}
|
||||||
tabBarExtraContent={
|
tabBarExtraContent={
|
||||||
<span style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
|
<span style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
|
||||||
@ -109,7 +117,7 @@ function QuerySection({ updateQuery, selectedGraph }: QueryProps): JSX.Element {
|
|||||||
<Button
|
<Button
|
||||||
loading={isLoadingQueryResult}
|
loading={isLoadingQueryResult}
|
||||||
type="primary"
|
type="primary"
|
||||||
onClick={handleStageQuery}
|
onClick={handleRunQuery}
|
||||||
>
|
>
|
||||||
Stage & Run Query
|
Stage & Run Query
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import { LockFilled } from '@ant-design/icons';
|
import { LockFilled } from '@ant-design/icons';
|
||||||
import { Button, Modal, Tooltip, Typography } from 'antd';
|
import { Button, Modal, Tooltip, Typography } from 'antd';
|
||||||
import { FeatureKeys } from 'constants/features';
|
import { FeatureKeys } from 'constants/features';
|
||||||
|
import { COMPOSITE_QUERY } from 'constants/queryBuilderQueryNames';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
||||||
import { ITEMS } from 'container/NewDashboard/ComponentsSlider/menuItems';
|
import { ITEMS } from 'container/NewDashboard/ComponentsSlider/menuItems';
|
||||||
import { MESSAGE, useIsFeatureDisabled } from 'hooks/useFeatureFlag';
|
import { MESSAGE, useIsFeatureDisabled } from 'hooks/useFeatureFlag';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariables';
|
import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariables';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
import { DashboardWidgetPageParams } from 'pages/DashboardWidget';
|
import { DashboardWidgetPageParams } from 'pages/DashboardWidget';
|
||||||
@ -47,6 +49,7 @@ function NewWidget({
|
|||||||
saveSettingOfPanel,
|
saveSettingOfPanel,
|
||||||
getQueryResults,
|
getQueryResults,
|
||||||
}: Props): JSX.Element {
|
}: Props): JSX.Element {
|
||||||
|
const urlQuery = useUrlQuery();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { dashboards } = useSelector<AppState, DashboardReducer>(
|
const { dashboards } = useSelector<AppState, DashboardReducer>(
|
||||||
(state) => state.dashboards,
|
(state) => state.dashboards,
|
||||||
@ -159,9 +162,10 @@ function NewWidget({
|
|||||||
}, [dashboardId, dispatch]);
|
}, [dashboardId, dispatch]);
|
||||||
|
|
||||||
const getQueryResult = useCallback(() => {
|
const getQueryResult = useCallback(() => {
|
||||||
if (selectedWidget?.id.length !== 0 && selectedWidget?.query) {
|
const compositeQuery = urlQuery.get(COMPOSITE_QUERY);
|
||||||
|
if ((selectedWidget?.id.length !== 0 && compositeQuery) || compositeQuery) {
|
||||||
getQueryResults({
|
getQueryResults({
|
||||||
query: selectedWidget?.query,
|
query: JSON.parse(compositeQuery),
|
||||||
selectedTime: selectedTime.enum,
|
selectedTime: selectedTime.enum,
|
||||||
widgetId: selectedWidget?.id || '',
|
widgetId: selectedWidget?.id || '',
|
||||||
graphType,
|
graphType,
|
||||||
@ -170,12 +174,12 @@ function NewWidget({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
selectedWidget?.query,
|
|
||||||
selectedTime.enum,
|
selectedTime.enum,
|
||||||
selectedWidget?.id,
|
selectedWidget?.id,
|
||||||
getQueryResults,
|
getQueryResults,
|
||||||
globalSelectedInterval,
|
globalSelectedInterval,
|
||||||
graphType,
|
graphType,
|
||||||
|
urlQuery,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const setGraphHandler = (type: ITEMS): void => {
|
const setGraphHandler = (type: ITEMS): void => {
|
||||||
|
33
frontend/src/hooks/queryBuilder/useShareBuilderUrl.ts
Normal file
33
frontend/src/hooks/queryBuilder/useShareBuilderUrl.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { COMPOSITE_QUERY } from 'constants/queryBuilderQueryNames';
|
||||||
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
|
import { useEffect, useMemo } from 'react';
|
||||||
|
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
|
import { useQueryBuilder } from './useQueryBuilder';
|
||||||
|
|
||||||
|
type UseShareBuilderUrlParams = { defaultValue: Query };
|
||||||
|
type UseShareBuilderUrlReturnType = { compositeQuery: Query | null };
|
||||||
|
|
||||||
|
export const useShareBuilderUrl = ({
|
||||||
|
defaultValue,
|
||||||
|
}: UseShareBuilderUrlParams): UseShareBuilderUrlReturnType => {
|
||||||
|
const { redirectWithQueryBuilderData } = useQueryBuilder();
|
||||||
|
const urlQuery = useUrlQuery();
|
||||||
|
|
||||||
|
const compositeQuery: Query | null = useMemo(() => {
|
||||||
|
const query = urlQuery.get(COMPOSITE_QUERY);
|
||||||
|
if (query) {
|
||||||
|
return JSON.parse(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}, [urlQuery]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!compositeQuery) {
|
||||||
|
redirectWithQueryBuilderData(defaultValue);
|
||||||
|
}
|
||||||
|
}, [defaultValue, urlQuery, redirectWithQueryBuilderData, compositeQuery]);
|
||||||
|
|
||||||
|
return { compositeQuery };
|
||||||
|
};
|
@ -1,27 +1,35 @@
|
|||||||
import { initialQueryBuilderFormValues } from 'constants/queryBuilder';
|
import { initialQuery } from 'constants/queryBuilder';
|
||||||
import { FORMULA_REGEXP } from 'constants/regExp';
|
import { ICompositeMetricQuery } from 'types/api/alerts/compositeQuery';
|
||||||
import {
|
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
BuilderQueryDataResourse,
|
|
||||||
IBuilderFormula,
|
import { transformQueryBuilderDataModel } from '../transformQueryBuilderDataModel';
|
||||||
IBuilderQuery,
|
|
||||||
} from 'types/api/queryBuilder/queryBuilderData';
|
|
||||||
import { QueryBuilderData } from 'types/common/queryBuilder';
|
|
||||||
|
|
||||||
export const mapQueryDataFromApi = (
|
export const mapQueryDataFromApi = (
|
||||||
data: BuilderQueryDataResourse,
|
compositeQuery: ICompositeMetricQuery,
|
||||||
): QueryBuilderData => {
|
): Query => {
|
||||||
const queryData: QueryBuilderData['queryData'] = [];
|
const builder = compositeQuery.builderQueries
|
||||||
const queryFormulas: QueryBuilderData['queryFormulas'] = [];
|
? transformQueryBuilderDataModel(compositeQuery.builderQueries)
|
||||||
|
: initialQuery.builder;
|
||||||
|
|
||||||
Object.entries(data).forEach(([, value]) => {
|
const promql = compositeQuery.promQueries
|
||||||
if (FORMULA_REGEXP.test(value.queryName)) {
|
? Object.keys(compositeQuery.promQueries).map((key) => ({
|
||||||
const formula = value as IBuilderFormula;
|
...compositeQuery.promQueries[key],
|
||||||
queryFormulas.push(formula);
|
name: key,
|
||||||
} else {
|
}))
|
||||||
const query = value as IBuilderQuery;
|
: initialQuery.promql;
|
||||||
queryData.push({ ...initialQueryBuilderFormValues, ...query });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return { queryData, queryFormulas };
|
const clickhouseSql = compositeQuery.chQueries
|
||||||
|
? Object.keys(compositeQuery.chQueries).map((key) => ({
|
||||||
|
...compositeQuery.chQueries[key],
|
||||||
|
name: key,
|
||||||
|
rawQuery: compositeQuery.chQueries[key].query,
|
||||||
|
}))
|
||||||
|
: initialQuery.clickhouse_sql;
|
||||||
|
|
||||||
|
return {
|
||||||
|
builder,
|
||||||
|
promql,
|
||||||
|
clickhouse_sql: clickhouseSql,
|
||||||
|
queryType: compositeQuery.queryType,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
import {
|
||||||
|
initialFormulaBuilderFormValues,
|
||||||
|
initialQueryBuilderFormValues,
|
||||||
|
} from 'constants/queryBuilder';
|
||||||
|
import { FORMULA_REGEXP } from 'constants/regExp';
|
||||||
|
import {
|
||||||
|
BuilderQueryDataResourse,
|
||||||
|
IBuilderFormula,
|
||||||
|
IBuilderQuery,
|
||||||
|
} from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
import { QueryBuilderData } from 'types/common/queryBuilder';
|
||||||
|
|
||||||
|
export const transformQueryBuilderDataModel = (
|
||||||
|
data: BuilderQueryDataResourse,
|
||||||
|
): QueryBuilderData => {
|
||||||
|
const queryData: QueryBuilderData['queryData'] = [];
|
||||||
|
const queryFormulas: QueryBuilderData['queryFormulas'] = [];
|
||||||
|
|
||||||
|
Object.entries(data).forEach(([, value]) => {
|
||||||
|
if (FORMULA_REGEXP.test(value.queryName)) {
|
||||||
|
const formula = value as IBuilderFormula;
|
||||||
|
queryFormulas.push({ ...initialFormulaBuilderFormValues, ...formula });
|
||||||
|
} else {
|
||||||
|
const query = value as IBuilderQuery;
|
||||||
|
queryData.push({ ...initialQueryBuilderFormValues, ...query });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return { queryData, queryFormulas };
|
||||||
|
};
|
28
frontend/src/lib/replaceIncorrectObjectFields.ts
Normal file
28
frontend/src/lib/replaceIncorrectObjectFields.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
export function replaceIncorrectObjectFields<
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
|
TargetValue extends object,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
|
ResultValue extends object
|
||||||
|
>(
|
||||||
|
targetObject: TargetValue,
|
||||||
|
defaultObject: ResultValue,
|
||||||
|
): { isValid: boolean; validData: ResultValue } {
|
||||||
|
const targetObjectKeys = Object.keys(targetObject);
|
||||||
|
const defaultObjectKeys = Object.keys(defaultObject);
|
||||||
|
|
||||||
|
let isValid = true;
|
||||||
|
|
||||||
|
const result: ResultValue = { ...defaultObject };
|
||||||
|
|
||||||
|
defaultObjectKeys.forEach((key) => {
|
||||||
|
if (targetObjectKeys.includes(key)) {
|
||||||
|
result[key as keyof ResultValue] = (targetObject[
|
||||||
|
key as keyof TargetValue
|
||||||
|
] as unknown) as ResultValue[keyof ResultValue];
|
||||||
|
} else {
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return { isValid, validData: result };
|
||||||
|
}
|
@ -1,30 +1,39 @@
|
|||||||
import {
|
import {
|
||||||
alphabet,
|
alphabet,
|
||||||
formulasNames,
|
formulasNames,
|
||||||
|
initialClickHouseData,
|
||||||
initialFormulaBuilderFormValues,
|
initialFormulaBuilderFormValues,
|
||||||
initialQuery,
|
initialQuery,
|
||||||
initialQueryBuilderFormValues,
|
initialQueryBuilderFormValues,
|
||||||
|
initialQueryPromQLData,
|
||||||
|
initialQueryWithType,
|
||||||
initialSingleQueryMap,
|
initialSingleQueryMap,
|
||||||
MAX_FORMULAS,
|
MAX_FORMULAS,
|
||||||
MAX_QUERIES,
|
MAX_QUERIES,
|
||||||
PANEL_TYPES,
|
PANEL_TYPES,
|
||||||
} from 'constants/queryBuilder';
|
} from 'constants/queryBuilder';
|
||||||
|
import { COMPOSITE_QUERY } from 'constants/queryBuilderQueryNames';
|
||||||
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
||||||
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import { createNewBuilderItemName } from 'lib/newQueryBuilder/createNewBuilderItemName';
|
import { createNewBuilderItemName } from 'lib/newQueryBuilder/createNewBuilderItemName';
|
||||||
import { getOperatorsBySourceAndPanelType } from 'lib/newQueryBuilder/getOperatorsBySourceAndPanelType';
|
import { getOperatorsBySourceAndPanelType } from 'lib/newQueryBuilder/getOperatorsBySourceAndPanelType';
|
||||||
|
import { replaceIncorrectObjectFields } from 'lib/replaceIncorrectObjectFields';
|
||||||
import {
|
import {
|
||||||
createContext,
|
createContext,
|
||||||
PropsWithChildren,
|
PropsWithChildren,
|
||||||
useCallback,
|
useCallback,
|
||||||
|
useEffect,
|
||||||
useMemo,
|
useMemo,
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
import { useHistory, useLocation } from 'react-router-dom';
|
||||||
// ** Types
|
// ** Types
|
||||||
import {
|
import {
|
||||||
IBuilderFormula,
|
IBuilderFormula,
|
||||||
IBuilderQuery,
|
IBuilderQuery,
|
||||||
IClickHouseQuery,
|
IClickHouseQuery,
|
||||||
IPromQLQuery,
|
IPromQLQuery,
|
||||||
|
Query,
|
||||||
QueryState,
|
QueryState,
|
||||||
} from 'types/api/queryBuilder/queryBuilderData';
|
} from 'types/api/queryBuilder/queryBuilderData';
|
||||||
import { EQueryType } from 'types/common/dashboard';
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
@ -35,8 +44,7 @@ import {
|
|||||||
} from 'types/common/queryBuilder';
|
} from 'types/common/queryBuilder';
|
||||||
|
|
||||||
export const QueryBuilderContext = createContext<QueryBuilderContextType>({
|
export const QueryBuilderContext = createContext<QueryBuilderContextType>({
|
||||||
currentQuery: initialQuery,
|
currentQuery: initialQueryWithType,
|
||||||
queryType: EQueryType.QUERY_BUILDER,
|
|
||||||
initialDataSource: null,
|
initialDataSource: null,
|
||||||
panelType: PANEL_TYPES.TIME_SERIES,
|
panelType: PANEL_TYPES.TIME_SERIES,
|
||||||
resetQueryBuilderData: () => {},
|
resetQueryBuilderData: () => {},
|
||||||
@ -53,11 +61,16 @@ export const QueryBuilderContext = createContext<QueryBuilderContextType>({
|
|||||||
addNewBuilderQuery: () => {},
|
addNewBuilderQuery: () => {},
|
||||||
addNewFormula: () => {},
|
addNewFormula: () => {},
|
||||||
addNewQueryItem: () => {},
|
addNewQueryItem: () => {},
|
||||||
|
redirectWithQueryBuilderData: () => {},
|
||||||
});
|
});
|
||||||
|
|
||||||
export function QueryBuilderProvider({
|
export function QueryBuilderProvider({
|
||||||
children,
|
children,
|
||||||
}: PropsWithChildren): JSX.Element {
|
}: PropsWithChildren): JSX.Element {
|
||||||
|
const urlQuery = useUrlQuery();
|
||||||
|
const history = useHistory();
|
||||||
|
const location = useLocation();
|
||||||
|
|
||||||
const [initialDataSource, setInitialDataSource] = useState<DataSource | null>(
|
const [initialDataSource, setInitialDataSource] = useState<DataSource | null>(
|
||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
@ -85,13 +98,41 @@ export function QueryBuilderProvider({
|
|||||||
setCurrentQuery(initialQuery);
|
setCurrentQuery(initialQuery);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const initQueryBuilderData = useCallback(
|
const initQueryBuilderData = useCallback((query: Partial<Query>): void => {
|
||||||
(query: QueryState, queryType: EQueryType): void => {
|
const { queryType, ...queryState } = query;
|
||||||
setCurrentQuery(query);
|
const builder: QueryBuilderData = {
|
||||||
setQueryType(queryType);
|
queryData: queryState.builder
|
||||||
},
|
? queryState.builder.queryData.map((item) => ({
|
||||||
[],
|
...initialQueryBuilderFormValues,
|
||||||
);
|
...item,
|
||||||
|
}))
|
||||||
|
: initialQuery.builder.queryData,
|
||||||
|
queryFormulas: queryState.builder
|
||||||
|
? queryState.builder.queryFormulas.map((item) => ({
|
||||||
|
...initialFormulaBuilderFormValues,
|
||||||
|
...item,
|
||||||
|
}))
|
||||||
|
: initialQuery.builder.queryFormulas,
|
||||||
|
};
|
||||||
|
|
||||||
|
const promql: IPromQLQuery[] = queryState.promql
|
||||||
|
? queryState.promql.map((item) => ({
|
||||||
|
...initialQueryPromQLData,
|
||||||
|
...item,
|
||||||
|
}))
|
||||||
|
: initialQuery.promql;
|
||||||
|
|
||||||
|
const clickHouse: IClickHouseQuery[] = queryState.clickhouse_sql
|
||||||
|
? queryState.clickhouse_sql.map((item) => ({
|
||||||
|
...initialClickHouseData,
|
||||||
|
...item,
|
||||||
|
}))
|
||||||
|
: initialQuery.clickhouse_sql;
|
||||||
|
|
||||||
|
setCurrentQuery({ builder, clickhouse_sql: clickHouse, promql });
|
||||||
|
|
||||||
|
setQueryType(queryType || EQueryType.QUERY_BUILDER);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const removeQueryBuilderEntityByIndex = useCallback(
|
const removeQueryBuilderEntityByIndex = useCallback(
|
||||||
(type: keyof QueryBuilderData, index: number) => {
|
(type: keyof QueryBuilderData, index: number) => {
|
||||||
@ -316,10 +357,62 @@ export function QueryBuilderProvider({
|
|||||||
setPanelType(newPanelType);
|
setPanelType(newPanelType);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const redirectWithQueryBuilderData = useCallback(
|
||||||
|
(query: Partial<Query>) => {
|
||||||
|
const currentGeneratedQuery: Query = {
|
||||||
|
queryType:
|
||||||
|
!query.queryType || !Object.values(EQueryType).includes(query.queryType)
|
||||||
|
? EQueryType.QUERY_BUILDER
|
||||||
|
: query.queryType,
|
||||||
|
builder:
|
||||||
|
!query.builder || query.builder.queryData.length === 0
|
||||||
|
? initialQuery.builder
|
||||||
|
: query.builder,
|
||||||
|
promql:
|
||||||
|
!query.promql || query.promql.length === 0
|
||||||
|
? initialQuery.promql
|
||||||
|
: query.promql,
|
||||||
|
clickhouse_sql:
|
||||||
|
!query.clickhouse_sql || query.clickhouse_sql.length === 0
|
||||||
|
? initialQuery.clickhouse_sql
|
||||||
|
: query.clickhouse_sql,
|
||||||
|
};
|
||||||
|
|
||||||
|
urlQuery.set(COMPOSITE_QUERY, JSON.stringify(currentGeneratedQuery));
|
||||||
|
|
||||||
|
const generatedUrl = `${location.pathname}?${urlQuery.toString()}`;
|
||||||
|
|
||||||
|
history.push(generatedUrl);
|
||||||
|
},
|
||||||
|
[history, location, urlQuery],
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const compositeQuery = urlQuery.get(COMPOSITE_QUERY);
|
||||||
|
if (!compositeQuery) return;
|
||||||
|
|
||||||
|
const newQuery: Query = JSON.parse(compositeQuery);
|
||||||
|
|
||||||
|
const { isValid, validData } = replaceIncorrectObjectFields(
|
||||||
|
newQuery,
|
||||||
|
initialQueryWithType,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isValid) {
|
||||||
|
redirectWithQueryBuilderData(validData);
|
||||||
|
} else {
|
||||||
|
initQueryBuilderData(newQuery);
|
||||||
|
}
|
||||||
|
}, [initQueryBuilderData, redirectWithQueryBuilderData, urlQuery]);
|
||||||
|
|
||||||
|
const query: Query = useMemo(() => ({ ...currentQuery, queryType }), [
|
||||||
|
currentQuery,
|
||||||
|
queryType,
|
||||||
|
]);
|
||||||
|
|
||||||
const contextValues: QueryBuilderContextType = useMemo(
|
const contextValues: QueryBuilderContextType = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
currentQuery,
|
currentQuery: query,
|
||||||
queryType,
|
|
||||||
initialDataSource,
|
initialDataSource,
|
||||||
panelType,
|
panelType,
|
||||||
resetQueryBuilderData,
|
resetQueryBuilderData,
|
||||||
@ -336,12 +429,12 @@ export function QueryBuilderProvider({
|
|||||||
addNewBuilderQuery,
|
addNewBuilderQuery,
|
||||||
addNewFormula,
|
addNewFormula,
|
||||||
addNewQueryItem,
|
addNewQueryItem,
|
||||||
|
redirectWithQueryBuilderData,
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
currentQuery,
|
query,
|
||||||
initialDataSource,
|
initialDataSource,
|
||||||
panelType,
|
panelType,
|
||||||
queryType,
|
|
||||||
resetQueryBuilderData,
|
resetQueryBuilderData,
|
||||||
resetQueryBuilderInfo,
|
resetQueryBuilderInfo,
|
||||||
handleSetQueryData,
|
handleSetQueryData,
|
||||||
@ -356,6 +449,7 @@ export function QueryBuilderProvider({
|
|||||||
addNewBuilderQuery,
|
addNewBuilderQuery,
|
||||||
addNewFormula,
|
addNewFormula,
|
||||||
addNewQueryItem,
|
addNewQueryItem,
|
||||||
|
redirectWithQueryBuilderData,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,15 +1,9 @@
|
|||||||
import getDashboard from 'api/dashboard/get';
|
import getDashboard from 'api/dashboard/get';
|
||||||
import {
|
import { initialQueryWithType, PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
initialClickHouseData,
|
|
||||||
initialQueryBuilderFormValues,
|
|
||||||
initialQueryPromQLData,
|
|
||||||
PANEL_TYPES,
|
|
||||||
} from 'constants/queryBuilder';
|
|
||||||
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
||||||
import { Dispatch } from 'redux';
|
import { Dispatch } from 'redux';
|
||||||
import AppActions from 'types/actions';
|
import AppActions from 'types/actions';
|
||||||
import { Props } from 'types/api/dashboard/get';
|
import { Props } from 'types/api/dashboard/get';
|
||||||
import { EQueryType } from 'types/common/dashboard';
|
|
||||||
|
|
||||||
export const GetDashboard = ({
|
export const GetDashboard = ({
|
||||||
uuid,
|
uuid,
|
||||||
@ -55,15 +49,7 @@ export const GetDashboard = ({
|
|||||||
errorMessage: '',
|
errorMessage: '',
|
||||||
loading: false,
|
loading: false,
|
||||||
},
|
},
|
||||||
query: {
|
query: initialQueryWithType,
|
||||||
queryType: EQueryType.QUERY_BUILDER,
|
|
||||||
promql: [initialQueryPromQLData],
|
|
||||||
clickhouse_sql: [initialClickHouseData],
|
|
||||||
builder: {
|
|
||||||
queryFormulas: [],
|
|
||||||
queryData: [initialQueryBuilderFormValues],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -84,8 +84,6 @@ export interface Query {
|
|||||||
|
|
||||||
export type QueryState = Omit<Query, 'queryType'>;
|
export type QueryState = Omit<Query, 'queryType'>;
|
||||||
|
|
||||||
export type BuilderQueryResource = Record<string, IBuilderQuery>;
|
|
||||||
export type BuilderFormulaResource = Record<string, IBuilderFormula>;
|
|
||||||
export type BuilderClickHouseResource = Record<string, IClickHouseQuery>;
|
export type BuilderClickHouseResource = Record<string, IClickHouseQuery>;
|
||||||
export type BuilderPromQLResource = Record<string, IPromQLQuery>;
|
export type BuilderPromQLResource = Record<string, IPromQLQuery>;
|
||||||
export type BuilderQueryDataResourse = Record<
|
export type BuilderQueryDataResourse = Record<
|
||||||
|
@ -4,7 +4,7 @@ import {
|
|||||||
IBuilderQuery,
|
IBuilderQuery,
|
||||||
IClickHouseQuery,
|
IClickHouseQuery,
|
||||||
IPromQLQuery,
|
IPromQLQuery,
|
||||||
QueryState,
|
Query,
|
||||||
} from 'types/api/queryBuilder/queryBuilderData';
|
} from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
import { EQueryType } from './dashboard';
|
import { EQueryType } from './dashboard';
|
||||||
@ -153,8 +153,7 @@ export type QueryBuilderData = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type QueryBuilderContextType = {
|
export type QueryBuilderContextType = {
|
||||||
currentQuery: QueryState;
|
currentQuery: Query;
|
||||||
queryType: EQueryType;
|
|
||||||
initialDataSource: DataSource | null;
|
initialDataSource: DataSource | null;
|
||||||
panelType: GRAPH_TYPES;
|
panelType: GRAPH_TYPES;
|
||||||
resetQueryBuilderData: () => void;
|
resetQueryBuilderData: () => void;
|
||||||
@ -168,7 +167,7 @@ export type QueryBuilderContextType = {
|
|||||||
) => void;
|
) => void;
|
||||||
handleSetPanelType: (newPanelType: GRAPH_TYPES) => void;
|
handleSetPanelType: (newPanelType: GRAPH_TYPES) => void;
|
||||||
handleSetQueryType: (newQueryType: EQueryType) => void;
|
handleSetQueryType: (newQueryType: EQueryType) => void;
|
||||||
initQueryBuilderData: (query: QueryState, queryType: EQueryType) => void;
|
initQueryBuilderData: (query: Partial<Query>) => void;
|
||||||
setupInitialDataSource: (newInitialDataSource: DataSource | null) => void;
|
setupInitialDataSource: (newInitialDataSource: DataSource | null) => void;
|
||||||
removeQueryBuilderEntityByIndex: (
|
removeQueryBuilderEntityByIndex: (
|
||||||
type: keyof QueryBuilderData,
|
type: keyof QueryBuilderData,
|
||||||
@ -181,6 +180,7 @@ export type QueryBuilderContextType = {
|
|||||||
addNewBuilderQuery: () => void;
|
addNewBuilderQuery: () => void;
|
||||||
addNewFormula: () => void;
|
addNewFormula: () => void;
|
||||||
addNewQueryItem: (type: EQueryType.PROM | EQueryType.CLICKHOUSE) => void;
|
addNewQueryItem: (type: EQueryType.PROM | EQueryType.CLICKHOUSE) => void;
|
||||||
|
redirectWithQueryBuilderData: (query: Query) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type QueryAdditionalFilter = {
|
export type QueryAdditionalFilter = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user