@@ -10,7 +10,7 @@ import {
1010 EuiSmallButtonEmpty ,
1111 PopoverAnchorPosition ,
1212} from '@elastic/eui' ;
13- import React , { useEffect , useState } from 'react' ;
13+ import React , { useCallback , useEffect , useMemo , useState } from 'react' ;
1414import { Query } from '../..' ;
1515import { LanguageConfig } from '../../query' ;
1616import { getQueryService } from '../../services' ;
@@ -36,12 +36,14 @@ export const QueryLanguageSelector = (props: QueryLanguageSelectorProps) => {
3636 const queryString = getQueryService ( ) . queryString ;
3737 const languageService = queryString . getLanguageService ( ) ;
3838
39- const datasetSupportedLanguages = props . query . dataset
40- ? queryString
41- . getDatasetService ( )
42- . getType ( props . query . dataset . type )
43- ?. supportedLanguages ( props . query . dataset )
44- : undefined ;
39+ const datasetSupportedLanguages = useMemo ( ( ) => {
40+ const dataset = props . query . dataset ;
41+ if ( ! dataset ) {
42+ return undefined ;
43+ }
44+ const datasetType = queryString . getDatasetService ( ) . getType ( dataset . type ) ;
45+ return datasetType ?. supportedLanguages ( dataset ) ;
46+ } , [ props . query . dataset , queryString ] ) ;
4547
4648 useEffect ( ( ) => {
4749 const subscription = queryString . getUpdates$ ( ) . subscribe ( ( query : Query ) => {
@@ -59,51 +61,58 @@ export const QueryLanguageSelector = (props: QueryLanguageSelectorProps) => {
5961 setPopover ( ! isPopoverOpen ) ;
6062 } ;
6163
62- const languageOptions : Array < { label : string ; value : string } > = [ ] ;
63-
64- languageService . getLanguages ( ) . forEach ( ( language ) => {
65- if (
66- ( language && props . appName && ! language . editorSupportedAppNames ?. includes ( props . appName ) ) ||
67- languageService . getUserQueryLanguageBlocklist ( ) . includes ( language ?. id ) ||
68- ( datasetSupportedLanguages && ! datasetSupportedLanguages . includes ( language . id ) )
69- )
70- return ;
71- languageOptions . unshift ( mapExternalLanguageToOptions ( language ) ) ;
72- } ) ;
73-
74- const selectedLanguage = {
75- label :
76- ( languageOptions . find (
77- ( option ) => ( option . value as string ) . toLowerCase ( ) === currentLanguage . toLowerCase ( )
78- ) ?. label as string ) ?? languageOptions [ 0 ] . label ,
79- } ;
64+ const languageOptions = useMemo ( ( ) => {
65+ const options : Array < { label : string ; value : string } > = [ ] ;
8066
81- const handleLanguageChange = ( newLanguage : string ) => {
82- setCurrentLanguage ( newLanguage ) ;
83- props . onSelectLanguage ( newLanguage ) ;
84- } ;
67+ languageService . getLanguages ( ) . forEach ( ( language ) => {
68+ const isSupported =
69+ ! datasetSupportedLanguages || datasetSupportedLanguages . includes ( language . id ) ;
70+ const isBlocklisted = languageService . getUserQueryLanguageBlocklist ( ) . includes ( language ?. id ) ;
71+ const isAppSupported =
72+ ! props . appName || language ?. editorSupportedAppNames ?. includes ( props . appName ) ;
73+
74+ if ( ! isSupported || isBlocklisted || ! isAppSupported ) return ;
75+
76+ options . unshift ( mapExternalLanguageToOptions ( language ) ) ;
77+ } ) ;
8578
86- languageService . setUserQueryLanguage ( currentLanguage ) ;
79+ return options . sort ( ( a , b ) => a . label . localeCompare ( b . label ) ) ;
80+ } , [ languageService , props . appName , datasetSupportedLanguages ] ) ;
81+
82+ const selectedLanguage = useMemo (
83+ ( ) => ( {
84+ label :
85+ languageOptions . find (
86+ ( option ) => option . value . toLowerCase ( ) === currentLanguage . toLowerCase ( )
87+ ) ?. label ?? languageOptions [ 0 ] ?. label ,
88+ } ) ,
89+ [ languageOptions , currentLanguage ]
90+ ) ;
91+
92+ const handleLanguageChange = useCallback (
93+ ( newLanguage : string ) => {
94+ setCurrentLanguage ( newLanguage ) ;
95+ props . onSelectLanguage ( newLanguage ) ;
96+ languageService . setUserQueryLanguage ( newLanguage ) ;
97+ setPopover ( false ) ;
98+ } ,
99+ [ props , languageService ]
100+ ) ;
87101
88- const languageOptionsMenu = languageOptions
89- . sort ( ( a , b ) => {
90- return a . label . localeCompare ( b . label ) ;
91- } )
92- . map ( ( language ) => {
93- return (
102+ const languageOptionsMenu = useMemo (
103+ ( ) =>
104+ languageOptions . map ( ( language ) => (
94105 < EuiContextMenuItem
95106 key = { language . label }
96107 className = "languageSelector__menuItem"
97108 icon = { language . label === selectedLanguage . label ? 'check' : 'empty' }
98- onClick = { ( ) => {
99- setPopover ( false ) ;
100- handleLanguageChange ( language . value ) ;
101- } }
109+ onClick = { ( ) => handleLanguageChange ( language . value ) }
102110 >
103111 { language . label }
104112 </ EuiContextMenuItem >
105- ) ;
106- } ) ;
113+ ) ) ,
114+ [ languageOptions , selectedLanguage . label , handleLanguageChange ]
115+ ) ;
107116
108117 return (
109118 < EuiPopover
0 commit comments