1- import React , { ChangeEvent , ReactNode } from 'react' ;
2- import { AsyncSelect , Button , Form , Icon , InlineField , Input , VerticalGroup } from '@grafana/ui' ;
3- import { DataFrame , DataQueryRequest , Field , getDefaultTimeRange , QueryEditorProps , SelectableValue , Vector } from '@grafana/data' ;
1+ import React , { } from 'react' ;
2+ import { Button , Form , VerticalGroup } from '@grafana/ui' ;
3+ import { QueryEditorProps } from '@grafana/data' ;
44import { DataSource } from '../datasource' ;
5- import { DEFAULT_QUERY , HaystackDataSourceOptions , HaystackQuery } from '../types' ;
5+ import { HaystackDataSourceOptions , HaystackQuery } from '../types' ;
6+ import { HaystackQueryTypeSelector } from './HaystackQueryTypeSelector' ;
7+ import { HaystackQueryInput } from './HaystackQueryInput' ;
68
79type Props = QueryEditorProps < DataSource , HaystackQuery , HaystackDataSourceOptions > ;
810
9- export function QueryEditor ( { datasource, query, onChange, onRunQuery, range , app } : Props ) {
10- const onTypeChange = ( event : SelectableValue < string > ) => {
11- onChange ( { ...query , type : event . value ?? queryTypeDefault . value ! } ) ;
11+ export function QueryEditor ( { datasource, query, onChange, onRunQuery } : Props ) {
12+ const onTypeChange = ( newType : string ) => {
13+ onChange ( { ...query , type : newType } ) ;
1214 } ;
13- const onEvalChange = ( event : ChangeEvent < HTMLInputElement > ) => {
14- onChange ( { ...query , type : 'eval' , eval : event . target . value } ) ;
15- } ;
16- const onHisReadChange = ( event : ChangeEvent < HTMLInputElement > ) => {
17- onChange ( { ...query , type : 'hisRead' , hisRead : event . target . value } ) ;
18- } ;
19- const onReadChange = ( event : ChangeEvent < HTMLInputElement > ) => {
20- onChange ( { ...query , type : 'read' , read : event . target . value } ) ;
21- } ;
22-
23- interface QueryType extends SelectableValue < string > {
24- apiRequirements : string [ ] ;
25- }
26-
27- const queryTypes : QueryType [ ] = [
28- { label : 'Read' , value : "read" , apiRequirements : [ "read" ] , description : 'Read the records matched by a filter' } ,
29- { label : 'HisRead' , value : "hisRead" , apiRequirements : [ "hisRead" ] , description : 'Read the history of a point' } ,
30- { label : 'Eval' , value : "eval" , apiRequirements : [ "eval" ] , description : 'Evaluate an Axon expression' } ,
31- ] ;
32- const queryTypeDefault = queryTypes [ 0 ] ;
33- function queryTypeFromLabel ( label : string ) {
34- return queryTypes . find ( ( queryType ) => queryType . value === label ) ;
35- }
36-
37- const SelectComponent = ( ) => {
38- return (
39- < InlineField label = "Type" >
40- < AsyncSelect
41- loadOptions = { loadOps }
42- defaultOptions
43- value = { queryTypeFromLabel ( query . type ) }
44- width = { 30 }
45- onChange = { ( queryType ) => {
46- onTypeChange ( queryType ) ;
47- } }
48- />
49- </ InlineField >
50- ) ;
51- } ;
52-
53- // Queries the available ops from the datasource on only returns the ones that are supported.
54- const loadOps = ( ) => {
55- let opsRequest : DataQueryRequest < HaystackQuery > = {
56- requestId : 'ops' ,
57- dashboardId : 0 ,
58- interval : '0' ,
59- intervalMs : 0 ,
60- panelId : 0 ,
61- range : range ?? getDefaultTimeRange ( ) ,
62- scopedVars : { } ,
63- targets : [ { type : 'ops' , eval : "" , read : "" , hisRead : "" , refId : query . refId } ] ,
64- timezone : 'UTC' ,
65- app : 'ops' ,
66- startTime : 0 ,
15+ const onQueryChange = ( newQuery : string ) => {
16+ if ( query . type === "hisRead" ) {
17+ onChange ( { ...query , hisRead : newQuery } ) ;
18+ } else if ( query . type === "eval" ) {
19+ onChange ( { ...query , eval : newQuery } ) ;
20+ } else if ( query . type === "read" ) {
21+ onChange ( { ...query , read : newQuery } ) ;
6722 }
68- return datasource . query ( opsRequest ) . toPromise ( ) . then ( ( result ) => {
69- if ( result ?. state === 'Error' ) {
70- return [ ] ;
71- }
72- let frame = result ?. data ?. find ( ( frame : DataFrame ) => {
73- return frame . refId === query . refId
74- } )
75- let opSymbols = frame ?. fields ?. find ( ( field : Field < any , Vector < string > > ) => {
76- return field . name === 'def'
77- } ) . values ?? [ ] ;
78- let ops : string [ ] = opSymbols . map ( ( opSymbol : string ) => {
79- if ( opSymbol . startsWith ( '^op:' ) ) {
80- return opSymbol . substring ( 4 ) ;
81- } else {
82- return opSymbol ;
83- }
84- } ) ;
85-
86- return queryTypes . filter ( ( queryType ) => {
87- return queryType . apiRequirements . every ( ( apiRequirement ) => {
88- return ops . find ( ( op ) => {
89- return op === apiRequirement
90- } ) !== undefined ;
91- } ) ;
92- } ) ;
93- } ) ;
94- }
95-
96- function renderQuery ( ) : ReactNode {
97- let width = 100 ;
98- let queryType = queryTypeFromLabel ( query . type ) ;
99- switch ( queryType ?. value ) {
100- case "eval" :
101- return (
102- < InlineField >
103- < Input
104- width = { width }
105- prefix = { < Icon name = "angle-right" /> }
106- onChange = { onEvalChange }
107- value = { query . eval }
108- placeholder = { DEFAULT_QUERY . eval }
109- />
110- </ InlineField >
111- ) ;
112- case "hisRead" :
113- return (
114- < InlineField >
115- < Input
116- width = { width }
117- prefix = { '@' }
118- onChange = { onHisReadChange }
119- value = { query . hisRead }
120- placeholder = { DEFAULT_QUERY . hisRead }
121- />
122- </ InlineField >
123- ) ;
124- case "read" :
125- return (
126- < InlineField >
127- < Input
128- width = { width }
129- prefix = { < Icon name = "filter" /> }
130- onChange = { onReadChange }
131- value = { query . read }
132- placeholder = { DEFAULT_QUERY . read }
133- />
134- </ InlineField >
135- ) ;
136- }
137- return < p > Select a query type</ p > ;
138- }
23+ } ;
13924
14025 function onSubmit ( newQuery : Partial < HaystackQuery > ) {
14126 query = { ...query , ...newQuery } ;
@@ -149,8 +34,16 @@ export function QueryEditor({ datasource, query, onChange, onRunQuery, range, ap
14934 { ( { register, errors } ) => {
15035 return (
15136 < VerticalGroup >
152- < SelectComponent />
153- { renderQuery ( ) }
37+ < HaystackQueryTypeSelector
38+ datasource = { datasource }
39+ type = { query . type }
40+ refId = { query . refId }
41+ onChange = { onTypeChange }
42+ />
43+ < HaystackQueryInput
44+ query = { query }
45+ onChange = { onQueryChange }
46+ />
15447 < Button type = "submit" > Run</ Button >
15548 </ VerticalGroup >
15649 ) ;
0 commit comments