From 85e0767b233b3a7d5238dd2b594fb9e338e8c68d Mon Sep 17 00:00:00 2001 From: Kawika Avilla Date: Wed, 23 Oct 2024 01:07:45 -0700 Subject: [PATCH] [discover] optimize rendering language options (#8685) * memoization plus not setting the user query language Signed-off-by: Kawika Avilla * clean up commented code Signed-off-by: Kawika Avilla * Changeset file for PR #8685 created/updated * Changeset file for PR #8685 deleted --------- Signed-off-by: Kawika Avilla Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com> --- .../ui/query_editor/language_selector.tsx | 93 ++++++++++--------- 1 file changed, 51 insertions(+), 42 deletions(-) diff --git a/src/plugins/data/public/ui/query_editor/language_selector.tsx b/src/plugins/data/public/ui/query_editor/language_selector.tsx index 28ab7cf1acd..31387c85c58 100644 --- a/src/plugins/data/public/ui/query_editor/language_selector.tsx +++ b/src/plugins/data/public/ui/query_editor/language_selector.tsx @@ -10,7 +10,7 @@ import { EuiSmallButtonEmpty, PopoverAnchorPosition, } from '@elastic/eui'; -import React, { useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { Query } from '../..'; import { LanguageConfig } from '../../query'; import { getQueryService } from '../../services'; @@ -36,12 +36,14 @@ export const QueryLanguageSelector = (props: QueryLanguageSelectorProps) => { const queryString = getQueryService().queryString; const languageService = queryString.getLanguageService(); - const datasetSupportedLanguages = props.query.dataset - ? queryString - .getDatasetService() - .getType(props.query.dataset.type) - ?.supportedLanguages(props.query.dataset) - : undefined; + const datasetSupportedLanguages = useMemo(() => { + const dataset = props.query.dataset; + if (!dataset) { + return undefined; + } + const datasetType = queryString.getDatasetService().getType(dataset.type); + return datasetType?.supportedLanguages(dataset); + }, [props.query.dataset, queryString]); useEffect(() => { const subscription = queryString.getUpdates$().subscribe((query: Query) => { @@ -59,51 +61,58 @@ export const QueryLanguageSelector = (props: QueryLanguageSelectorProps) => { setPopover(!isPopoverOpen); }; - const languageOptions: Array<{ label: string; value: string }> = []; - - languageService.getLanguages().forEach((language) => { - if ( - (language && props.appName && !language.editorSupportedAppNames?.includes(props.appName)) || - languageService.getUserQueryLanguageBlocklist().includes(language?.id) || - (datasetSupportedLanguages && !datasetSupportedLanguages.includes(language.id)) - ) - return; - languageOptions.unshift(mapExternalLanguageToOptions(language)); - }); - - const selectedLanguage = { - label: - (languageOptions.find( - (option) => (option.value as string).toLowerCase() === currentLanguage.toLowerCase() - )?.label as string) ?? languageOptions[0].label, - }; + const languageOptions = useMemo(() => { + const options: Array<{ label: string; value: string }> = []; - const handleLanguageChange = (newLanguage: string) => { - setCurrentLanguage(newLanguage); - props.onSelectLanguage(newLanguage); - }; + languageService.getLanguages().forEach((language) => { + const isSupported = + !datasetSupportedLanguages || datasetSupportedLanguages.includes(language.id); + const isBlocklisted = languageService.getUserQueryLanguageBlocklist().includes(language?.id); + const isAppSupported = + !props.appName || language?.editorSupportedAppNames?.includes(props.appName); + + if (!isSupported || isBlocklisted || !isAppSupported) return; + + options.unshift(mapExternalLanguageToOptions(language)); + }); - languageService.setUserQueryLanguage(currentLanguage); + return options.sort((a, b) => a.label.localeCompare(b.label)); + }, [languageService, props.appName, datasetSupportedLanguages]); + + const selectedLanguage = useMemo( + () => ({ + label: + languageOptions.find( + (option) => option.value.toLowerCase() === currentLanguage.toLowerCase() + )?.label ?? languageOptions[0]?.label, + }), + [languageOptions, currentLanguage] + ); + + const handleLanguageChange = useCallback( + (newLanguage: string) => { + setCurrentLanguage(newLanguage); + props.onSelectLanguage(newLanguage); + languageService.setUserQueryLanguage(newLanguage); + setPopover(false); + }, + [props, languageService] + ); - const languageOptionsMenu = languageOptions - .sort((a, b) => { - return a.label.localeCompare(b.label); - }) - .map((language) => { - return ( + const languageOptionsMenu = useMemo( + () => + languageOptions.map((language) => ( { - setPopover(false); - handleLanguageChange(language.value); - }} + onClick={() => handleLanguageChange(language.value)} > {language.label} - ); - }); + )), + [languageOptions, selectedLanguage.label, handleLanguageChange] + ); return (