@@ -40,19 +40,6 @@ export interface DimensionEditorProps extends IndexPatternDimensionEditorProps {
4040 currentIndexPattern : IndexPattern ;
4141}
4242
43- function asOperationOptions ( operationTypes : OperationType [ ] , compatibleWithCurrentField : boolean ) {
44- return [ ...operationTypes ]
45- . sort ( ( opType1 , opType2 ) => {
46- return operationPanels [ opType1 ] . displayName . localeCompare (
47- operationPanels [ opType2 ] . displayName
48- ) ;
49- } )
50- . map ( ( operationType ) => ( {
51- operationType,
52- compatibleWithCurrentField,
53- } ) ) ;
54- }
55-
5643const LabelInput = ( { value, onChange } : { value : string ; onChange : ( value : string ) => void } ) => {
5744 const [ inputValue , setInputValue ] = useState ( value ) ;
5845
@@ -98,7 +85,7 @@ export function DimensionEditor(props: DimensionEditorProps) {
9885 currentIndexPattern,
9986 hideGrouping,
10087 } = props ;
101- const { operationByField , fieldByOperation } = operationSupportMatrix ;
88+ const { fieldByOperation , operationWithoutField } = operationSupportMatrix ;
10289 const [
10390 incompatibleSelectedOperationType ,
10491 setInvalidOperationType ,
@@ -117,30 +104,35 @@ export function DimensionEditor(props: DimensionEditorProps) {
117104 return fields ;
118105 } , [ currentIndexPattern ] ) ;
119106
120- function getOperationTypes ( ) {
121- const possibleOperationTypes = Object . keys ( fieldByOperation ) as OperationType [ ] ;
122- const validOperationTypes : OperationType [ ] = [ ] ;
123-
124- if ( ! selectedColumn ) {
125- validOperationTypes . push ( ...( Object . keys ( fieldByOperation ) as OperationType [ ] ) ) ;
126- } else if ( hasField ( selectedColumn ) && operationByField [ selectedColumn . sourceField ] ) {
127- validOperationTypes . push ( ...operationByField [ selectedColumn . sourceField ] ! ) ;
128- }
107+ const possibleOperations = useMemo ( ( ) => {
108+ return Object . values ( operationDefinitionMap )
109+ . sort ( ( op1 , op2 ) => {
110+ return op1 . displayName . localeCompare ( op2 . displayName ) ;
111+ } )
112+ . map ( ( def ) => def . type )
113+ . filter (
114+ ( type ) => fieldByOperation [ type ] ?. length || operationWithoutField . indexOf ( type ) !== - 1
115+ ) ;
116+ } , [ fieldByOperation , operationWithoutField ] ) ;
129117
130- return _ . uniqBy (
131- [
132- ...asOperationOptions ( validOperationTypes , true ) ,
133- ...asOperationOptions ( possibleOperationTypes , false ) ,
134- ...asOperationOptions (
135- operationSupportMatrix . operationWithoutField ,
136- ! selectedColumn || ! hasField ( selectedColumn )
137- ) ,
138- ] ,
139- 'operationType'
140- ) ;
141- }
118+ // Operations are compatible if they match inputs. They are always compatible in
119+ // the empty state. Field-based operations are not compatible with field-less operations.
120+ const operationsWithCompatibility = [ ...possibleOperations ] . map ( ( operationType ) => {
121+ const definition = operationDefinitionMap [ operationType ] ;
142122
143- const sideNavItems : EuiListGroupItemProps [ ] = getOperationTypes ( ) . map (
123+ return {
124+ operationType,
125+ compatibleWithCurrentField :
126+ ! selectedColumn ||
127+ ( selectedColumn &&
128+ hasField ( selectedColumn ) &&
129+ definition . input === 'field' &&
130+ fieldByOperation [ operationType ] ?. indexOf ( selectedColumn . sourceField ) !== - 1 ) ||
131+ ( selectedColumn && ! hasField ( selectedColumn ) && definition . input !== 'field' ) ,
132+ } ;
133+ } ) ;
134+
135+ const sideNavItems : EuiListGroupItemProps [ ] = operationsWithCompatibility . map (
144136 ( { operationType, compatibleWithCurrentField } ) => {
145137 const isActive = Boolean (
146138 incompatibleSelectedOperationType === operationType ||
0 commit comments