feat: add share url (#2778)

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
This commit is contained in:
Yevhen Shevchenko 2023-06-01 20:17:09 +03:00 committed by GitHub
parent 7fd27ec09d
commit ad5a9dcd6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 405 additions and 203 deletions

View File

@ -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),

View File

@ -0,0 +1 @@
export const COMPOSITE_QUERY = 'compositeQuery';

View File

@ -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,
};

View File

@ -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}

View File

@ -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>
</> </>

View File

@ -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 => {

View File

@ -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 };

View File

@ -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>

View File

@ -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({

View File

@ -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>

View File

@ -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 => {

View 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 };
};

View File

@ -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,
};
}; };

View File

@ -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 };
};

View 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 };
}

View File

@ -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,
], ],
); );

View File

@ -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],
},
},
}, },
}); });
} }

View File

@ -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<

View File

@ -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 = {