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} > )} - + ); } }