mirror of https://github.com/grafana/grafana
InfluxDB: Introduce custom variable support (#87903)
* Introduce custom variable support * Remove comment lines * bettererpull/88127/head
parent
a2aea70100
commit
9bdfb6ee13
@ -1,68 +1,75 @@ |
||||
import React, { PureComponent } from 'react'; |
||||
import React from 'react'; |
||||
|
||||
import { Field, FieldSet, InlineFormLabel, TextArea } from '@grafana/ui'; |
||||
import { QueryEditorProps } from '@grafana/data'; |
||||
import { Field, FieldSet, InlineFieldRow, TextArea } from '@grafana/ui'; |
||||
import { InlineField } from '@grafana/ui/'; |
||||
|
||||
import InfluxDatasource from '../../../datasource'; |
||||
import { InfluxVersion } from '../../../types'; |
||||
import { InfluxOptions, InfluxQuery, InfluxVariableQuery, InfluxVersion } from '../../../types'; |
||||
import { FluxQueryEditor } from '../query/flux/FluxQueryEditor'; |
||||
|
||||
interface Props { |
||||
query: string; // before flux, it was always a string
|
||||
onChange: (query?: string) => void; |
||||
datasource: InfluxDatasource; |
||||
} |
||||
export type Props = QueryEditorProps<InfluxDatasource, InfluxQuery, InfluxOptions, InfluxVariableQuery>; |
||||
|
||||
export default class VariableQueryEditor extends PureComponent<Props> { |
||||
onRefresh = () => { |
||||
// noop
|
||||
const refId = 'InfluxVariableQueryEditor-VariableQuery'; |
||||
|
||||
const useVariableQuery = (query: InfluxVariableQuery | string): InfluxVariableQuery => { |
||||
// in legacy variable support query can be only a string
|
||||
// in new variable support query can be an object and hold more information
|
||||
// to be able to support old version we check the query here
|
||||
if (typeof query === 'string') { |
||||
return { |
||||
refId, |
||||
query, |
||||
}; |
||||
} else { |
||||
return { |
||||
refId, |
||||
query: query.query ?? '', |
||||
}; |
||||
} |
||||
}; |
||||
|
||||
export const InfluxVariableEditor = ({ onChange, datasource, query }: Props) => { |
||||
const varQuery = useVariableQuery(query); |
||||
|
||||
const onChangeHandler = (q: InfluxQuery) => { |
||||
onChange({ refId, query: q.query || '' }); |
||||
}; |
||||
|
||||
render() { |
||||
let { query, datasource, onChange } = this.props; |
||||
const onBlurHandler = (e: React.FocusEvent<HTMLTextAreaElement>) => { |
||||
onChange({ refId, query: e.currentTarget.value }); |
||||
}; |
||||
|
||||
switch (datasource.version) { |
||||
case InfluxVersion.Flux: |
||||
return ( |
||||
<FluxQueryEditor |
||||
datasource={datasource} |
||||
query={{ |
||||
refId: 'A', |
||||
query, |
||||
}} |
||||
onRunQuery={this.onRefresh} |
||||
onChange={(v) => onChange(v.query)} |
||||
/> |
||||
); |
||||
case InfluxVersion.SQL: |
||||
return ( |
||||
<FieldSet> |
||||
<Field htmlFor="influx-sql-variable-query"> |
||||
<TextArea |
||||
id="influx-sql-variable-query" |
||||
defaultValue={query || ''} |
||||
placeholder="metric name or tags query" |
||||
rows={1} |
||||
onBlur={(e) => onChange(e.currentTarget.value)} |
||||
/> |
||||
</Field> |
||||
</FieldSet> |
||||
); |
||||
case InfluxVersion.InfluxQL: |
||||
default: |
||||
return ( |
||||
<div className="gf-form-inline"> |
||||
<InlineFormLabel width={10}>Query</InlineFormLabel> |
||||
<div className="gf-form-inline gf-form--grow"> |
||||
<TextArea |
||||
defaultValue={query || ''} |
||||
placeholder="metric name or tags query" |
||||
rows={1} |
||||
className="gf-form-input" |
||||
onBlur={(e) => onChange(e.currentTarget.value)} |
||||
/> |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
switch (datasource.version) { |
||||
case InfluxVersion.Flux: |
||||
return <FluxQueryEditor datasource={datasource} query={varQuery} onChange={onChangeHandler} />; |
||||
case InfluxVersion.SQL: |
||||
return ( |
||||
<FieldSet> |
||||
<Field htmlFor="influx-sql-variable-query"> |
||||
<TextArea |
||||
id="influx-sql-variable-query" |
||||
defaultValue={varQuery.query || ''} |
||||
placeholder="metric name or tags query" |
||||
rows={1} |
||||
onBlur={onBlurHandler} |
||||
/> |
||||
</Field> |
||||
</FieldSet> |
||||
); |
||||
case InfluxVersion.InfluxQL: |
||||
default: |
||||
return ( |
||||
<InlineFieldRow> |
||||
<InlineField label="Query" labelWidth={20} required grow aria-labelledby="label-select"> |
||||
<TextArea |
||||
defaultValue={varQuery.query || ''} |
||||
placeholder="metric name or tags query" |
||||
rows={1} |
||||
onBlur={onBlurHandler} |
||||
/> |
||||
</InlineField> |
||||
</InlineFieldRow> |
||||
); |
||||
} |
||||
} |
||||
}; |
||||
|
||||
@ -0,0 +1,37 @@ |
||||
import { from, Observable, of } from 'rxjs'; |
||||
import { map } from 'rxjs/operators'; |
||||
|
||||
import { CustomVariableSupport, DataQueryRequest, DataQueryResponse } from '@grafana/data'; |
||||
import { getTemplateSrv, TemplateSrv } from '@grafana/runtime'; |
||||
|
||||
import { InfluxVariableEditor } from './components/editor/variable/VariableQueryEditor'; |
||||
import InfluxDatasource from './datasource'; |
||||
import { InfluxVariableQuery } from './types'; |
||||
|
||||
export class InfluxVariableSupport extends CustomVariableSupport<InfluxDatasource> { |
||||
editor = InfluxVariableEditor; |
||||
|
||||
constructor( |
||||
private readonly datasource: InfluxDatasource, |
||||
private readonly templateSrv: TemplateSrv = getTemplateSrv() |
||||
) { |
||||
super(); |
||||
} |
||||
|
||||
query(request: DataQueryRequest<InfluxVariableQuery>): Observable<DataQueryResponse> { |
||||
let query: string | undefined; |
||||
if (typeof request.targets[0] === 'string') { |
||||
query = request.targets[0]; |
||||
} else { |
||||
query = request.targets[0].query; |
||||
} |
||||
|
||||
if (!query) { |
||||
return of({ data: [] }); |
||||
} |
||||
|
||||
const interpolated = this.templateSrv.replace(query, request.scopedVars, this.datasource.interpolateQueryExpr); |
||||
const metricFindStream = from(this.datasource.metricFindQuery(interpolated, request.range)); |
||||
return metricFindStream.pipe(map((results) => ({ data: results }))); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue