@@ -12,7 +12,7 @@ import {
1212 Label ,
1313 VerticalGroup ,
1414} from '@grafana/ui' ;
15- import { debounce } from 'lodash' ;
15+ import { debounce , isNull } from 'lodash' ;
1616import React , { JSXElementConstructor } from 'react' ;
1717
1818import {
@@ -38,6 +38,14 @@ interface CheckMkAsyncSelectProps<Key extends keyof RequestSpec, Value = Request
3838 inputId : string ; // make the InlineField magic do its work // TODO: find better solution
3939}
4040
41+ function findValueInOptions < Value > ( lookupOptions : Array < NonNullable < SelectableValue < Value > > > , value : Value ) {
42+ const result = lookupOptions . find ( ( opt ) => opt . value === value ) ;
43+ if ( result !== undefined ) {
44+ return result ;
45+ }
46+ return null ;
47+ }
48+
4149export const CheckMkAsyncSelect = function < Key extends keyof RequestSpec , Value = RequestSpec [ Key ] > (
4250 props : CheckMkAsyncSelectProps < Key , Value >
4351) {
@@ -46,14 +54,6 @@ export const CheckMkAsyncSelect = function <Key extends keyof RequestSpec, Value
4654 const [ counter , setCounter ] = React . useState ( 0 ) ;
4755 const [ autocompleteError , setAutocompleteError ] = React . useState ( '' ) ;
4856
49- function findValueInOptions ( ) {
50- const result = options . find ( ( opt ) => opt . value === value ) ;
51- if ( result ) {
52- return result ;
53- }
54- return null ;
55- }
56-
5757 function getPlaceholder ( ) {
5858 if ( autocompleteError !== '' ) {
5959 return autocompleteError ;
@@ -68,22 +68,32 @@ export const CheckMkAsyncSelect = function <Key extends keyof RequestSpec, Value
6868 }
6969
7070 const loadOptions = React . useCallback (
71- ( inputValue : string ) : Promise < Array < SelectableValue < Value > > > => {
72- return autocompleter ( inputValue ) . then (
73- ( data ) => {
74- setAutocompleteError ( '' ) ;
75- setOptions ( data ) ;
76- return data ;
77- } ,
78- ( error ) => {
79- if ( error && error . message ) {
80- setAutocompleteError ( error . message ) ;
81- }
82- throw error ;
71+ async ( inputValue : string ) : Promise < Array < SelectableValue < Value > > > => {
72+ try {
73+ const data = await autocompleter ( inputValue ) ;
74+ setAutocompleteError ( '' ) ;
75+ if ( value !== null && value !== undefined && inputValue === '' && isNull ( findValueInOptions ( data , value ) ) ) {
76+ // when we load the query editor with a saved configuration it is
77+ // possible, that the value saved is not present in the autocompleter
78+ // values which got queried with an empty string. (the autocompleter
79+ // only returns the first 100 matching elements).
80+ // this would mean we would display an error "could not find element 'xxx'"
81+ // in order to prevent that, we do an additional query, with the
82+ // value to make sure we receive the value (and label).
83+ const specificData = await autocompleter ( value as string ) ;
84+ data . push ( ...specificData ) ;
85+ }
86+ setOptions ( data ) ;
87+ return data ;
88+ } catch ( e ) {
89+ const error = e as Error ;
90+ if ( error && error . message ) {
91+ setAutocompleteError ( error . message ) ;
8392 }
84- ) ;
93+ throw error ;
94+ }
8595 } ,
86- [ autocompleter ]
96+ [ autocompleter , value ]
8797 ) ;
8898
8999 React . useEffect ( ( ) => {
@@ -108,7 +118,7 @@ export const CheckMkAsyncSelect = function <Key extends keyof RequestSpec, Value
108118 key = { `${ Math . max ( 1 , counter ) } ` } // ignore the first update
109119 loadOptions = { loadOptions }
110120 width = { width || 32 }
111- value = { findValueInOptions ( ) }
121+ value = { findValueInOptions ( options , value ) }
112122 placeholder = { getPlaceholder ( ) }
113123 />
114124 ) ;
0 commit comments