import React, { ChangeEvent, PureComponent } from 'react'; import { QueryEditorProps } from '@grafana/data'; import { EditorField, EditorRow, Space } from '@grafana/experimental'; import { Input } from '@grafana/ui'; import { CloudWatchDatasource } from '../datasource'; import { isMetricsQuery } from '../guards'; import { CloudWatchJsonData, CloudWatchMetricsQuery, CloudWatchQuery, MetricEditorMode, MetricQueryType, } from '../types'; import { Alias, MathExpressionQueryField, MetricStatEditor, SQLBuilderEditor, SQLCodeEditor } from './'; import QueryHeader from './QueryHeader'; export type Props = QueryEditorProps; interface State { sqlCodeEditorIsDirty: boolean; } export const normalizeQuery = ({ namespace, metricName, expression, dimensions, region, id, alias, statistic, period, sqlExpression, metricQueryType, metricEditorMode, ...rest }: CloudWatchMetricsQuery): CloudWatchMetricsQuery => { const normalizedQuery = { queryMode: 'Metrics' as const, namespace: namespace ?? '', metricName: metricName ?? '', expression: expression ?? '', dimensions: dimensions ?? {}, region: region ?? 'default', id: id ?? '', alias: alias ?? '', statistic: statistic ?? 'Average', period: period ?? '', metricQueryType: metricQueryType ?? MetricQueryType.Search, metricEditorMode: metricEditorMode ?? MetricEditorMode.Builder, sqlExpression: sqlExpression ?? '', ...rest, }; return !rest.hasOwnProperty('matchExact') ? { ...normalizedQuery, matchExact: true } : normalizedQuery; }; export class MetricsQueryEditor extends PureComponent { state = { sqlCodeEditorIsDirty: false, }; componentDidMount = () => { const metricsQuery = this.props.query as CloudWatchMetricsQuery; const query = normalizeQuery(metricsQuery); this.props.onChange(query); }; onChange = (query: CloudWatchQuery) => { const { onChange, onRunQuery } = this.props; onChange(query); onRunQuery(); }; render() { const { onRunQuery, datasource } = this.props; const metricsQuery = this.props.query as CloudWatchMetricsQuery; const query = normalizeQuery(metricsQuery); return ( <> { if (isMetricsQuery(newQuery) && newQuery.metricEditorMode !== query.metricEditorMode) { this.setState({ sqlCodeEditorIsDirty: false }); } this.onChange(newQuery); }} sqlCodeEditorIsDirty={this.state.sqlCodeEditorIsDirty} /> {query.metricQueryType === MetricQueryType.Search && ( <> {query.metricEditorMode === MetricEditorMode.Builder && ( )} {query.metricEditorMode === MetricEditorMode.Code && ( this.props.onChange({ ...query, expression })} > )} )} {query.metricQueryType === MetricQueryType.Query && ( <> {query.metricEditorMode === MetricEditorMode.Code && ( { if (!this.state.sqlCodeEditorIsDirty) { this.setState({ sqlCodeEditorIsDirty: true }); } this.props.onChange({ ...metricsQuery, sqlExpression }); }} onRunQuery={onRunQuery} datasource={datasource} /> )} {query.metricEditorMode === MetricEditorMode.Builder && ( <> )} )} ) => this.onChange({ ...metricsQuery, id: event.target.value }) } type="text" invalid={!!query.id && !/^$|^[a-z][a-zA-Z0-9_]*$/.test(query.id)} value={query.id} /> ) => this.onChange({ ...metricsQuery, period: event.target.value }) } /> this.onChange({ ...metricsQuery, alias: value })} /> ); } }