2021-12-06 09:37:54 +01:00
import React , { ChangeEvent , PureComponent } from 'react' ;
2022-04-22 14:33:13 +01:00
2021-11-30 10:53:31 +01:00
import { QueryEditorProps } from '@grafana/data' ;
2021-12-06 09:37:54 +01:00
import { EditorField , EditorRow , Space } from '@grafana/experimental' ;
2021-11-30 10:53:31 +01:00
import { Input } from '@grafana/ui' ;
2022-04-22 14:33:13 +01:00
2021-12-06 09:37:54 +01:00
import { CloudWatchDatasource } from '../datasource' ;
2022-04-27 12:41:48 +02:00
import { isCloudWatchMetricsQuery } from '../guards' ;
2021-11-30 10:53:31 +01:00
import {
CloudWatchJsonData ,
2021-12-06 09:37:54 +01:00
CloudWatchMetricsQuery ,
CloudWatchQuery ,
2021-11-30 10:53:31 +01:00
MetricEditorMode ,
2021-12-06 09:37:54 +01:00
MetricQueryType ,
2022-04-27 12:41:48 +02:00
MetricStat ,
2021-11-30 10:53:31 +01:00
} from '../types' ;
2022-04-22 14:33:13 +01:00
2021-11-30 10:53:31 +01:00
import QueryHeader from './QueryHeader' ;
2019-11-14 10:59:41 +01:00
2022-04-22 14:33:13 +01:00
import { Alias , MathExpressionQueryField , MetricStatEditor , SQLBuilderEditor , SQLCodeEditor } from './' ;
2021-09-15 16:26:23 +01:00
export type Props = QueryEditorProps < CloudWatchDatasource , CloudWatchQuery , CloudWatchJsonData > ;
2019-11-14 10:59:41 +01:00
interface State {
2021-11-30 10:53:31 +01:00
sqlCodeEditorIsDirty : boolean ;
2019-11-14 10:59:41 +01:00
}
2020-03-20 14:00:49 +02:00
export const normalizeQuery = ( {
namespace ,
metricName ,
expression ,
dimensions ,
region ,
id ,
alias ,
2021-09-08 16:06:43 +02:00
statistic ,
2020-03-20 14:00:49 +02:00
period ,
2021-11-30 10:53:31 +01:00
sqlExpression ,
metricQueryType ,
metricEditorMode ,
2020-03-20 14:00:49 +02:00
. . . rest
2020-04-25 21:48:20 +01:00
} : CloudWatchMetricsQuery ) : CloudWatchMetricsQuery = > {
2020-03-20 14:00:49 +02:00
const normalizedQuery = {
2021-11-30 10:53:31 +01:00
queryMode : 'Metrics' as const ,
namespace : namespace ? ? '' ,
metricName : metricName ? ? '' ,
expression : expression ? ? '' ,
dimensions : dimensions ? ? { } ,
region : region ? ? 'default' ,
id : id ? ? '' ,
alias : alias ? ? '' ,
2021-09-08 16:06:43 +02:00
statistic : statistic ? ? 'Average' ,
2021-11-30 10:53:31 +01:00
period : period ? ? '' ,
metricQueryType : metricQueryType ? ? MetricQueryType . Search ,
metricEditorMode : metricEditorMode ? ? MetricEditorMode . Builder ,
sqlExpression : sqlExpression ? ? '' ,
2020-03-20 14:00:49 +02:00
. . . rest ,
} ;
return ! rest . hasOwnProperty ( 'matchExact' ) ? { . . . normalizedQuery , matchExact : true } : normalizedQuery ;
} ;
2020-04-25 21:48:20 +01:00
export class MetricsQueryEditor extends PureComponent < Props , State > {
2021-11-30 10:53:31 +01:00
state = {
sqlCodeEditorIsDirty : false ,
} ;
2019-11-14 10:59:41 +01:00
2021-11-30 10:53:31 +01:00
componentDidMount = ( ) = > {
2020-05-07 13:22:45 +02:00
const metricsQuery = this . props . query as CloudWatchMetricsQuery ;
const query = normalizeQuery ( metricsQuery ) ;
this . props . onChange ( query ) ;
2021-11-30 10:53:31 +01:00
} ;
2020-05-07 13:22:45 +02:00
2021-11-30 10:53:31 +01:00
onChange = ( query : CloudWatchQuery ) = > {
2019-11-14 10:59:41 +01:00
const { onChange , onRunQuery } = this . props ;
onChange ( query ) ;
onRunQuery ( ) ;
2021-11-30 10:53:31 +01:00
} ;
2021-09-08 16:06:43 +02:00
2019-11-14 10:59:41 +01:00
render() {
2021-11-30 10:53:31 +01:00
const { onRunQuery , datasource } = this . props ;
2020-04-25 21:48:20 +01:00
const metricsQuery = this . props . query as CloudWatchMetricsQuery ;
const query = normalizeQuery ( metricsQuery ) ;
2021-11-30 10:53:31 +01:00
2019-11-14 10:59:41 +01:00
return (
< >
2021-11-30 10:53:31 +01:00
< QueryHeader
query = { query }
onRunQuery = { onRunQuery }
datasource = { datasource }
onChange = { ( newQuery ) = > {
2022-04-27 12:41:48 +02:00
if ( isCloudWatchMetricsQuery ( newQuery ) && newQuery . metricEditorMode !== query . metricEditorMode ) {
2021-11-30 10:53:31 +01:00
this . setState ( { sqlCodeEditorIsDirty : false } ) ;
}
this . onChange ( newQuery ) ;
} }
sqlCodeEditorIsDirty = { this . state . sqlCodeEditorIsDirty }
/ >
< Space v = { 0.5 } / >
{ query . metricQueryType === MetricQueryType . Search && (
< >
{ query . metricEditorMode === MetricEditorMode . Builder && (
2022-04-27 12:41:48 +02:00
< MetricStatEditor
{ . . . this . props }
refId = { query . refId }
metricStat = { query }
onChange = { ( metricStat : MetricStat ) = > this . props . onChange ( { . . . query , . . . metricStat } ) }
> < / MetricStatEditor >
2021-11-30 10:53:31 +01:00
) }
{ query . metricEditorMode === MetricEditorMode . Code && (
< MathExpressionQueryField
onRunQuery = { onRunQuery }
expression = { query . expression ? ? '' }
onChange = { ( expression ) = > this . props . onChange ( { . . . query , expression } ) }
2022-02-01 22:53:32 -05:00
datasource = { datasource }
2021-11-30 10:53:31 +01:00
> < / MathExpressionQueryField >
) }
< / >
) }
{ query . metricQueryType === MetricQueryType . Query && (
< >
{ query . metricEditorMode === MetricEditorMode . Code && (
< SQLCodeEditor
region = { query . region }
sql = { query . sqlExpression ? ? '' }
onChange = { ( sqlExpression ) = > {
if ( ! this . state . sqlCodeEditorIsDirty ) {
this . setState ( { sqlCodeEditorIsDirty : true } ) ;
}
this . props . onChange ( { . . . metricsQuery , sqlExpression } ) ;
} }
onRunQuery = { onRunQuery }
datasource = { datasource }
2020-04-25 21:48:20 +01:00
/ >
2021-11-30 10:53:31 +01:00
) }
{ query . metricEditorMode === MetricEditorMode . Builder && (
< >
< SQLBuilderEditor
query = { query }
onChange = { this . props . onChange }
onRunQuery = { onRunQuery }
datasource = { datasource }
> < / SQLBuilderEditor >
< / >
) }
< / >
) }
< Space v = { 0.5 } / >
< EditorRow >
< EditorField
label = "ID"
width = { 26 }
optional
tooltip = "ID can be used to reference other queries in math expressions. The ID can include numbers, letters, and underscore, and must start with a lowercase letter."
2022-04-26 11:28:34 +02:00
invalid = { ! ! query . id && ! /^$|^[a-z][a-zA-Z0-9_]*$/ . test ( query . id ) }
2021-11-30 10:53:31 +01:00
>
< Input
2022-01-18 14:31:51 +01:00
id = { ` ${ query . refId } -cloudwatch-metric-query-editor-id ` }
2021-11-30 10:53:31 +01:00
onBlur = { onRunQuery }
onChange = { ( event : ChangeEvent < HTMLInputElement > ) = >
this . onChange ( { . . . metricsQuery , id : event.target.value } )
2020-04-25 21:48:20 +01:00
}
2021-11-30 10:53:31 +01:00
type = "text"
value = { query . id }
/ >
< / EditorField >
< EditorField label = "Period" width = { 26 } tooltip = "Minimum interval between points in seconds." >
< Input
2022-01-18 14:31:51 +01:00
id = { ` ${ query . refId } -cloudwatch-metric-query-editor-period ` }
2021-11-30 10:53:31 +01:00
value = { query . period || '' }
placeholder = "auto"
onBlur = { onRunQuery }
onChange = { ( event : ChangeEvent < HTMLInputElement > ) = >
this . onChange ( { . . . metricsQuery , period : event.target.value } )
}
/ >
< / EditorField >
< EditorField
label = "Alias"
width = { 26 }
optional
tooltip = "Change time series legend name using this field. See documentation for replacement variable formats."
>
< Alias
value = { metricsQuery . alias ? ? '' }
onChange = { ( value : string ) = > this . onChange ( { . . . metricsQuery , alias : value } ) }
2019-11-14 10:59:41 +01:00
/ >
2021-11-30 10:53:31 +01:00
< / EditorField >
< / EditorRow >
2019-11-14 10:59:41 +01:00
< / >
) ;
}
}