@@ -2,7 +2,7 @@ import React, { useState } from 'react';
2
2
3
3
import { SelectableValue } from '@grafana/data' ;
4
4
import { QueryBuilderOperationParamEditorProps } from '@grafana/plugin-ui' ;
5
- import { Icon , MultiSelect } from '@grafana/ui' ;
5
+ import { FormatOptionLabelMeta , Icon , MultiSelect } from '@grafana/ui' ;
6
6
7
7
import { getValue , quoteString , unquoteString } from '../utils/stringHandler' ;
8
8
import { splitByUnescapedChar , SplitString , splitString } from '../utils/stringSplitter' ;
@@ -24,6 +24,10 @@ export default function SortedFieldsEditor(props: QueryBuilderOperationParamEdit
24
24
const setFields = ( values : FieldWithDirection [ ] ) => {
25
25
setValues ( values ) ;
26
26
const newValue = values . map ( ( field ) => {
27
+ const isRaw = field . isDesc === undefined ;
28
+ if ( isRaw ) {
29
+ return quoteString ( field as unknown as string ) ;
30
+ }
27
31
return field . isDesc ? `${ quoteString ( field . name ) } desc` : `${ quoteString ( field . name ) } ` ;
28
32
} ) . join ( ', ' ) ;
29
33
onChange ( index , newValue ) ;
@@ -42,11 +46,39 @@ export default function SortedFieldsEditor(props: QueryBuilderOperationParamEdit
42
46
setIsLoading ( true ) ;
43
47
let options = await getFieldNameOptions ( props ) ;
44
48
const selectedNames = values . map ( v => v . name ) ;
45
- options = options . filter ( ( opt : SelectableValue < FieldWithDirection > ) => opt . value && ! selectedNames . includes ( opt . value . name ) ) ;
49
+ options = options . filter ( ( opt : SelectableValue < string > ) => opt . value && ! selectedNames . includes ( opt . value ) ) ;
46
50
setOptions ( options ) ;
47
51
setIsLoading ( false ) ;
48
52
}
49
53
54
+ const handleFormatOptionLabel = ( option : SelectableValue < FieldWithDirection > , { context } : FormatOptionLabelMeta < FieldWithDirection > ) => {
55
+ if ( context === 'value' ) {
56
+ const field = option as FieldWithDirection ;
57
+ const handleToggle = ( e : React . SyntheticEvent ) => {
58
+ e . stopPropagation ( ) ;
59
+ const idx = values . findIndex ( ( v ) => ( v ) . name === field . name ) ;
60
+ if ( idx !== - 1 ) {
61
+ toggleDirection ( idx ) ;
62
+ }
63
+ } ;
64
+ return (
65
+ < span
66
+ tabIndex = { 0 }
67
+ style = { { cursor : 'pointer' } }
68
+ onMouseDown = { handleToggle }
69
+ title = { field . isDesc ? 'Sorting descending' : 'Sorting ascending' }
70
+ >
71
+ { formatFieldLabel ( field ) }
72
+ < Icon
73
+ name = { field . isDesc ? 'arrow-down' : 'arrow-up' }
74
+ style = { { marginLeft : '4px' , verticalAlign : 'middle' } }
75
+ />
76
+ </ span >
77
+ ) ;
78
+ }
79
+ return < > { option . label } </ > ;
80
+ }
81
+
50
82
return (
51
83
< MultiSelect < FieldWithDirection >
52
84
openMenuOnFocus
@@ -59,33 +91,7 @@ export default function SortedFieldsEditor(props: QueryBuilderOperationParamEdit
59
91
options = { options }
60
92
value = { values }
61
93
onChange = { ( values ) => setFields ( values . map ( ( v ) => v . value || v as FieldWithDirection ) ) }
62
- formatOptionLabel = { ( option , { context } ) => {
63
- if ( context === 'value' ) {
64
- const field = option as FieldWithDirection ;
65
- const handleToggle = ( e : React . SyntheticEvent ) => {
66
- e . stopPropagation ( ) ;
67
- const idx = values . findIndex ( ( v ) => ( v ) . name === field . name ) ;
68
- if ( idx !== - 1 ) {
69
- toggleDirection ( idx ) ;
70
- }
71
- } ;
72
- return (
73
- < span
74
- tabIndex = { 0 }
75
- style = { { cursor : 'pointer' } }
76
- onMouseDown = { handleToggle }
77
- title = { field . isDesc ? 'Sorting descending' : 'Sorting ascending' }
78
- >
79
- { formatFieldLabel ( field ) }
80
- < Icon
81
- name = { field . isDesc ? 'arrow-down' : 'arrow-up' }
82
- style = { { marginLeft : '4px' , verticalAlign : 'middle' } }
83
- />
84
- </ span >
85
- ) ;
86
- }
87
- return < > { option . label } </ > ;
88
- } }
94
+ formatOptionLabel = { handleFormatOptionLabel }
89
95
/>
90
96
) ;
91
97
}
0 commit comments