mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-08 06:48:58 +08:00
feat: Metrics Builder Enhancements and Code Cleanup (#1325)
* feat: improved ts typings * chore: remove uncommented code
This commit is contained in:
parent
6dbc11991b
commit
ba7427f280
@ -24,8 +24,11 @@ function TextToolTip({ text, url }: TextToolTipProps): JSX.Element {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextToolTip.defaultProps = {
|
||||||
|
url: '',
|
||||||
|
};
|
||||||
interface TextToolTipProps {
|
interface TextToolTipProps {
|
||||||
url: string;
|
url?: string;
|
||||||
text: string;
|
text: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,18 +36,17 @@ export const UpdateDashboard = async ({
|
|||||||
nullZeroValues: '',
|
nullZeroValues: '',
|
||||||
opacity: '',
|
opacity: '',
|
||||||
panelTypes: graphType,
|
panelTypes: graphType,
|
||||||
queryType: 0,
|
|
||||||
query: {
|
query: {
|
||||||
queryType: EQueryType.QUERY_BUILDER,
|
queryType: EQueryType.QUERY_BUILDER,
|
||||||
promQL: [
|
promQL: [
|
||||||
{
|
{
|
||||||
name: GetQueryName([]),
|
name: GetQueryName([]) || '',
|
||||||
...PromQLQueryTemplate,
|
...PromQLQueryTemplate,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
clickHouse: [
|
clickHouse: [
|
||||||
{
|
{
|
||||||
name: GetQueryName([]),
|
name: GetQueryName([]) || '',
|
||||||
...ClickHouseQueryTemplate,
|
...ClickHouseQueryTemplate,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -55,14 +54,14 @@ export const UpdateDashboard = async ({
|
|||||||
formulas: [],
|
formulas: [],
|
||||||
queryBuilder: [
|
queryBuilder: [
|
||||||
{
|
{
|
||||||
name: GetQueryName([]),
|
name: GetQueryName([]) || '',
|
||||||
...QueryBuilderQueryTemplate,
|
...QueryBuilderQueryTemplate,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
queryData: {
|
queryData: {
|
||||||
data: [],
|
data: { queryData: [] },
|
||||||
error: false,
|
error: false,
|
||||||
errorMessage: '',
|
errorMessage: '',
|
||||||
loading: false,
|
loading: false,
|
||||||
|
@ -73,10 +73,7 @@ function ImportJSON({
|
|||||||
...e,
|
...e,
|
||||||
queryData: {
|
queryData: {
|
||||||
...e.queryData,
|
...e.queryData,
|
||||||
data: e.queryData.data.map((queryData) => ({
|
data: e.queryData.data,
|
||||||
...queryData,
|
|
||||||
queryData: [],
|
|
||||||
})),
|
|
||||||
error: false,
|
error: false,
|
||||||
errorMessage: '',
|
errorMessage: '',
|
||||||
loading: false,
|
loading: false,
|
||||||
|
@ -4,7 +4,7 @@ import React from 'react';
|
|||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { PromQLWidgets, Widgets } from 'types/api/dashboard/getAll';
|
import { PromQLWidgets } from 'types/api/dashboard/getAll';
|
||||||
import MetricReducer from 'types/reducer/metrics';
|
import MetricReducer from 'types/reducer/metrics';
|
||||||
|
|
||||||
import { Card, GraphContainer, GraphTitle, Row } from '../styles';
|
import { Card, GraphContainer, GraphTitle, Row } from '../styles';
|
||||||
|
@ -29,7 +29,7 @@ function External({ getWidget }: ExternalProps): JSX.Element {
|
|||||||
widget={getWidget([
|
widget={getWidget([
|
||||||
{
|
{
|
||||||
query: `max((sum(rate(signoz_external_call_latency_count{service_name="${servicename}", status_code="STATUS_CODE_ERROR"${resourceAttributePromQLQuery}}[1m]) OR rate(signoz_external_call_latency_count{service_name="${servicename}", http_status_code=~"5.."${resourceAttributePromQLQuery}}[1m]) OR vector(0)) by (http_url))*100/sum(rate(signoz_external_call_latency_count{service_name="${servicename}"${resourceAttributePromQLQuery}}[1m])) by (http_url)) < 1000 OR vector(0)`,
|
query: `max((sum(rate(signoz_external_call_latency_count{service_name="${servicename}", status_code="STATUS_CODE_ERROR"${resourceAttributePromQLQuery}}[1m]) OR rate(signoz_external_call_latency_count{service_name="${servicename}", http_status_code=~"5.."${resourceAttributePromQLQuery}}[1m]) OR vector(0)) by (http_url))*100/sum(rate(signoz_external_call_latency_count{service_name="${servicename}"${resourceAttributePromQLQuery}}[1m])) by (http_url)) < 1000 OR vector(0)`,
|
||||||
legend,
|
legend: 'External Call Error Percentage',
|
||||||
},
|
},
|
||||||
])}
|
])}
|
||||||
yAxisUnit="%"
|
yAxisUnit="%"
|
||||||
|
@ -42,7 +42,8 @@ function Application({ getWidget }: DashboardProps): JSX.Element {
|
|||||||
urlParams.set(METRICS_PAGE_QUERY_PARAM.endTime, tPlusOne.toString());
|
urlParams.set(METRICS_PAGE_QUERY_PARAM.endTime, tPlusOne.toString());
|
||||||
|
|
||||||
history.replace(
|
history.replace(
|
||||||
`${ROUTES.TRACE
|
`${
|
||||||
|
ROUTES.TRACE
|
||||||
}?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&&isFilterExclude={"serviceName":false}&userSelectedFilter={"status":["error","ok"],"serviceName":["${servicename}"]}&spanAggregateCurrentPage=1&spanAggregateOrder=ascend`,
|
}?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&&isFilterExclude={"serviceName":false}&userSelectedFilter={"status":["error","ok"],"serviceName":["${servicename}"]}&spanAggregateCurrentPage=1&spanAggregateOrder=ascend`,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -93,7 +94,8 @@ function Application({ getWidget }: DashboardProps): JSX.Element {
|
|||||||
urlParams.set(METRICS_PAGE_QUERY_PARAM.endTime, tPlusOne.toString());
|
urlParams.set(METRICS_PAGE_QUERY_PARAM.endTime, tPlusOne.toString());
|
||||||
|
|
||||||
history.replace(
|
history.replace(
|
||||||
`${ROUTES.TRACE
|
`${
|
||||||
|
ROUTES.TRACE
|
||||||
}?${urlParams.toString()}?selected={"serviceName":["${servicename}"],"status":["error"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&isFilterExclude={"serviceName":false,"status":false}&userSelectedFilter={"serviceName":["${servicename}"],"status":["error"]}&spanAggregateCurrentPage=1&spanAggregateOrder=ascend`,
|
}?${urlParams.toString()}?selected={"serviceName":["${servicename}"],"status":["error"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&isFilterExclude={"serviceName":false,"status":false}&userSelectedFilter={"serviceName":["${servicename}"],"status":["error"]}&spanAggregateCurrentPage=1&spanAggregateOrder=ascend`,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -20,7 +20,7 @@ const getWidget = (query: PromQLWidgets['query']): PromQLWidgets => {
|
|||||||
panelTypes: 'TIME_SERIES',
|
panelTypes: 'TIME_SERIES',
|
||||||
query,
|
query,
|
||||||
queryData: {
|
queryData: {
|
||||||
data: [],
|
data: { queryData: [] },
|
||||||
error: false,
|
error: false,
|
||||||
errorMessage: '',
|
errorMessage: '',
|
||||||
loading: false,
|
loading: false,
|
||||||
|
@ -5,7 +5,7 @@ export const AggregateFunctions = Object.keys(EAggregateOperator)
|
|||||||
.map((key) => {
|
.map((key) => {
|
||||||
return {
|
return {
|
||||||
label: key,
|
label: key,
|
||||||
value: EAggregateOperator[key],
|
value: EAggregateOperator[key as keyof typeof EAggregateOperator],
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -10,13 +10,21 @@ import React, { useState } from 'react';
|
|||||||
|
|
||||||
import { QueryWrapper } from '../styles';
|
import { QueryWrapper } from '../styles';
|
||||||
|
|
||||||
|
interface IQueryHeaderProps {
|
||||||
|
disabled: boolean;
|
||||||
|
onDisable: VoidFunction;
|
||||||
|
name: string;
|
||||||
|
onDelete: VoidFunction;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
function QueryHeader({
|
function QueryHeader({
|
||||||
disabled,
|
disabled,
|
||||||
onDisable,
|
onDisable,
|
||||||
name,
|
name,
|
||||||
onDelete,
|
onDelete,
|
||||||
children,
|
children,
|
||||||
}): JSX.Element {
|
}: IQueryHeaderProps): JSX.Element {
|
||||||
const [collapse, setCollapse] = useState(false);
|
const [collapse, setCollapse] = useState(false);
|
||||||
return (
|
return (
|
||||||
<QueryWrapper>
|
<QueryWrapper>
|
||||||
|
@ -2,23 +2,31 @@ import { PlusOutlined } from '@ant-design/icons';
|
|||||||
import { ClickHouseQueryTemplate } from 'constants/dashboard';
|
import { ClickHouseQueryTemplate } from 'constants/dashboard';
|
||||||
import GetQueryName from 'lib/query/GetQueryName';
|
import GetQueryName from 'lib/query/GetQueryName';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { Query } from 'types/api/dashboard/getAll';
|
||||||
|
|
||||||
import { WIDGET_CLICKHOUSE_QUERY_KEY_NAME } from '../../constants';
|
import { WIDGET_CLICKHOUSE_QUERY_KEY_NAME } from '../../constants';
|
||||||
import { QueryButton } from '../../styles';
|
import { QueryButton } from '../../styles';
|
||||||
|
import { IHandleUpdatedQuery } from '../../types';
|
||||||
import ClickHouseQueryBuilder from './query';
|
import ClickHouseQueryBuilder from './query';
|
||||||
|
import { IClickHouseQueryHandleChange } from './types';
|
||||||
|
|
||||||
|
interface IClickHouseQueryContainerProps {
|
||||||
|
queryData: Query;
|
||||||
|
updateQueryData: (args: IHandleUpdatedQuery) => void;
|
||||||
|
clickHouseQueries: Query['clickHouse'];
|
||||||
|
}
|
||||||
function ClickHouseQueryContainer({
|
function ClickHouseQueryContainer({
|
||||||
queryData,
|
queryData,
|
||||||
updateQueryData,
|
updateQueryData,
|
||||||
clickHouseQueries,
|
clickHouseQueries,
|
||||||
}): JSX.Element | null {
|
}: IClickHouseQueryContainerProps): JSX.Element | null {
|
||||||
const handleClickHouseQueryChange = ({
|
const handleClickHouseQueryChange = ({
|
||||||
queryIndex,
|
queryIndex,
|
||||||
rawQuery,
|
rawQuery,
|
||||||
legend,
|
legend,
|
||||||
toggleDisable,
|
toggleDisable,
|
||||||
toggleDelete,
|
toggleDelete,
|
||||||
}): void => {
|
}: IClickHouseQueryHandleChange): void => {
|
||||||
const allQueries = queryData[WIDGET_CLICKHOUSE_QUERY_KEY_NAME];
|
const allQueries = queryData[WIDGET_CLICKHOUSE_QUERY_KEY_NAME];
|
||||||
const currentIndexQuery = allQueries[queryIndex];
|
const currentIndexQuery = allQueries[queryIndex];
|
||||||
|
|
||||||
@ -40,7 +48,7 @@ function ClickHouseQueryContainer({
|
|||||||
};
|
};
|
||||||
const addQueryHandler = (): void => {
|
const addQueryHandler = (): void => {
|
||||||
queryData[WIDGET_CLICKHOUSE_QUERY_KEY_NAME].push({
|
queryData[WIDGET_CLICKHOUSE_QUERY_KEY_NAME].push({
|
||||||
name: GetQueryName(queryData[WIDGET_CLICKHOUSE_QUERY_KEY_NAME]),
|
name: GetQueryName(queryData[WIDGET_CLICKHOUSE_QUERY_KEY_NAME]) || '',
|
||||||
...ClickHouseQueryTemplate,
|
...ClickHouseQueryTemplate,
|
||||||
});
|
});
|
||||||
updateQueryData({ updatedQuery: { ...queryData } });
|
updateQueryData({ updatedQuery: { ...queryData } });
|
||||||
|
@ -1,14 +1,22 @@
|
|||||||
import { Input } from 'antd';
|
import { Input } from 'antd';
|
||||||
import MonacoEditor from 'components/Editor';
|
import MonacoEditor from 'components/Editor';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { IClickHouseQuery } from 'types/api/dashboard/getAll';
|
||||||
|
|
||||||
import QueryHeader from '../QueryHeader';
|
import QueryHeader from '../QueryHeader';
|
||||||
|
import { IClickHouseQueryHandleChange } from './types';
|
||||||
|
|
||||||
|
interface IClickHouseQueryBuilderProps {
|
||||||
|
queryData: IClickHouseQuery;
|
||||||
|
queryIndex: number;
|
||||||
|
handleQueryChange: (args: IClickHouseQueryHandleChange) => void;
|
||||||
|
}
|
||||||
|
|
||||||
function ClickHouseQueryBuilder({
|
function ClickHouseQueryBuilder({
|
||||||
queryData,
|
queryData,
|
||||||
queryIndex,
|
queryIndex,
|
||||||
handleQueryChange,
|
handleQueryChange,
|
||||||
}): JSX.Element | null {
|
}: IClickHouseQueryBuilderProps): JSX.Element | null {
|
||||||
if (queryData === undefined) {
|
if (queryData === undefined) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -26,7 +34,6 @@ function ClickHouseQueryBuilder({
|
|||||||
>
|
>
|
||||||
<MonacoEditor
|
<MonacoEditor
|
||||||
language="sql"
|
language="sql"
|
||||||
theme="vs-dark"
|
|
||||||
height="200px"
|
height="200px"
|
||||||
onChange={(value): void =>
|
onChange={(value): void =>
|
||||||
handleQueryChange({ queryIndex, rawQuery: value })
|
handleQueryChange({ queryIndex, rawQuery: value })
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
import { IClickHouseQuery } from 'types/api/dashboard/getAll';
|
||||||
|
|
||||||
|
export interface IClickHouseQueryHandleChange {
|
||||||
|
queryIndex: number;
|
||||||
|
rawQuery?: IClickHouseQuery['rawQuery'];
|
||||||
|
legend?: IClickHouseQuery['legend'];
|
||||||
|
toggleDisable?: IClickHouseQuery['disabled'];
|
||||||
|
toggleDelete?: boolean;
|
||||||
|
}
|
@ -1,95 +0,0 @@
|
|||||||
import {
|
|
||||||
DeleteOutlined,
|
|
||||||
DownOutlined,
|
|
||||||
EyeFilled,
|
|
||||||
RightOutlined,
|
|
||||||
} from '@ant-design/icons';
|
|
||||||
import { Button, Row } from 'antd';
|
|
||||||
import MonacoEditor from 'components/Editor';
|
|
||||||
import React, { useState } from 'react';
|
|
||||||
import { useSelector } from 'react-redux';
|
|
||||||
import { AppState } from 'store/reducers';
|
|
||||||
import AppReducer from 'types/reducer/app';
|
|
||||||
|
|
||||||
import { QueryBuilderWrapper, QueryWrapper } from '../styles';
|
|
||||||
import { TQueryCategories } from '../types';
|
|
||||||
import PromQLQueryBuilder from './promQL/promQL';
|
|
||||||
import MetricsBuilder from './queryBuilder/query';
|
|
||||||
|
|
||||||
function QueryBuilder({
|
|
||||||
name,
|
|
||||||
onDelete,
|
|
||||||
queryCategory,
|
|
||||||
queryData,
|
|
||||||
updateQueryData,
|
|
||||||
}: QueryBuilderProps): JSX.Element {
|
|
||||||
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
|
|
||||||
const [hideFromUI, setHideFromUI] = useState<boolean>(false);
|
|
||||||
const handleHideFromUI = (): void => {
|
|
||||||
setHideFromUI(!hideFromUI);
|
|
||||||
};
|
|
||||||
const handleClickhouseQueryChange = (clickHouseQuery): void => {
|
|
||||||
if (clickHouseQuery !== null) {
|
|
||||||
queryData.clickHouseQuery = clickHouseQuery;
|
|
||||||
}
|
|
||||||
updateQueryData(queryData);
|
|
||||||
};
|
|
||||||
const handlePromQLQueryChange = ({ query, legend }): void => {
|
|
||||||
if (query) queryData.promQL.query = query;
|
|
||||||
if (legend) queryData.promQL.legend = legend;
|
|
||||||
|
|
||||||
updateQueryData(queryData);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<QueryWrapper>
|
|
||||||
<Row style={{ justifyContent: 'space-between' }}>
|
|
||||||
<Row>
|
|
||||||
<Button type="ghost" icon={<EyeFilled />}>
|
|
||||||
{name}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
type="ghost"
|
|
||||||
icon={hideFromUI ? <RightOutlined /> : <DownOutlined />}
|
|
||||||
onClick={handleHideFromUI}
|
|
||||||
/>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Button type="ghost" danger icon={<DeleteOutlined />} onClick={onDelete} />
|
|
||||||
</Row>
|
|
||||||
{!hideFromUI && (
|
|
||||||
<QueryBuilderWrapper isDarkMode={isDarkMode}>
|
|
||||||
{queryCategory === 0 ? (
|
|
||||||
<MetricsBuilder
|
|
||||||
queryData={queryData}
|
|
||||||
updateQueryData={updateQueryData}
|
|
||||||
metricName={queryData.queryBuilder.metricName}
|
|
||||||
/>
|
|
||||||
) : queryCategory === 1 ? (
|
|
||||||
<MonacoEditor
|
|
||||||
language="sql"
|
|
||||||
theme="vs-dark"
|
|
||||||
height="200px"
|
|
||||||
onChange={handleClickhouseQueryChange}
|
|
||||||
value={queryData.clickHouseQuery}
|
|
||||||
// options={options}
|
|
||||||
/>
|
|
||||||
) : queryCategory === 2 ? (
|
|
||||||
<PromQLQueryBuilder
|
|
||||||
query={queryData.promQL.query}
|
|
||||||
onQueryChange={(value) => handlePromQLQueryChange({ query: value })}
|
|
||||||
legend={queryData.promQL.legend}
|
|
||||||
onLegendChange={(value) => handlePromQLQueryChange({ legend: value })}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
</QueryBuilderWrapper>
|
|
||||||
)}
|
|
||||||
</QueryWrapper>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface QueryBuilderProps {
|
|
||||||
queryCategory: TQueryCategories;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
export default QueryBuilder;
|
|
@ -2,25 +2,32 @@ import { PlusOutlined } from '@ant-design/icons';
|
|||||||
import { PromQLQueryTemplate } from 'constants/dashboard';
|
import { PromQLQueryTemplate } from 'constants/dashboard';
|
||||||
import GetQueryName from 'lib/query/GetQueryName';
|
import GetQueryName from 'lib/query/GetQueryName';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { IPromQLQuery, Query } from 'types/api/dashboard/getAll';
|
||||||
|
|
||||||
import { WIDGET_PROMQL_QUERY_KEY_NAME } from '../../constants';
|
import { WIDGET_PROMQL_QUERY_KEY_NAME } from '../../constants';
|
||||||
import { QueryButton } from '../../styles';
|
import { QueryButton } from '../../styles';
|
||||||
|
import { IHandleUpdatedQuery } from '../../types';
|
||||||
import PromQLQueryBuilder from './query';
|
import PromQLQueryBuilder from './query';
|
||||||
|
import { IPromQLQueryHandleChange } from './types';
|
||||||
|
|
||||||
|
interface IPromQLQueryContainerProps {
|
||||||
|
queryData: Query;
|
||||||
|
updateQueryData: (args: IHandleUpdatedQuery) => void;
|
||||||
|
promQLQueries: IPromQLQuery[];
|
||||||
|
}
|
||||||
|
|
||||||
function PromQLQueryContainer({
|
function PromQLQueryContainer({
|
||||||
queryData,
|
queryData,
|
||||||
updateQueryData,
|
updateQueryData,
|
||||||
promQLQueries,
|
promQLQueries,
|
||||||
onQueryChange,
|
}: IPromQLQueryContainerProps): JSX.Element | null {
|
||||||
onQueryAdd,
|
|
||||||
}): JSX.Element | null {
|
|
||||||
const handlePromQLQueryChange = ({
|
const handlePromQLQueryChange = ({
|
||||||
queryIndex,
|
queryIndex,
|
||||||
query,
|
query,
|
||||||
legend,
|
legend,
|
||||||
toggleDisable,
|
toggleDisable,
|
||||||
toggleDelete,
|
toggleDelete,
|
||||||
}): void => {
|
}: IPromQLQueryHandleChange): void => {
|
||||||
const allQueries = queryData[WIDGET_PROMQL_QUERY_KEY_NAME];
|
const allQueries = queryData[WIDGET_PROMQL_QUERY_KEY_NAME];
|
||||||
const currentIndexQuery = allQueries[queryIndex];
|
const currentIndexQuery = allQueries[queryIndex];
|
||||||
if (query) currentIndexQuery.query = query;
|
if (query) currentIndexQuery.query = query;
|
||||||
@ -36,7 +43,7 @@ function PromQLQueryContainer({
|
|||||||
};
|
};
|
||||||
const addQueryHandler = (): void => {
|
const addQueryHandler = (): void => {
|
||||||
queryData[WIDGET_PROMQL_QUERY_KEY_NAME].push({
|
queryData[WIDGET_PROMQL_QUERY_KEY_NAME].push({
|
||||||
name: GetQueryName(queryData[WIDGET_PROMQL_QUERY_KEY_NAME]),
|
name: GetQueryName(queryData[WIDGET_PROMQL_QUERY_KEY_NAME]) || '',
|
||||||
...PromQLQueryTemplate,
|
...PromQLQueryTemplate,
|
||||||
});
|
});
|
||||||
updateQueryData({ updatedQuery: { ...queryData } });
|
updateQueryData({ updatedQuery: { ...queryData } });
|
||||||
@ -48,7 +55,7 @@ function PromQLQueryContainer({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{promQLQueries.map(
|
{promQLQueries.map(
|
||||||
(q, idx): JSX.Element => (
|
(q: IPromQLQuery, idx: number): JSX.Element => (
|
||||||
<PromQLQueryBuilder
|
<PromQLQueryBuilder
|
||||||
key={q.name}
|
key={q.name}
|
||||||
queryIndex={idx}
|
queryIndex={idx}
|
||||||
|
@ -1,13 +1,21 @@
|
|||||||
import { Input } from 'antd';
|
import { Input } from 'antd';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { IPromQLQuery } from 'types/api/dashboard/getAll';
|
||||||
|
|
||||||
import QueryHeader from '../QueryHeader';
|
import QueryHeader from '../QueryHeader';
|
||||||
|
import { IPromQLQueryHandleChange } from './types';
|
||||||
|
|
||||||
|
interface IPromQLQueryBuilderProps {
|
||||||
|
queryData: IPromQLQuery;
|
||||||
|
queryIndex: number;
|
||||||
|
handleQueryChange: (args: IPromQLQueryHandleChange) => void;
|
||||||
|
}
|
||||||
|
|
||||||
function PromQLQueryBuilder({
|
function PromQLQueryBuilder({
|
||||||
queryData,
|
queryData,
|
||||||
queryIndex,
|
queryIndex,
|
||||||
handleQueryChange,
|
handleQueryChange,
|
||||||
}): JSX.Element {
|
}: IPromQLQueryBuilderProps): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<QueryHeader
|
<QueryHeader
|
||||||
name={queryData.name}
|
name={queryData.name}
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
import { IPromQLQuery } from 'types/api/dashboard/getAll';
|
||||||
|
|
||||||
|
export interface IPromQLQueryHandleChange {
|
||||||
|
queryIndex: number;
|
||||||
|
query?: IPromQLQuery['query'];
|
||||||
|
legend?: IPromQLQuery['legend'];
|
||||||
|
toggleDisable?: IPromQLQuery['disabled'];
|
||||||
|
toggleDelete?: boolean;
|
||||||
|
}
|
@ -1,12 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { QueryChipContainer, QueryChipItem } from './styles';
|
import { QueryChipContainer, QueryChipItem } from './styles';
|
||||||
import { IMetricBuilderTagKeyQuery } from './types';
|
import { ITagKeyValueQuery } from './types';
|
||||||
|
|
||||||
interface IQueryChipProps {
|
interface IQueryChipProps {
|
||||||
queryData: IMetricBuilderTagKeyQuery;
|
queryData: ITagKeyValueQuery;
|
||||||
onClose: (id: string) => void;
|
onClose: (id: string) => void;
|
||||||
disabled: boolean;
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function QueryChip({
|
export default function QueryChip({
|
||||||
@ -29,3 +29,6 @@ export default function QueryChip({
|
|||||||
</QueryChipContainer>
|
</QueryChipContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
QueryChip.defaultProps = {
|
||||||
|
disabled: false,
|
||||||
|
};
|
||||||
|
@ -5,13 +5,14 @@ import { map } from 'lodash-es';
|
|||||||
import React, { useCallback, useEffect, useState } from 'react';
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
|
import { IMetricsBuilderQuery } from 'types/api/dashboard/getAll';
|
||||||
import AppReducer from 'types/reducer/app';
|
import AppReducer from 'types/reducer/app';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
import { ResourceAttributesFilterMachine } from './MetricTagKey.machine';
|
import { ResourceAttributesFilterMachine } from './MetricTagKey.machine';
|
||||||
import QueryChip from './QueryChip';
|
import QueryChip from './QueryChip';
|
||||||
import { QueryChipItem, SearchContainer } from './styles';
|
import { QueryChipItem, SearchContainer } from './styles';
|
||||||
import { IMetricBuilderTagKeyQuery, IOption } from './types';
|
import { IOption, ITagKeyValueQuery } from './types';
|
||||||
import {
|
import {
|
||||||
createQuery,
|
createQuery,
|
||||||
GetTagKeys,
|
GetTagKeys,
|
||||||
@ -20,16 +21,22 @@ import {
|
|||||||
SingleValueOperators,
|
SingleValueOperators,
|
||||||
} from './utils';
|
} from './utils';
|
||||||
|
|
||||||
|
interface IMetricTagKeyFilterProps {
|
||||||
|
metricName: IMetricsBuilderQuery['metricName'];
|
||||||
|
onSetQuery: (args: IMetricsBuilderQuery['tagFilters']['items']) => void;
|
||||||
|
selectedTagFilters: IMetricsBuilderQuery['tagFilters']['items'];
|
||||||
|
}
|
||||||
|
|
||||||
function MetricTagKeyFilter({
|
function MetricTagKeyFilter({
|
||||||
metricName,
|
metricName,
|
||||||
onSetQuery,
|
onSetQuery,
|
||||||
selectedTagFilters: selectedTagQueries,
|
selectedTagFilters: selectedTagQueries,
|
||||||
}): JSX.Element | null {
|
}: IMetricTagKeyFilterProps): JSX.Element | null {
|
||||||
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
|
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [selectedValues, setSelectedValues] = useState<string[]>([]);
|
const [selectedValues, setSelectedValues] = useState<string[]>([]);
|
||||||
const [staging, setStaging] = useState<string[]>([]);
|
const [staging, setStaging] = useState<string[]>([]);
|
||||||
const [queries, setQueries] = useState<IMetricBuilderTagKeyQuery[]>([]);
|
const [queries, setQueries] = useState<ITagKeyValueQuery[]>([]);
|
||||||
const [optionsData, setOptionsData] = useState<{
|
const [optionsData, setOptionsData] = useState<{
|
||||||
mode: undefined | 'tags' | 'multiple';
|
mode: undefined | 'tags' | 'multiple';
|
||||||
options: IOption[];
|
options: IOption[];
|
||||||
@ -39,7 +46,7 @@ function MetricTagKeyFilter({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const dispatchQueries = (
|
const dispatchQueries = (
|
||||||
updatedQueries: IMetricBuilderTagKeyQuery[],
|
updatedQueries: IMetricsBuilderQuery['tagFilters']['items'],
|
||||||
): void => {
|
): void => {
|
||||||
onSetQuery(updatedQueries);
|
onSetQuery(updatedQueries);
|
||||||
setQueries(updatedQueries);
|
setQueries(updatedQueries);
|
||||||
@ -54,7 +61,7 @@ function MetricTagKeyFilter({
|
|||||||
actions: {
|
actions: {
|
||||||
onSelectTagKey: () => {
|
onSelectTagKey: () => {
|
||||||
handleLoading(true);
|
handleLoading(true);
|
||||||
GetTagKeys(metricName)
|
GetTagKeys(metricName || '')
|
||||||
.then((tagKeys) => setOptionsData({ options: tagKeys, mode: undefined }))
|
.then((tagKeys) => setOptionsData({ options: tagKeys, mode: undefined }))
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
handleLoading(false);
|
handleLoading(false);
|
||||||
@ -66,7 +73,7 @@ function MetricTagKeyFilter({
|
|||||||
onSelectTagValue: () => {
|
onSelectTagValue: () => {
|
||||||
handleLoading(true);
|
handleLoading(true);
|
||||||
|
|
||||||
GetTagValues(staging[0], metricName)
|
GetTagValues(staging[0], metricName || '')
|
||||||
.then((tagValuesOptions) =>
|
.then((tagValuesOptions) =>
|
||||||
setOptionsData({ options: tagValuesOptions, mode: 'tags' }),
|
setOptionsData({ options: tagValuesOptions, mode: 'tags' }),
|
||||||
)
|
)
|
||||||
@ -113,16 +120,17 @@ function MetricTagKeyFilter({
|
|||||||
handleBlur();
|
handleBlur();
|
||||||
}, [handleBlur, metricName]);
|
}, [handleBlur, metricName]);
|
||||||
|
|
||||||
const handleChange = (value: never): void => {
|
const handleChange = (value: never | string[]): void => {
|
||||||
if (!optionsData.mode) {
|
if (!optionsData.mode) {
|
||||||
setStaging((prevStaging) => [...prevStaging, value]);
|
setStaging((prevStaging) => [...prevStaging, String(value)]);
|
||||||
setSelectedValues([]);
|
setSelectedValues([]);
|
||||||
send('NEXT');
|
send('NEXT');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
state.value === 'TagValue' &&
|
state.value === 'TagValue' &&
|
||||||
SingleValueOperators.includes(staging[staging.length - 1])
|
SingleValueOperators.includes(staging[staging.length - 1]) &&
|
||||||
|
Array.isArray(value)
|
||||||
) {
|
) {
|
||||||
setSelectedValues([value[value.length - 1]]);
|
setSelectedValues([value[value.length - 1]]);
|
||||||
return;
|
return;
|
||||||
@ -142,12 +150,6 @@ function MetricTagKeyFilter({
|
|||||||
setSelectedValues([]);
|
setSelectedValues([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const disabledOrEmpty = !!(
|
|
||||||
queries.length ||
|
|
||||||
staging.length ||
|
|
||||||
selectedValues.length
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SearchContainer isDarkMode={isDarkMode}>
|
<SearchContainer isDarkMode={isDarkMode}>
|
||||||
<div style={{ display: 'inline-flex', flexWrap: 'wrap' }}>
|
<div style={{ display: 'inline-flex', flexWrap: 'wrap' }}>
|
||||||
@ -162,7 +164,7 @@ function MetricTagKeyFilter({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{map(staging, (item, idx) => {
|
{map(staging, (item) => {
|
||||||
return <QueryChipItem key={uuid()}>{item}</QueryChipItem>;
|
return <QueryChipItem key={uuid()}>{item}</QueryChipItem>;
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,7 +4,7 @@ import styled from 'styled-components';
|
|||||||
|
|
||||||
export const SearchContainer = styled.div<{
|
export const SearchContainer = styled.div<{
|
||||||
isDarkMode: boolean;
|
isDarkMode: boolean;
|
||||||
disabled: boolean;
|
disabled?: boolean;
|
||||||
}>`
|
}>`
|
||||||
background: ${({ isDarkMode }): string => (isDarkMode ? '#000' : '#fff')};
|
background: ${({ isDarkMode }): string => (isDarkMode ? '#000' : '#fff')};
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
@ -9,3 +9,10 @@ export interface IMetricBuilderTagKeyQuery {
|
|||||||
operator: string;
|
operator: string;
|
||||||
tagValue: string[];
|
tagValue: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ITagKeyValueQuery {
|
||||||
|
id: string;
|
||||||
|
key: string;
|
||||||
|
op: string;
|
||||||
|
value: string[];
|
||||||
|
}
|
||||||
|
@ -5,7 +5,7 @@ import {
|
|||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
import { TagKeyOperator } from '../../Options';
|
import { TagKeyOperator } from '../../Options';
|
||||||
import { IMetricBuilderTagKeyQuery, IOption } from './types';
|
import { IOption, ITagKeyValueQuery } from './types';
|
||||||
|
|
||||||
export const OperatorSchema: IOption[] = TagKeyOperator;
|
export const OperatorSchema: IOption[] = TagKeyOperator;
|
||||||
|
|
||||||
@ -40,12 +40,12 @@ export const GetTagValues = async (
|
|||||||
|
|
||||||
export const createQuery = (
|
export const createQuery = (
|
||||||
selectedItems: Array<string | string[]> = [],
|
selectedItems: Array<string | string[]> = [],
|
||||||
): IMetricBuilderTagKeyQuery | null => {
|
): ITagKeyValueQuery | null => {
|
||||||
if (selectedItems.length === 3) {
|
if (selectedItems.length === 3) {
|
||||||
return {
|
return {
|
||||||
id: uuid().slice(0, 8),
|
id: uuid().slice(0, 8),
|
||||||
key: selectedItems[0] as string,
|
key: typeof selectedItems[0] === 'string' ? selectedItems[0] : '',
|
||||||
op: selectedItems[1] as string,
|
op: typeof selectedItems[1] === 'string' ? selectedItems[1] : '',
|
||||||
value: selectedItems[2] as string[],
|
value: selectedItems[2] as string[],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,22 @@
|
|||||||
import { Input } from 'antd';
|
import { Input } from 'antd';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { IMetricsBuilderFormula } from 'types/api/dashboard/getAll';
|
||||||
|
|
||||||
import QueryHeader from '../QueryHeader';
|
import QueryHeader from '../QueryHeader';
|
||||||
|
import { IQueryBuilderFormulaHandleChange } from './types';
|
||||||
|
|
||||||
const { TextArea } = Input;
|
const { TextArea } = Input;
|
||||||
|
|
||||||
|
interface IMetricsBuilderFormulaProps {
|
||||||
|
formulaData: IMetricsBuilderFormula;
|
||||||
|
formulaIndex: number;
|
||||||
|
handleFormulaChange: (args: IQueryBuilderFormulaHandleChange) => void;
|
||||||
|
}
|
||||||
function MetricsBuilderFormula({
|
function MetricsBuilderFormula({
|
||||||
formulaData,
|
formulaData,
|
||||||
formulaIndex,
|
formulaIndex,
|
||||||
handleFormulaChange,
|
handleFormulaChange,
|
||||||
}): JSX.Element {
|
}: IMetricsBuilderFormulaProps): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<QueryHeader
|
<QueryHeader
|
||||||
name={formulaData.name}
|
name={formulaData.name}
|
||||||
|
@ -4,25 +4,39 @@ import {
|
|||||||
QueryBuilderFormulaTemplate,
|
QueryBuilderFormulaTemplate,
|
||||||
QueryBuilderQueryTemplate,
|
QueryBuilderQueryTemplate,
|
||||||
} from 'constants/dashboard';
|
} from 'constants/dashboard';
|
||||||
|
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
||||||
import GetFormulaName from 'lib/query/GetFormulaName';
|
import GetFormulaName from 'lib/query/GetFormulaName';
|
||||||
import GetQueryName from 'lib/query/GetQueryName';
|
import GetQueryName from 'lib/query/GetQueryName';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { Query } from 'types/api/dashboard/getAll';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME,
|
WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME,
|
||||||
WIDGET_QUERY_BUILDER_QUERY_KEY_NAME,
|
WIDGET_QUERY_BUILDER_QUERY_KEY_NAME,
|
||||||
} from '../../constants';
|
} from '../../constants';
|
||||||
import { QueryButton } from '../../styles';
|
import { QueryButton } from '../../styles';
|
||||||
|
import { IHandleUpdatedQuery } from '../../types';
|
||||||
import MetricsBuilderFormula from './formula';
|
import MetricsBuilderFormula from './formula';
|
||||||
import MetricsBuilder from './query';
|
import MetricsBuilder from './query';
|
||||||
|
import {
|
||||||
|
IQueryBuilderFormulaHandleChange,
|
||||||
|
IQueryBuilderQueryHandleChange,
|
||||||
|
} from './types';
|
||||||
import { canCreateQueryAndFormula } from './utils';
|
import { canCreateQueryAndFormula } from './utils';
|
||||||
|
|
||||||
|
interface IQueryBuilderQueryContainerProps {
|
||||||
|
queryData: Query;
|
||||||
|
updateQueryData: (args: IHandleUpdatedQuery) => void;
|
||||||
|
metricsBuilderQueries: Query['metricsBuilder'];
|
||||||
|
selectedGraph: GRAPH_TYPES;
|
||||||
|
}
|
||||||
|
|
||||||
function QueryBuilderQueryContainer({
|
function QueryBuilderQueryContainer({
|
||||||
queryData,
|
queryData,
|
||||||
updateQueryData,
|
updateQueryData,
|
||||||
metricsBuilderQueries,
|
metricsBuilderQueries,
|
||||||
selectedGraph,
|
selectedGraph,
|
||||||
}): JSX.Element | null {
|
}: IQueryBuilderQueryContainerProps): JSX.Element | null {
|
||||||
const handleQueryBuilderQueryChange = ({
|
const handleQueryBuilderQueryChange = ({
|
||||||
queryIndex,
|
queryIndex,
|
||||||
aggregateFunction,
|
aggregateFunction,
|
||||||
@ -33,7 +47,7 @@ function QueryBuilderQueryContainer({
|
|||||||
toggleDisable,
|
toggleDisable,
|
||||||
toggleDelete,
|
toggleDelete,
|
||||||
reduceTo,
|
reduceTo,
|
||||||
}): void => {
|
}: IQueryBuilderQueryHandleChange): void => {
|
||||||
const allQueries =
|
const allQueries =
|
||||||
queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME].queryBuilder;
|
queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME].queryBuilder;
|
||||||
const currentIndexQuery = allQueries[queryIndex];
|
const currentIndexQuery = allQueries[queryIndex];
|
||||||
@ -73,7 +87,7 @@ function QueryBuilderQueryContainer({
|
|||||||
expression,
|
expression,
|
||||||
toggleDisable,
|
toggleDisable,
|
||||||
toggleDelete,
|
toggleDelete,
|
||||||
}): void => {
|
}: IQueryBuilderFormulaHandleChange): void => {
|
||||||
const allFormulas =
|
const allFormulas =
|
||||||
queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME][
|
queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME][
|
||||||
WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME
|
WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME
|
||||||
@ -102,9 +116,9 @@ function QueryBuilderQueryContainer({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME].queryBuilder.push({
|
queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME].queryBuilder.push({
|
||||||
name: GetQueryName(
|
name:
|
||||||
queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME].queryBuilder,
|
GetQueryName(queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME].queryBuilder) ||
|
||||||
),
|
'',
|
||||||
...QueryBuilderQueryTemplate,
|
...QueryBuilderQueryTemplate,
|
||||||
});
|
});
|
||||||
updateQueryData({ updatedQuery: { ...queryData } });
|
updateQueryData({ updatedQuery: { ...queryData } });
|
||||||
@ -121,11 +135,12 @@ function QueryBuilderQueryContainer({
|
|||||||
queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME][
|
queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME][
|
||||||
WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME
|
WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME
|
||||||
].push({
|
].push({
|
||||||
name: GetFormulaName(
|
name:
|
||||||
|
GetFormulaName(
|
||||||
queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME][
|
queryData[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME][
|
||||||
WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME
|
WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME
|
||||||
],
|
],
|
||||||
),
|
) || '',
|
||||||
...QueryBuilderFormulaTemplate,
|
...QueryBuilderFormulaTemplate,
|
||||||
});
|
});
|
||||||
updateQueryData({ updatedQuery: { ...queryData } });
|
updateQueryData({ updatedQuery: { ...queryData } });
|
||||||
|
@ -2,28 +2,40 @@ import { AutoComplete, Col, Input, Row, Select, Spin } from 'antd';
|
|||||||
import { getMetricName } from 'api/metrics/getMetricName';
|
import { getMetricName } from 'api/metrics/getMetricName';
|
||||||
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { IMetricsBuilderQuery } from 'types/api/dashboard/getAll';
|
||||||
import { EReduceOperator } from 'types/common/dashboard';
|
import { EReduceOperator } from 'types/common/dashboard';
|
||||||
|
|
||||||
import { TQueryCategories } from '../../types';
|
|
||||||
import { AggregateFunctions } from '../Options';
|
import { AggregateFunctions } from '../Options';
|
||||||
import QueryHeader from '../QueryHeader';
|
import QueryHeader from '../QueryHeader';
|
||||||
import MetricTagKeyFilter from './MetricTagKeyFilter';
|
import MetricTagKeyFilter from './MetricTagKeyFilter';
|
||||||
|
import { IOption } from './MetricTagKeyFilter/types';
|
||||||
import { GetTagKeys } from './MetricTagKeyFilter/utils';
|
import { GetTagKeys } from './MetricTagKeyFilter/utils';
|
||||||
|
import { IQueryBuilderQueryHandleChange } from './types';
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
function MetricsBuilder({
|
|
||||||
queryData,
|
|
||||||
queryIndex,
|
|
||||||
handleQueryChange,
|
|
||||||
selectedGraph,
|
|
||||||
}: QueryBuilderProps): JSX.Element {
|
|
||||||
const [groupByOptions, setGroupByOptions] = useState([]);
|
|
||||||
const [metricName, setMetricName] = useState(queryData.metricName);
|
|
||||||
|
|
||||||
const [metricNameList, setMetricNameList] = useState([]);
|
interface IMetricsBuilderProps {
|
||||||
|
queryIndex: number;
|
||||||
|
selectedGraph: GRAPH_TYPES;
|
||||||
|
queryData: IMetricsBuilderQuery;
|
||||||
|
handleQueryChange: (args: IQueryBuilderQueryHandleChange) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function MetricsBuilder({
|
||||||
|
queryIndex,
|
||||||
|
selectedGraph,
|
||||||
|
queryData,
|
||||||
|
handleQueryChange,
|
||||||
|
}: IMetricsBuilderProps): JSX.Element {
|
||||||
|
const [groupByOptions, setGroupByOptions] = useState<IOption[]>([]);
|
||||||
|
const [metricName, setMetricName] = useState<string | null>(
|
||||||
|
queryData.metricName,
|
||||||
|
);
|
||||||
|
|
||||||
|
const [metricNameList, setMetricNameList] = useState<string[]>([]);
|
||||||
const [metricNameLoading, setMetricNameLoading] = useState(false);
|
const [metricNameLoading, setMetricNameLoading] = useState(false);
|
||||||
|
|
||||||
const handleMetricNameSelect = (e): void => {
|
const handleMetricNameSelect = (e: string): void => {
|
||||||
handleQueryChange({ queryIndex, metricName: e });
|
handleQueryChange({ queryIndex, metricName: e });
|
||||||
setMetricName(e);
|
setMetricName(e);
|
||||||
};
|
};
|
||||||
@ -51,7 +63,7 @@ function MetricsBuilder({
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
GetTagKeys(metricName).then((tagKeys) => {
|
GetTagKeys(metricName || '').then((tagKeys) => {
|
||||||
setGroupByOptions(tagKeys);
|
setGroupByOptions(tagKeys);
|
||||||
});
|
});
|
||||||
}, [metricName]);
|
}, [metricName]);
|
||||||
@ -120,7 +132,9 @@ function MetricsBuilder({
|
|||||||
<MetricTagKeyFilter
|
<MetricTagKeyFilter
|
||||||
metricName={metricName}
|
metricName={metricName}
|
||||||
selectedTagFilters={queryData.tagFilters.items}
|
selectedTagFilters={queryData.tagFilters.items}
|
||||||
onSetQuery={(updatedTagFilters): void =>
|
onSetQuery={(
|
||||||
|
updatedTagFilters: IMetricsBuilderQuery['tagFilters']['items'],
|
||||||
|
): void =>
|
||||||
handleQueryChange({ queryIndex, tagFilters: updatedTagFilters })
|
handleQueryChange({ queryIndex, tagFilters: updatedTagFilters })
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -166,9 +180,13 @@ function MetricsBuilder({
|
|||||||
.filter((op) => !(parseInt(op, 10) >= 0))
|
.filter((op) => !(parseInt(op, 10) >= 0))
|
||||||
.map((op) => ({
|
.map((op) => ({
|
||||||
label: op,
|
label: op,
|
||||||
value: EReduceOperator[op],
|
value: EReduceOperator[op as keyof typeof EReduceOperator],
|
||||||
}))}
|
}))}
|
||||||
defaultValue={EReduceOperator[queryData.reduceTo]}
|
defaultValue={
|
||||||
|
EReduceOperator[
|
||||||
|
(queryData.reduceTo as unknown) as keyof typeof EReduceOperator
|
||||||
|
]
|
||||||
|
}
|
||||||
onChange={(e): void => {
|
onChange={(e): void => {
|
||||||
handleQueryChange({ queryIndex, reduceTo: e });
|
handleQueryChange({ queryIndex, reduceTo: e });
|
||||||
}}
|
}}
|
||||||
@ -193,8 +211,4 @@ function MetricsBuilder({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface QueryBuilderProps {
|
|
||||||
selectedGraph: GRAPH_TYPES;
|
|
||||||
queryCategory: TQueryCategories;
|
|
||||||
}
|
|
||||||
export default MetricsBuilder;
|
export default MetricsBuilder;
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
import {
|
||||||
|
IMetricsBuilderFormula,
|
||||||
|
IMetricsBuilderQuery,
|
||||||
|
} from 'types/api/dashboard/getAll';
|
||||||
|
|
||||||
|
export interface IQueryBuilderQueryHandleChange {
|
||||||
|
queryIndex: number;
|
||||||
|
aggregateFunction?: IMetricsBuilderQuery['aggregateOperator'];
|
||||||
|
metricName?: IMetricsBuilderQuery['metricName'];
|
||||||
|
tagFilters?: IMetricsBuilderQuery['tagFilters']['items'];
|
||||||
|
groupBy?: IMetricsBuilderQuery['groupBy'];
|
||||||
|
legend?: IMetricsBuilderQuery['legend'];
|
||||||
|
toggleDisable?: boolean;
|
||||||
|
toggleDelete?: boolean;
|
||||||
|
reduceTo?: IMetricsBuilderQuery['reduceTo'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IQueryBuilderFormulaHandleChange {
|
||||||
|
formulaIndex: number;
|
||||||
|
expression?: IMetricsBuilderFormula['expression'];
|
||||||
|
toggleDisable?: IMetricsBuilderFormula['disabled'];
|
||||||
|
toggleDelete?: boolean;
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
import { Query } from 'types/api/dashboard/getAll';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME,
|
WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME,
|
||||||
WIDGET_QUERY_BUILDER_QUERY_KEY_NAME,
|
WIDGET_QUERY_BUILDER_QUERY_KEY_NAME,
|
||||||
@ -5,7 +7,7 @@ import {
|
|||||||
|
|
||||||
const QUERY_AND_FORMULA_LIMIT = 10;
|
const QUERY_AND_FORMULA_LIMIT = 10;
|
||||||
|
|
||||||
export const canCreateQueryAndFormula = (query): boolean => {
|
export const canCreateQueryAndFormula = (query: Query): boolean => {
|
||||||
const queries = query[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME].queryBuilder;
|
const queries = query[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME].queryBuilder;
|
||||||
const formulas =
|
const formulas =
|
||||||
query[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME][
|
query[WIDGET_QUERY_BUILDER_QUERY_KEY_NAME][
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
import { Tooltip } from 'antd';
|
import { Tooltip } from 'antd';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
function TabHeader({ tabName, hasUnstagedChanges }): JSX.Element {
|
interface ITabHeaderProps {
|
||||||
|
tabName: string;
|
||||||
|
hasUnstagedChanges: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
function TabHeader({
|
||||||
|
tabName,
|
||||||
|
hasUnstagedChanges,
|
||||||
|
}: ITabHeaderProps): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
@ -1,17 +1,21 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// @ts-ignore
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
import { EQueryType } from 'types/common/dashboard';
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
|
|
||||||
import { EQueryTypeToQueryKeyMapping } from './types';
|
import { EQueryTypeToQueryKeyMapping } from './types';
|
||||||
|
|
||||||
export const WIDGET_PROMQL_QUERY_KEY_NAME: string = EQueryTypeToQueryKeyMapping[
|
export const WIDGET_PROMQL_QUERY_KEY_NAME: EQueryTypeToQueryKeyMapping.PROM =
|
||||||
EQueryType[EQueryType.PROM]
|
EQueryTypeToQueryKeyMapping[EQueryType[EQueryType.PROM]];
|
||||||
] as string;
|
|
||||||
|
|
||||||
export const WIDGET_CLICKHOUSE_QUERY_KEY_NAME: string = EQueryTypeToQueryKeyMapping[
|
export const WIDGET_CLICKHOUSE_QUERY_KEY_NAME: EQueryTypeToQueryKeyMapping.CLICKHOUSE = EQueryTypeToQueryKeyMapping[
|
||||||
EQueryType[EQueryType.CLICKHOUSE]
|
EQueryType[EQueryType.CLICKHOUSE]
|
||||||
] as string;
|
] as string;
|
||||||
|
|
||||||
export const WIDGET_QUERY_BUILDER_QUERY_KEY_NAME: string = EQueryTypeToQueryKeyMapping[
|
export const WIDGET_QUERY_BUILDER_QUERY_KEY_NAME: EQueryTypeToQueryKeyMapping.QUERY_BUILDER = EQueryTypeToQueryKeyMapping[
|
||||||
EQueryType[EQueryType.QUERY_BUILDER]
|
EQueryType[EQueryType.QUERY_BUILDER]
|
||||||
] as string;
|
] as string;
|
||||||
|
|
||||||
export const WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME: string = 'formulas' as string;
|
type TFormulas = 'formulas';
|
||||||
|
export const WIDGET_QUERY_BUILDER_FORMULA_KEY_NAME: TFormulas = 'formulas';
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
//@ts-nocheck
|
||||||
|
|
||||||
import { Button, Tabs } from 'antd';
|
import { Button, Tabs } from 'antd';
|
||||||
import TextToolTip from 'components/TextToolTip';
|
import TextToolTip from 'components/TextToolTip';
|
||||||
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
||||||
@ -8,22 +11,13 @@ import { connect, useSelector } from 'react-redux';
|
|||||||
import { useLocation } from 'react-router-dom';
|
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 { CreateQuery, CreateQueryProps } from 'store/actions';
|
|
||||||
import {
|
|
||||||
GetQueryResults,
|
|
||||||
GetQueryResultsProps,
|
|
||||||
} from 'store/actions/dashboard/getQueryResults';
|
|
||||||
import {
|
import {
|
||||||
UpdateQuery,
|
UpdateQuery,
|
||||||
UpdateQueryProps,
|
UpdateQueryProps,
|
||||||
} from 'store/actions/dashboard/updateQuery';
|
} from 'store/actions/dashboard/updateQuery';
|
||||||
import {
|
|
||||||
UpdateQueryType,
|
|
||||||
UpdateQueryTypeProps,
|
|
||||||
} from 'store/actions/dashboard/updateQueryType';
|
|
||||||
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 { Query, Widgets } from 'types/api/dashboard/getAll';
|
||||||
import { EQueryType } from 'types/common/dashboard';
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
import DashboardReducer from 'types/reducer/dashboards';
|
import DashboardReducer from 'types/reducer/dashboards';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
@ -46,11 +40,13 @@ function QuerySection({
|
|||||||
updateQuery,
|
updateQuery,
|
||||||
selectedGraph,
|
selectedGraph,
|
||||||
}: QueryProps): JSX.Element {
|
}: QueryProps): JSX.Element {
|
||||||
const [localQueryChanges, setLocalQueryChanges] = useState({});
|
const [localQueryChanges, setLocalQueryChanges] = useState<Query>({} as Query);
|
||||||
const [rctTabKey, setRctTabKey] = useState({
|
const [rctTabKey, setRctTabKey] = useState<
|
||||||
|
Record<keyof typeof EQueryType, string>
|
||||||
|
>({
|
||||||
QUERY_BUILDER: uuid(),
|
QUERY_BUILDER: uuid(),
|
||||||
CLICKHOUSE: uuid(),
|
CLICKHOUSE: uuid(),
|
||||||
PROMQL: uuid(),
|
PROM: uuid(),
|
||||||
});
|
});
|
||||||
const { dashboards } = useSelector<AppState, DashboardReducer>(
|
const { dashboards } = useSelector<AppState, DashboardReducer>(
|
||||||
(state) => state.dashboards,
|
(state) => state.dashboards,
|
||||||
@ -73,104 +69,80 @@ function QuerySection({
|
|||||||
selectedWidget.query.queryType,
|
selectedWidget.query.queryType,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { query = [] } = selectedWidget || {};
|
const { query } = selectedWidget || {};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLocalQueryChanges(cloneDeep(query));
|
setLocalQueryChanges(cloneDeep(query) as Query);
|
||||||
}, [query]);
|
}, [query]);
|
||||||
const queryOnClickHandler = () => {
|
|
||||||
setLocalQueryChanges([
|
|
||||||
...localQueryChanges,
|
|
||||||
// {
|
|
||||||
// name: GetQueryName(localQueryChanges),
|
|
||||||
// disabled: false,
|
|
||||||
|
|
||||||
// promQL: {
|
|
||||||
// query: '',
|
|
||||||
// legend: '',
|
|
||||||
// },
|
|
||||||
// clickHouseQuery: '',
|
|
||||||
// queryBuilder: {
|
|
||||||
// metricName: null,
|
|
||||||
// aggregateOperator: null,
|
|
||||||
// tagFilters: {
|
|
||||||
// op: 'AND',
|
|
||||||
// items: [],
|
|
||||||
// },
|
|
||||||
// groupBy: [],
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const queryDiff = (queryA, queryB, queryCategory) => {
|
const queryDiff = (
|
||||||
|
queryA: Query,
|
||||||
|
queryB: Query,
|
||||||
|
queryCategory: EQueryType,
|
||||||
|
): boolean => {
|
||||||
const keyOfConcern = getQueryKey(queryCategory);
|
const keyOfConcern = getQueryKey(queryCategory);
|
||||||
return !isEqual(queryA[keyOfConcern], queryB[keyOfConcern]);
|
return !isEqual(queryA[keyOfConcern], queryB[keyOfConcern]);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
handleUnstagedChanges(
|
handleUnstagedChanges(
|
||||||
queryDiff(query, localQueryChanges, parseInt(queryCategory)),
|
queryDiff(query, localQueryChanges, parseInt(`${queryCategory}`, 10)),
|
||||||
);
|
);
|
||||||
}, [handleUnstagedChanges, localQueryChanges, query, queryCategory]);
|
}, [handleUnstagedChanges, localQueryChanges, query, queryCategory]);
|
||||||
|
|
||||||
const purgeLocalChanges = () => {
|
const regenRctKeys = (): void => {
|
||||||
setLocalQueryChanges(query);
|
|
||||||
};
|
|
||||||
const regenRctKeys = () => {
|
|
||||||
setRctTabKey((prevState) => {
|
setRctTabKey((prevState) => {
|
||||||
Object.keys(prevState).map((key) => {
|
const newState = prevState;
|
||||||
prevState[key] = uuid();
|
Object.keys(newState).forEach((key) => {
|
||||||
|
newState[key as keyof typeof EQueryType] = uuid();
|
||||||
});
|
});
|
||||||
|
|
||||||
return cloneDeep(prevState);
|
return cloneDeep(newState);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleStageQuery = () => {
|
const handleStageQuery = (): void => {
|
||||||
updateQuery({
|
updateQuery({
|
||||||
updatedQuery: localQueryChanges,
|
updatedQuery: localQueryChanges,
|
||||||
widgetId: urlQuery.get('widgetId'),
|
widgetId: urlQuery.get('widgetId') || '',
|
||||||
yAxisUnit: selectedWidget.yAxisUnit,
|
yAxisUnit: selectedWidget.yAxisUnit,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleQueryCategoryChange = (qCategory): void => {
|
const handleQueryCategoryChange = (qCategory: string): void => {
|
||||||
// If true, then it means that the user has made some changes and haven't staged them
|
// If true, then it means that the user has made some changes and haven't staged them
|
||||||
const unstagedChanges = queryDiff(
|
const unstagedChanges = queryDiff(
|
||||||
query,
|
query,
|
||||||
localQueryChanges,
|
localQueryChanges,
|
||||||
parseInt(queryCategory),
|
parseInt(`${queryCategory}`, 10),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (unstagedChanges && showUnstagedStashConfirmBox()) {
|
if (unstagedChanges && showUnstagedStashConfirmBox()) {
|
||||||
|
// eslint-disable-next-line no-alert
|
||||||
window.confirm(
|
window.confirm(
|
||||||
"You are trying to navigate to different tab with unstaged changes. Your current changes will be purged. Press 'Stage & Run Query' to stage them.",
|
"You are trying to navigate to different tab with unstaged changes. Your current changes will be purged. Press 'Stage & Run Query' to stage them.",
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setQueryCategory(parseInt(qCategory));
|
setQueryCategory(parseInt(`${qCategory}`, 10));
|
||||||
const newLocalQuery = {
|
const newLocalQuery = {
|
||||||
...cloneDeep(query),
|
...cloneDeep(query),
|
||||||
queryType: parseInt(qCategory),
|
queryType: parseInt(`${qCategory}`, 10),
|
||||||
};
|
};
|
||||||
setLocalQueryChanges(newLocalQuery);
|
setLocalQueryChanges(newLocalQuery);
|
||||||
regenRctKeys();
|
regenRctKeys();
|
||||||
updateQuery({
|
updateQuery({
|
||||||
updatedQuery: newLocalQuery,
|
updatedQuery: newLocalQuery,
|
||||||
widgetId: urlQuery.get('widgetId'),
|
widgetId: urlQuery.get('widgetId') || '',
|
||||||
yAxisUnit: selectedWidget.yAxisUnit,
|
yAxisUnit: selectedWidget.yAxisUnit,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const handleLocalQueryUpdate = ({ updatedQuery }) => {
|
|
||||||
setLocalQueryChanges(updatedQuery);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDeleteQuery = ({ currentIndex }) => {
|
const handleLocalQueryUpdate = ({
|
||||||
setLocalQueryChanges((prevState) => {
|
updatedQuery,
|
||||||
prevState.splice(currentIndex, 1);
|
}: IHandleUpdatedQuery): void => {
|
||||||
return [...prevState];
|
setLocalQueryChanges(updatedQuery);
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -211,7 +183,7 @@ function QuerySection({
|
|||||||
<QueryBuilderQueryContainer
|
<QueryBuilderQueryContainer
|
||||||
key={rctTabKey.QUERY_BUILDER}
|
key={rctTabKey.QUERY_BUILDER}
|
||||||
queryData={localQueryChanges}
|
queryData={localQueryChanges}
|
||||||
updateQueryData={({ updatedQuery }) => {
|
updateQueryData={({ updatedQuery }: IHandleUpdatedQuery): void => {
|
||||||
handleLocalQueryUpdate({ updatedQuery });
|
handleLocalQueryUpdate({ updatedQuery });
|
||||||
}}
|
}}
|
||||||
metricsBuilderQueries={
|
metricsBuilderQueries={
|
||||||
@ -236,7 +208,7 @@ function QuerySection({
|
|||||||
<ClickHouseQueryContainer
|
<ClickHouseQueryContainer
|
||||||
key={rctTabKey.CLICKHOUSE}
|
key={rctTabKey.CLICKHOUSE}
|
||||||
queryData={localQueryChanges}
|
queryData={localQueryChanges}
|
||||||
updateQueryData={({ updatedQuery }) => {
|
updateQueryData={({ updatedQuery }: IHandleUpdatedQuery): void => {
|
||||||
handleLocalQueryUpdate({ updatedQuery });
|
handleLocalQueryUpdate({ updatedQuery });
|
||||||
}}
|
}}
|
||||||
clickHouseQueries={localQueryChanges[WIDGET_CLICKHOUSE_QUERY_KEY_NAME]}
|
clickHouseQueries={localQueryChanges[WIDGET_CLICKHOUSE_QUERY_KEY_NAME]}
|
||||||
@ -256,9 +228,9 @@ function QuerySection({
|
|||||||
key={EQueryType.PROM.toString()}
|
key={EQueryType.PROM.toString()}
|
||||||
>
|
>
|
||||||
<PromQLQueryContainer
|
<PromQLQueryContainer
|
||||||
key={rctTabKey.PROMQL}
|
key={rctTabKey.PROM}
|
||||||
queryData={localQueryChanges}
|
queryData={localQueryChanges}
|
||||||
updateQueryData={({ updatedQuery }) => {
|
updateQueryData={({ updatedQuery }: IHandleUpdatedQuery): void => {
|
||||||
handleLocalQueryUpdate({ updatedQuery });
|
handleLocalQueryUpdate({ updatedQuery });
|
||||||
}}
|
}}
|
||||||
promQLQueries={localQueryChanges[WIDGET_PROMQL_QUERY_KEY_NAME]}
|
promQLQueries={localQueryChanges[WIDGET_PROMQL_QUERY_KEY_NAME]}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { Query } from 'types/api/dashboard/getAll';
|
||||||
|
|
||||||
export type TQueryCategories = 'query_builder' | 'clickhouse_query' | 'promql';
|
export type TQueryCategories = 'query_builder' | 'clickhouse_query' | 'promql';
|
||||||
|
|
||||||
export enum EQueryCategories {
|
export enum EQueryCategories {
|
||||||
@ -11,3 +13,7 @@ export enum EQueryTypeToQueryKeyMapping {
|
|||||||
CLICKHOUSE = 'clickHouse',
|
CLICKHOUSE = 'clickHouse',
|
||||||
PROM = 'promQL',
|
PROM = 'promQL',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IHandleUpdatedQuery {
|
||||||
|
updatedQuery: Query;
|
||||||
|
}
|
||||||
|
@ -2,6 +2,10 @@ import { EQueryType } from 'types/common/dashboard';
|
|||||||
|
|
||||||
import { EQueryTypeToQueryKeyMapping } from '../types';
|
import { EQueryTypeToQueryKeyMapping } from '../types';
|
||||||
|
|
||||||
export const getQueryKey = (queryCategory): EQueryTypeToQueryKeyMapping => {
|
export const getQueryKey = (
|
||||||
return EQueryTypeToQueryKeyMapping[EQueryType[queryCategory] as unknown];
|
queryCategory: EQueryType,
|
||||||
|
): EQueryTypeToQueryKeyMapping => {
|
||||||
|
return EQueryTypeToQueryKeyMapping[
|
||||||
|
EQueryType[queryCategory] as keyof typeof EQueryTypeToQueryKeyMapping
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
@ -4,7 +4,7 @@ import { EQueryType } from 'types/common/dashboard';
|
|||||||
import { Tag } from '../styles';
|
import { Tag } from '../styles';
|
||||||
|
|
||||||
interface IQueryTypeTagProps {
|
interface IQueryTypeTagProps {
|
||||||
queryType: EQueryType;
|
queryType: EQueryType | undefined;
|
||||||
}
|
}
|
||||||
function QueryTypeTag({ queryType }: IQueryTypeTagProps): JSX.Element {
|
function QueryTypeTag({ queryType }: IQueryTypeTagProps): JSX.Element {
|
||||||
switch (queryType) {
|
switch (queryType) {
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
|
|
||||||
import QueryTypeTag from '../QueryTypeTag';
|
import QueryTypeTag from '../QueryTypeTag';
|
||||||
|
|
||||||
function PlotTag({ queryType }): JSX.Element | null {
|
interface IPlotTagProps {
|
||||||
|
queryType: EQueryType;
|
||||||
|
}
|
||||||
|
|
||||||
|
function PlotTag({ queryType }: IPlotTagProps): JSX.Element | null {
|
||||||
if (queryType === undefined) {
|
if (queryType === undefined) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,7 @@ function WidgetGraph({
|
|||||||
</NotFoundContainer>
|
</NotFoundContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (queryData.data.queryData.length === 0) {
|
||||||
if (queryData.data.length === 0 || queryData.data[0].queryData.length === 0) {
|
|
||||||
return (
|
return (
|
||||||
<NotFoundContainer>
|
<NotFoundContainer>
|
||||||
<Typography>No Data</Typography>
|
<Typography>No Data</Typography>
|
||||||
@ -51,7 +50,7 @@ function WidgetGraph({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const chartDataSet = getChartData({
|
const chartDataSet = getChartData({
|
||||||
queryData: queryData.data,
|
queryData: [queryData.data],
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -136,9 +136,9 @@ function NewWidget({
|
|||||||
}, [dashboardId, dispatch]);
|
}, [dashboardId, dispatch]);
|
||||||
|
|
||||||
const getQueryResult = useCallback(() => {
|
const getQueryResult = useCallback(() => {
|
||||||
if (selectedWidget?.id.length !== 0) {
|
if (selectedWidget?.id.length !== 0 && selectedWidget?.query) {
|
||||||
getQueryResults({
|
getQueryResults({
|
||||||
query: selectedWidget?.query || [],
|
query: selectedWidget?.query,
|
||||||
selectedTime: selectedTime.enum,
|
selectedTime: selectedTime.enum,
|
||||||
widgetId: selectedWidget?.id || '',
|
widgetId: selectedWidget?.id || '',
|
||||||
graphType: selectedGraph,
|
graphType: selectedGraph,
|
||||||
|
@ -6,14 +6,14 @@ import convertIntoEpoc from './covertIntoEpoc';
|
|||||||
import { colors } from './getRandomColor';
|
import { colors } from './getRandomColor';
|
||||||
|
|
||||||
const getChartData = ({ queryData }: GetChartDataProps): ChartData => {
|
const getChartData = ({ queryData }: GetChartDataProps): ChartData => {
|
||||||
const response = queryData.map(({ queryData }) => {
|
const response = queryData.map(
|
||||||
|
({ queryData, query: queryG, legend: legendG }) => {
|
||||||
return queryData.map((e) => {
|
return queryData.map((e) => {
|
||||||
const { values = [], metric, legend, queryName } = e || {};
|
const { values = [], metric, legend, queryName } = e || {};
|
||||||
|
|
||||||
const labelNames = getLabelName(
|
const labelNames = getLabelName(
|
||||||
metric,
|
metric,
|
||||||
queryName || '', // query
|
queryName || queryG || '', // query
|
||||||
legend || '',
|
legend || legendG || '',
|
||||||
);
|
);
|
||||||
const dataValue = values?.map((e) => {
|
const dataValue = values?.map((e) => {
|
||||||
const [first = 0, second = ''] = e || [];
|
const [first = 0, second = ''] = e || [];
|
||||||
@ -29,7 +29,8 @@ const getChartData = ({ queryData }: GetChartDataProps): ChartData => {
|
|||||||
second: dataValue.map((e) => e.second),
|
second: dataValue.map((e) => e.second),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
});
|
},
|
||||||
|
);
|
||||||
const allLabels = response
|
const allLabels = response
|
||||||
.map((e) => e.map((e) => e.label))
|
.map((e) => e.map((e) => e.label))
|
||||||
.reduce((a, b) => [...a, ...b], []);
|
.reduce((a, b) => [...a, ...b], []);
|
||||||
@ -58,7 +59,7 @@ const getChartData = ({ queryData }: GetChartDataProps): ChartData => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
interface GetChartDataProps {
|
interface GetChartDataProps {
|
||||||
queryData: Widgets['queryData']['data'];
|
queryData: Widgets['queryData']['data'][];
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getChartData;
|
export default getChartData;
|
||||||
|
@ -2,13 +2,16 @@ import { sortBy } from 'lodash-es';
|
|||||||
|
|
||||||
const MAX_QUERIES = 20;
|
const MAX_QUERIES = 20;
|
||||||
|
|
||||||
function GetFormulaName(formulas = []): string | null {
|
function GetFormulaName(
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
formulas: { name: string; [key: string]: any }[] = [],
|
||||||
|
): string | null {
|
||||||
if (!formulas.length) return 'F1';
|
if (!formulas.length) return 'F1';
|
||||||
if (formulas.length === MAX_QUERIES) {
|
if (formulas.length === MAX_QUERIES) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const formulasNameNumbered = sortBy(
|
const formulasNameNumbered = sortBy(
|
||||||
formulas.map(({ name }) => {
|
formulas.map(({ name }: { name: string }) => {
|
||||||
return parseInt(name.slice(1), 10);
|
return parseInt(name.slice(1), 10);
|
||||||
}),
|
}),
|
||||||
(e) => e,
|
(e) => e,
|
||||||
@ -22,6 +25,7 @@ function GetFormulaName(formulas = []): string | null {
|
|||||||
}
|
}
|
||||||
// formulaIteratorIdx += 1;
|
// formulaIteratorIdx += 1;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default GetFormulaName;
|
export default GetFormulaName;
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
import { sortBy } from 'lodash-es';
|
import { sortBy } from 'lodash-es';
|
||||||
|
|
||||||
const MAX_QUERIES = 26;
|
const MAX_QUERIES = 26;
|
||||||
function GetQueryName(queries = []): string | null {
|
function GetQueryName(queries: { name: string }[] = []): string | null {
|
||||||
if (!queries.length) return 'A';
|
if (!queries.length) return 'A';
|
||||||
if (queries.length === MAX_QUERIES) {
|
if (queries.length === MAX_QUERIES) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const sortedQueries = sortBy(queries, function (q) {
|
const sortedQueries = sortBy(queries, (q) => {
|
||||||
return q.name;
|
return q.name;
|
||||||
});
|
});
|
||||||
|
|
||||||
let query_iterator_idx = 0;
|
let queryIteratorIdx = 0;
|
||||||
|
|
||||||
for (
|
for (
|
||||||
let charItr = 'A'.charCodeAt(0);
|
let charItr = 'A'.charCodeAt(0);
|
||||||
charItr <= 'A'.charCodeAt(0) + MAX_QUERIES;
|
charItr <= 'A'.charCodeAt(0) + MAX_QUERIES;
|
||||||
charItr += 1
|
charItr += 1
|
||||||
) {
|
) {
|
||||||
if (charItr !== sortedQueries[query_iterator_idx]?.name.charCodeAt(0)) {
|
if (charItr !== sortedQueries[queryIteratorIdx]?.name.charCodeAt(0)) {
|
||||||
return String.fromCharCode(charItr);
|
return String.fromCharCode(charItr);
|
||||||
}
|
}
|
||||||
query_iterator_idx += 1;
|
queryIteratorIdx += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
import { Dispatch } from 'redux';
|
|
||||||
import AppActions from 'types/actions';
|
|
||||||
|
|
||||||
export const CreateQuery = ({ widgetId }: CreateQueryProps) => (
|
|
||||||
dispatch: Dispatch<AppActions>,
|
|
||||||
): void => {
|
|
||||||
dispatch({
|
|
||||||
type: 'CREATE_NEW_QUERY',
|
|
||||||
payload: {
|
|
||||||
widgetId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface CreateQueryProps {
|
|
||||||
widgetId: string;
|
|
||||||
}
|
|
@ -46,11 +46,10 @@ export const GetDashboard = ({
|
|||||||
title: '',
|
title: '',
|
||||||
queryType: 0,
|
queryType: 0,
|
||||||
queryData: {
|
queryData: {
|
||||||
data: [
|
data: {
|
||||||
{
|
|
||||||
queryData: [],
|
queryData: [],
|
||||||
},
|
},
|
||||||
],
|
|
||||||
error: false,
|
error: false,
|
||||||
errorMessage: '',
|
errorMessage: '',
|
||||||
loading: false,
|
loading: false,
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// @ts-ignore
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
import { getMetricsQueryRange } from 'api/metrics/getQueryRange';
|
import { getMetricsQueryRange } from 'api/metrics/getQueryRange';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
||||||
@ -36,6 +40,7 @@ export async function GetMetricQueryRange({
|
|||||||
EQueryTypeToQueryKeyMapping[EQueryType[query.queryType]];
|
EQueryTypeToQueryKeyMapping[EQueryType[query.queryType]];
|
||||||
const queryData = query[queryKey];
|
const queryData = query[queryKey];
|
||||||
const legendMap: Record<string, string> = {};
|
const legendMap: Record<string, string> = {};
|
||||||
|
|
||||||
const QueryPayload = {
|
const QueryPayload = {
|
||||||
dataSource: EDataSource.METRICS,
|
dataSource: EDataSource.METRICS,
|
||||||
compositeMetricQuery: {
|
compositeMetricQuery: {
|
||||||
@ -175,12 +180,6 @@ export const GetQueryResults = (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// const data = response.map((e) => ({
|
|
||||||
// query: e.query,
|
|
||||||
// legend: e.legend || '',
|
|
||||||
// queryData: e.queryData.payload?.result || [],
|
|
||||||
// }));
|
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'QUERY_SUCCESS',
|
type: 'QUERY_SUCCESS',
|
||||||
payload: {
|
payload: {
|
||||||
@ -216,7 +215,7 @@ export const GetQueryResults = (
|
|||||||
export interface GetQueryResultsProps {
|
export interface GetQueryResultsProps {
|
||||||
widgetId: string;
|
widgetId: string;
|
||||||
selectedTime: timePreferenceType;
|
selectedTime: timePreferenceType;
|
||||||
query: Query[];
|
query: Query;
|
||||||
graphType: ITEMS;
|
graphType: ITEMS;
|
||||||
globalSelectedInterval: GlobalReducer['selectedTime'];
|
globalSelectedInterval: GlobalReducer['selectedTime'];
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
export * from './applySettingsToPanel';
|
export * from './applySettingsToPanel';
|
||||||
export * from './createQuery';
|
|
||||||
export * from './deleteDashboard';
|
export * from './deleteDashboard';
|
||||||
export * from './deleteQuery';
|
export * from './deleteQuery';
|
||||||
export * from './getAllDashboard';
|
export * from './getAllDashboard';
|
||||||
|
@ -82,7 +82,6 @@ export const SaveDashboard = ({
|
|||||||
...allLayout.slice(emptyLayoutIndex + 1, allLayout.length),
|
...allLayout.slice(emptyLayoutIndex + 1, allLayout.length),
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
const allLayout = getAllLayout();
|
const allLayout = getAllLayout();
|
||||||
const response = await updateDashboardApi({
|
const response = await updateDashboardApi({
|
||||||
data: {
|
data: {
|
||||||
@ -109,12 +108,6 @@ export const SaveDashboard = ({
|
|||||||
panelTypes: search.get('graphType') as Widgets['panelTypes'],
|
panelTypes: search.get('graphType') as Widgets['panelTypes'],
|
||||||
queryData: {
|
queryData: {
|
||||||
...selectedWidget.queryData,
|
...selectedWidget.queryData,
|
||||||
data: [
|
|
||||||
...selectedWidget.queryData.data.map((e) => ({
|
|
||||||
...e,
|
|
||||||
queryData: [],
|
|
||||||
})),
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
...afterWidget,
|
...afterWidget,
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
import { Dispatch } from 'redux';
|
|
||||||
import AppActions from 'types/actions';
|
|
||||||
|
|
||||||
export const UpdateQueryType = (
|
|
||||||
props: UpdateQueryTypeProps,
|
|
||||||
): ((dispatch: Dispatch<AppActions>) => void) => {
|
|
||||||
return (dispatch: Dispatch<AppActions>): void => {
|
|
||||||
dispatch({
|
|
||||||
type: 'UPDATE_QUERY_TYPE',
|
|
||||||
payload: {
|
|
||||||
queryType: props.queryType,
|
|
||||||
widgetId: props.widgetId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface UpdateQueryTypeProps {
|
|
||||||
widgetId: string;
|
|
||||||
queryType: number;
|
|
||||||
}
|
|
@ -19,7 +19,6 @@ import {
|
|||||||
TOGGLE_EDIT_MODE,
|
TOGGLE_EDIT_MODE,
|
||||||
UPDATE_DASHBOARD,
|
UPDATE_DASHBOARD,
|
||||||
UPDATE_QUERY,
|
UPDATE_QUERY,
|
||||||
UPDATE_QUERY_TYPE,
|
|
||||||
UPDATE_TITLE_DESCRIPTION_TAGS_SUCCESS,
|
UPDATE_TITLE_DESCRIPTION_TAGS_SUCCESS,
|
||||||
} from 'types/actions/dashboard';
|
} from 'types/actions/dashboard';
|
||||||
import InitialValueTypes from 'types/reducer/dashboards';
|
import InitialValueTypes from 'types/reducer/dashboards';
|
||||||
@ -216,6 +215,7 @@ const dashboard = (
|
|||||||
|
|
||||||
case QUERY_SUCCESS: {
|
case QUERY_SUCCESS: {
|
||||||
const { widgetId, data: queryDataResponse } = action.payload;
|
const { widgetId, data: queryDataResponse } = action.payload;
|
||||||
|
|
||||||
const { dashboards } = state;
|
const { dashboards } = state;
|
||||||
const [selectedDashboard] = dashboards;
|
const [selectedDashboard] = dashboards;
|
||||||
const { data } = selectedDashboard;
|
const { data } = selectedDashboard;
|
||||||
@ -243,7 +243,7 @@ const dashboard = (
|
|||||||
{
|
{
|
||||||
...selectedWidget,
|
...selectedWidget,
|
||||||
queryData: {
|
queryData: {
|
||||||
data: [queryDataResponse],
|
data: queryDataResponse,
|
||||||
error: selectedWidget.queryData.error,
|
error: selectedWidget.queryData.error,
|
||||||
errorMessage: selectedWidget.queryData.errorMessage,
|
errorMessage: selectedWidget.queryData.errorMessage,
|
||||||
loading: false,
|
loading: false,
|
||||||
@ -397,88 +397,6 @@ const dashboard = (
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case UPDATE_QUERY_TYPE: {
|
|
||||||
const { widgetId, queryType } = action.payload;
|
|
||||||
const { dashboards } = state;
|
|
||||||
const [selectedDashboard] = dashboards;
|
|
||||||
const { data } = selectedDashboard;
|
|
||||||
const { widgets = [] } = data;
|
|
||||||
|
|
||||||
const selectedWidgetIndex = widgets.findIndex((e) => e.id === widgetId) || 0;
|
|
||||||
|
|
||||||
const preWidget = widgets?.slice(0, selectedWidgetIndex) || [];
|
|
||||||
const afterWidget =
|
|
||||||
widgets?.slice(
|
|
||||||
selectedWidgetIndex + 1, // this is never undefined
|
|
||||||
widgets.length,
|
|
||||||
) || [];
|
|
||||||
|
|
||||||
const selectedWidget = widgets[selectedWidgetIndex];
|
|
||||||
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
dashboards: [
|
|
||||||
{
|
|
||||||
...selectedDashboard,
|
|
||||||
data: {
|
|
||||||
...data,
|
|
||||||
widgets: [
|
|
||||||
...preWidget,
|
|
||||||
{
|
|
||||||
...selectedWidget,
|
|
||||||
queryType,
|
|
||||||
},
|
|
||||||
...afterWidget,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// case DELETE_QUERY: {
|
|
||||||
// const { currentIndex, widgetId } = action.payload;
|
|
||||||
// const { dashboards } = state;
|
|
||||||
// const [selectedDashboard] = dashboards;
|
|
||||||
// const { data } = selectedDashboard;
|
|
||||||
// const { widgets = [] } = data;
|
|
||||||
|
|
||||||
// const selectedWidgetIndex = widgets.findIndex((e) => e.id === widgetId) || 0;
|
|
||||||
|
|
||||||
// const preWidget = widgets?.slice(0, selectedWidgetIndex) || [];
|
|
||||||
// const afterWidget =
|
|
||||||
// widgets?.slice(
|
|
||||||
// selectedWidgetIndex + 1, // this is never undefined
|
|
||||||
// widgets.length,
|
|
||||||
// ) || [];
|
|
||||||
|
|
||||||
// const selectedWidget = widgets[selectedWidgetIndex];
|
|
||||||
|
|
||||||
// const { query } = selectedWidget;
|
|
||||||
|
|
||||||
// const preQuery = query.slice(0, currentIndex);
|
|
||||||
// const postQuery = query.slice(currentIndex + 1, query.length);
|
|
||||||
|
|
||||||
// return {
|
|
||||||
// ...state,
|
|
||||||
// dashboards: [
|
|
||||||
// {
|
|
||||||
// ...selectedDashboard,
|
|
||||||
// data: {
|
|
||||||
// ...data,
|
|
||||||
// widgets: [
|
|
||||||
// ...preWidget,
|
|
||||||
// {
|
|
||||||
// ...selectedWidget,
|
|
||||||
// query: [...preQuery, ...postQuery],
|
|
||||||
// },
|
|
||||||
// ...afterWidget,
|
|
||||||
// ],
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
|
@ -41,7 +41,6 @@ export const DELETE_WIDGET_ERROR = 'DELETE_WIDGET_ERROR';
|
|||||||
export const IS_ADD_WIDGET = 'IS_ADD_WIDGET';
|
export const IS_ADD_WIDGET = 'IS_ADD_WIDGET';
|
||||||
|
|
||||||
export const DELETE_QUERY = 'DELETE_QUERY';
|
export const DELETE_QUERY = 'DELETE_QUERY';
|
||||||
export const UPDATE_QUERY_TYPE = 'UPDATE_QUERY_TYPE';
|
|
||||||
export const FLUSH_DASHBOARD = 'FLUSH_DASHBOARD';
|
export const FLUSH_DASHBOARD = 'FLUSH_DASHBOARD';
|
||||||
interface GetDashboard {
|
interface GetDashboard {
|
||||||
type: typeof GET_DASHBOARD;
|
type: typeof GET_DASHBOARD;
|
||||||
@ -124,7 +123,7 @@ export interface QuerySuccessPayload {
|
|||||||
// legend: string;
|
// legend: string;
|
||||||
queryData: QueryData[];
|
queryData: QueryData[];
|
||||||
// query: string
|
// query: string
|
||||||
}[];
|
};
|
||||||
}
|
}
|
||||||
interface QuerySuccess {
|
interface QuerySuccess {
|
||||||
type: typeof QUERY_SUCCESS;
|
type: typeof QUERY_SUCCESS;
|
||||||
@ -172,14 +171,6 @@ interface DeleteQuery {
|
|||||||
payload: DeleteQueryProps;
|
payload: DeleteQueryProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UpdateQueryType {
|
|
||||||
type: typeof UPDATE_QUERY_TYPE;
|
|
||||||
payload: {
|
|
||||||
queryType: number;
|
|
||||||
widgetId: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
interface FlushDashboard {
|
interface FlushDashboard {
|
||||||
type: typeof FLUSH_DASHBOARD;
|
type: typeof FLUSH_DASHBOARD;
|
||||||
}
|
}
|
||||||
@ -203,5 +194,4 @@ export type DashboardActions =
|
|||||||
| IsAddWidget
|
| IsAddWidget
|
||||||
| UpdateQuery
|
| UpdateQuery
|
||||||
| DeleteQuery
|
| DeleteQuery
|
||||||
| UpdateQueryType
|
|
||||||
| FlushDashboard;
|
| FlushDashboard;
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
|
||||||
import { timePreferenceType } from 'container/NewWidget/RightContainer/timeItems';
|
import { timePreferenceType } from 'container/NewWidget/RightContainer/timeItems';
|
||||||
import { Layout } from 'react-grid-layout';
|
import { Layout } from 'react-grid-layout';
|
||||||
import { EAggregateOperator, EQueryType } from 'types/common/dashboard';
|
import {
|
||||||
|
EAggregateOperator,
|
||||||
|
EQueryType,
|
||||||
|
EReduceOperator,
|
||||||
|
} from 'types/common/dashboard';
|
||||||
|
|
||||||
import { QueryData } from '../widgets/getQuery';
|
import { QueryData } from '../widgets/getQuery';
|
||||||
|
|
||||||
@ -38,10 +42,10 @@ export interface IBaseWidget {
|
|||||||
error: boolean;
|
error: boolean;
|
||||||
errorMessage: string;
|
errorMessage: string;
|
||||||
data: {
|
data: {
|
||||||
// legend?: string;
|
query?: string;
|
||||||
|
legend?: string;
|
||||||
queryData: QueryData[];
|
queryData: QueryData[];
|
||||||
// query: string;
|
};
|
||||||
}[];
|
|
||||||
};
|
};
|
||||||
stepSize?: number;
|
stepSize?: number;
|
||||||
yAxisUnit?: string;
|
yAxisUnit?: string;
|
||||||
@ -74,8 +78,9 @@ export interface IMetricsBuilderQuery {
|
|||||||
name: string;
|
name: string;
|
||||||
legend: string;
|
legend: string;
|
||||||
metricName: string | null;
|
metricName: string | null;
|
||||||
groupBy: string[];
|
groupBy?: string[];
|
||||||
tagFilters: IQueryBuilderTagFilters;
|
tagFilters: IQueryBuilderTagFilters;
|
||||||
|
reduceTo?: EReduceOperator;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IQueryBuilderTagFilters {
|
export interface IQueryBuilderTagFilters {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { QueryData } from '../widgets/getQuery';
|
import { QueryData } from '../widgets/getQuery';
|
||||||
|
|
||||||
export type MetricsRangeProps = any;
|
export type MetricsRangeProps = never;
|
||||||
export interface MetricRangePayloadProps {
|
export interface MetricRangePayloadProps {
|
||||||
data: {
|
data: {
|
||||||
result: QueryData[];
|
result: QueryData[];
|
||||||
|
@ -9,6 +9,7 @@ export interface QueryData {
|
|||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
};
|
};
|
||||||
queryName: string;
|
queryName: string;
|
||||||
|
legend?: string;
|
||||||
values: [number, string][];
|
values: [number, string][];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user