diff --git a/public/app/plugins/datasource/cloud-monitoring/components/AnnotationQueryEditor.tsx b/public/app/plugins/datasource/cloud-monitoring/components/AnnotationQueryEditor.tsx
index 806bac92516..76fa6c02b4e 100644
--- a/public/app/plugins/datasource/cloud-monitoring/components/AnnotationQueryEditor.tsx
+++ b/public/app/plugins/datasource/cloud-monitoring/components/AnnotationQueryEditor.tsx
@@ -2,6 +2,7 @@ import React, { useState } from 'react';
import { useDebounce } from 'react-use';
import { QueryEditorProps, toOption } from '@grafana/data';
+import { config } from '@grafana/runtime';
import { Input } from '@grafana/ui';
import { INPUT_WIDTH } from '../constants';
@@ -15,6 +16,7 @@ import {
AlignmentTypes,
} from '../types';
+import { MetricQueryEditor as ExperimentalMetricQueryEditor } from './Experimental/MetricQueryEditor';
import { MetricQueryEditor } from './MetricQueryEditor';
import { AnnotationsHelp, QueryEditorRow } from './';
@@ -78,15 +80,27 @@ export const AnnotationQueryEditor = (props: Props) => {
return (
<>
-
+ {config.featureToggles.cloudMonitoringExperimentalUI ? (
+
+ ) : (
+
+ )}
diff --git a/public/app/plugins/datasource/cloud-monitoring/components/Experimental/AliasBy.tsx b/public/app/plugins/datasource/cloud-monitoring/components/Experimental/AliasBy.tsx
new file mode 100644
index 00000000000..85c54b5e1ee
--- /dev/null
+++ b/public/app/plugins/datasource/cloud-monitoring/components/Experimental/AliasBy.tsx
@@ -0,0 +1,32 @@
+import { debounce } from 'lodash';
+import React, { FunctionComponent, useState } from 'react';
+
+import { EditorRow, EditorField } from '@grafana/experimental';
+import { Input } from '@grafana/ui';
+
+import { SELECT_WIDTH } from '../../constants';
+
+export interface Props {
+ refId: string;
+ onChange: (alias: any) => void;
+ value?: string;
+}
+
+export const AliasBy: FunctionComponent = ({ refId, value = '', onChange }) => {
+ const [alias, setAlias] = useState(value ?? '');
+
+ const propagateOnChange = debounce(onChange, 1000);
+
+ onChange = (e: any) => {
+ setAlias(e.target.value);
+ propagateOnChange(e.target.value);
+ };
+
+ return (
+
+
+
+
+
+ );
+};
diff --git a/public/app/plugins/datasource/cloud-monitoring/components/Experimental/MetricQueryEditor.tsx b/public/app/plugins/datasource/cloud-monitoring/components/Experimental/MetricQueryEditor.tsx
new file mode 100644
index 00000000000..4f555ef6670
--- /dev/null
+++ b/public/app/plugins/datasource/cloud-monitoring/components/Experimental/MetricQueryEditor.tsx
@@ -0,0 +1,159 @@
+import React, { useCallback, useEffect, useState } from 'react';
+
+import { SelectableValue } from '@grafana/data';
+import { EditorRows } from '@grafana/experimental';
+
+import CloudMonitoringDatasource from '../../datasource';
+import { getAlignmentPickerData } from '../../functions';
+import {
+ AlignmentTypes,
+ CustomMetaData,
+ EditorMode,
+ MetricDescriptor,
+ MetricKind,
+ MetricQuery,
+ PreprocessorType,
+ SLOQuery,
+ ValueTypes,
+} from '../../types';
+import { Project, VisualMetricQueryEditor } from '../index';
+
+import { GraphPeriod } from './../GraphPeriod';
+import { MQLQueryEditor } from './../MQLQueryEditor';
+import { AliasBy } from './AliasBy';
+
+export interface Props {
+ refId: string;
+ customMetaData: CustomMetaData;
+ variableOptionGroup: SelectableValue;
+ onChange: (query: MetricQuery) => void;
+ onRunQuery: () => void;
+ query: MetricQuery;
+ datasource: CloudMonitoringDatasource;
+}
+
+interface State {
+ labels: any;
+ [key: string]: any;
+}
+
+export const defaultState: State = {
+ labels: {},
+};
+
+export const defaultQuery: (dataSource: CloudMonitoringDatasource) => MetricQuery = (dataSource) => ({
+ editorMode: EditorMode.Visual,
+ projectName: dataSource.getDefaultProject(),
+ metricType: '',
+ metricKind: MetricKind.GAUGE,
+ valueType: '',
+ crossSeriesReducer: 'REDUCE_MEAN',
+ alignmentPeriod: 'cloud-monitoring-auto',
+ perSeriesAligner: AlignmentTypes.ALIGN_MEAN,
+ groupBys: [],
+ filters: [],
+ aliasBy: '',
+ query: '',
+ preprocessor: PreprocessorType.None,
+});
+
+function Editor({
+ refId,
+ query,
+ datasource,
+ onChange: onQueryChange,
+ onRunQuery,
+ customMetaData,
+ variableOptionGroup,
+}: React.PropsWithChildren) {
+ const [state, setState] = useState(defaultState);
+ const { projectName, metricType, groupBys, editorMode, crossSeriesReducer } = query;
+
+ useEffect(() => {
+ if (projectName && metricType) {
+ datasource
+ .getLabels(metricType, refId, projectName)
+ .then((labels) => setState((prevState) => ({ ...prevState, labels })));
+ }
+ }, [datasource, groupBys, metricType, projectName, refId, crossSeriesReducer]);
+
+ const onChange = useCallback(
+ (metricQuery: MetricQuery | SLOQuery) => {
+ onQueryChange({ ...query, ...metricQuery });
+ onRunQuery();
+ },
+ [onQueryChange, onRunQuery, query]
+ );
+
+ const onMetricTypeChange = useCallback(
+ ({ valueType, metricKind, type }: MetricDescriptor) => {
+ const preprocessor =
+ metricKind === MetricKind.GAUGE || valueType === ValueTypes.DISTRIBUTION
+ ? PreprocessorType.None
+ : PreprocessorType.Rate;
+ const { perSeriesAligner } = getAlignmentPickerData(valueType, metricKind, state.perSeriesAligner, preprocessor);
+ onChange({
+ ...query,
+ perSeriesAligner,
+ metricType: type,
+ valueType,
+ metricKind,
+ preprocessor,
+ });
+ },
+ [onChange, query, state]
+ );
+
+ return (
+
+ {
+ onChange({ ...query, projectName });
+ }}
+ />
+
+ {editorMode === EditorMode.Visual && (
+
+ )}
+
+ {editorMode === EditorMode.MQL && (
+ <>
+ onQueryChange({ ...query, query: q })}
+ onRunQuery={onRunQuery}
+ query={query.query}
+ >
+ onQueryChange({ ...query, graphPeriod })}
+ graphPeriod={query.graphPeriod}
+ refId={refId}
+ variableOptionGroup={variableOptionGroup}
+ />
+ >
+ )}
+
+ {
+ onChange({ ...query, aliasBy });
+ }}
+ />
+
+ );
+}
+
+export const MetricQueryEditor = React.memo(Editor);
diff --git a/public/app/plugins/datasource/cloud-monitoring/components/QueryEditor.tsx b/public/app/plugins/datasource/cloud-monitoring/components/QueryEditor.tsx
index 7dd2a810087..62fe9c3748f 100644
--- a/public/app/plugins/datasource/cloud-monitoring/components/QueryEditor.tsx
+++ b/public/app/plugins/datasource/cloud-monitoring/components/QueryEditor.tsx
@@ -2,12 +2,15 @@ import { css } from '@emotion/css';
import React, { PureComponent } from 'react';
import { QueryEditorProps, toOption } from '@grafana/data';
+import { EditorRows } from '@grafana/experimental';
+import { config } from '@grafana/runtime';
import { Button, Select } from '@grafana/ui';
import { QUERY_TYPES, SELECT_WIDTH } from '../constants';
import CloudMonitoringDatasource from '../datasource';
import { CloudMonitoringQuery, EditorMode, MetricQuery, QueryType, SLOQuery, CloudMonitoringOptions } from '../types';
+import { MetricQueryEditor as ExperimentalMetricQueryEditor } from './Experimental/MetricQueryEditor';
import { defaultQuery } from './MetricQueryEditor';
import { defaultQuery as defaultSLOQuery } from './SLO/SLOQueryEditor';
@@ -55,7 +58,7 @@ export class QueryEditor extends PureComponent {
};
return (
- <>
+
{
/>
- {queryType === QueryType.METRICS && (
- {
- this.props.onChange({ ...this.props.query, metricQuery });
- }}
- onRunQuery={onRunQuery}
- datasource={datasource}
- query={metricQuery}
- >
- )}
+ {queryType === QueryType.METRICS &&
+ (config.featureToggles.cloudMonitoringExperimentalUI ? (
+ {
+ this.props.onChange({ ...this.props.query, metricQuery });
+ }}
+ onRunQuery={onRunQuery}
+ datasource={datasource}
+ query={metricQuery}
+ />
+ ) : (
+ {
+ this.props.onChange({ ...this.props.query, metricQuery });
+ }}
+ onRunQuery={onRunQuery}
+ datasource={datasource}
+ query={metricQuery}
+ />
+ ))}
{queryType === QueryType.SLO && (
{
query={sloQuery}
>
)}
- >
+
);
}
}