1- import  React ,  {  ChangeEvent ,   ReactNode  }  from  'react' ; 
2- import  {  AsyncSelect ,   Button ,  Form ,   Icon ,   InlineField ,   Input ,  VerticalGroup  }  from  '@grafana/ui' ; 
1+ import  React ,  {   }  from  'react' ; 
2+ import  {  Button ,  Form ,  VerticalGroup  }  from  '@grafana/ui' ; 
33import  {  QueryEditorProps  }  from  '@grafana/data' ; 
4- import  {  DataSource ,  queryTypes  }  from  '../datasource' ; 
5- import  {  DEFAULT_QUERY ,  HaystackDataSourceOptions ,  HaystackQuery ,  QueryType  }  from  '../types' ; 
4+ import  {  DataSource  }  from  '../datasource' ; 
5+ import  {  HaystackDataSourceOptions ,  HaystackQuery  }  from  '../types' ; 
6+ import  {  HaystackQueryTypeSelector  }  from  './HaystackQueryTypeSelector' ; 
7+ import  {  HaystackQueryInput  }  from  './HaystackQueryInput' ; 
68
79type  Props  =  QueryEditorProps < DataSource ,  HaystackQuery ,  HaystackDataSourceOptions > ; 
810
911export  function  QueryEditor ( {  datasource,  query,  onChange,  onRunQuery } : Props )  { 
10-   const  onTypeChange  =  ( event :  QueryType   |   null )  =>  { 
11-     onChange ( {  ...query ,  type : event ?. value   ??   queryTypeDefault . value !  } ) ; 
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-   const  queryTypeDefault  =  queryTypes [ 0 ] ; 
24-   function  queryTypeFromValue ( value : string ) : QueryType  |  null  { 
25-     return  queryTypes . find ( ( queryType )  =>  queryType . value  ===  value )  ??  null ; 
26-   } 
27- 
28-   const  SelectComponent  =  ( )  =>  { 
29-     return  ( 
30-       < InlineField  label = "Type" > 
31-         < AsyncSelect 
32-           loadOptions = { ( )  =>  { return  datasource . loadOps ( query . refId ) ; } } 
33-           defaultOptions 
34-           value = { queryTypeFromValue ( query . type ) } 
35-           width = { 30 } 
36-           onChange = { ( queryType )  =>  { 
37-             // QueryType comes back as a SelectableValue, so we just convert it to the QueryType 
38-             onTypeChange ( queryTypeFromValue ( queryType . value  ??  "" ) ) ; 
39-           } } 
40-         /> 
41-       </ InlineField > 
42-     ) ; 
43-   } ; 
44- 
45-   function  renderQuery ( ) : ReactNode  { 
46-     let  width  =  100 ; 
47-     switch  ( query . type )  { 
48-       case  "eval" :
49-         return  ( 
50-           < InlineField > 
51-             < Input 
52-               width = { width } 
53-               prefix = { < Icon  name = "angle-right"  /> } 
54-               onChange = { onEvalChange } 
55-               value = { query . eval } 
56-               placeholder = { DEFAULT_QUERY . eval } 
57-             /> 
58-           </ InlineField > 
59-         ) ; 
60-       case  "hisRead" :
61-         return  ( 
62-           < InlineField > 
63-             < Input 
64-               width = { width } 
65-               prefix = { '@' } 
66-               onChange = { onHisReadChange } 
67-               value = { query . hisRead } 
68-               placeholder = { DEFAULT_QUERY . hisRead } 
69-             /> 
70-           </ InlineField > 
71-         ) ; 
72-       case  "read" :
73-         return  ( 
74-           < InlineField > 
75-             < Input 
76-               width = { width } 
77-               prefix = { < Icon  name = "filter"  /> } 
78-               onChange = { onReadChange } 
79-               value = { query . read } 
80-               placeholder = { DEFAULT_QUERY . read } 
81-             /> 
82-           </ InlineField > 
83-         ) ; 
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  } ) ; 
8422    } 
85-     return  < p > Select a query type</ p > ; 
86-   } 
23+   } ; 
8724
8825  function  onSubmit ( newQuery : Partial < HaystackQuery > )  { 
8926    query  =  {  ...query ,  ...newQuery  } ; 
@@ -97,8 +34,16 @@ export function QueryEditor({ datasource, query, onChange, onRunQuery }: Props)
9734        { ( {  register,  errors } )  =>  { 
9835          return  ( 
9936            < VerticalGroup > 
100-               < SelectComponent  /> 
101-               { 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+               /> 
10247              < Button  type = "submit"  > Run</ Button > 
10348            </ VerticalGroup > 
10449          ) ; 
0 commit comments