diff --git a/src/plugins/data/public/plugin.ts b/src/plugins/data/public/plugin.ts index 60a216504620..ce521ff33251 100644 --- a/src/plugins/data/public/plugin.ts +++ b/src/plugins/data/public/plugin.ts @@ -53,6 +53,7 @@ import { UiSettingsPublicToCommon, } from './index_patterns'; import { + setApplication, setFieldFormats, setIndexPatterns, setNotifications, @@ -151,6 +152,7 @@ export class DataPublicPlugin sessionStorage: this.sessionStorage, defaultSearchInterceptor: searchService.getDefaultSearchInterceptor(), application: core.application, + notifications: core.notifications, }); uiActions.registerAction( @@ -195,6 +197,7 @@ export class DataPublicPlugin setNotifications(notifications); setOverlays(overlays); setUiSettings(uiSettings); + setApplication(application); const fieldFormats = this.fieldFormatsService.start(); setFieldFormats(fieldFormats); @@ -226,6 +229,7 @@ export class DataPublicPlugin uiSettings, indexPatterns, application: core.application, + notifications, }); setQueryService(query); diff --git a/src/plugins/data/public/query/query_service.ts b/src/plugins/data/public/query/query_service.ts index 8d4feacc51ee..b009d4eeef01 100644 --- a/src/plugins/data/public/query/query_service.ts +++ b/src/plugins/data/public/query/query_service.ts @@ -62,6 +62,7 @@ export class QueryService { storage, sessionStorage, defaultSearchInterceptor, + notifications, }: QueryServiceSetupDependencies): IQuerySetup { this.filterManager = new FilterManager(uiSettings); @@ -75,7 +76,8 @@ export class QueryService { storage, sessionStorage, uiSettings, - defaultSearchInterceptor + defaultSearchInterceptor, + notifications ); this.state$ = createQueryStateObservable({ diff --git a/src/plugins/data/public/query/query_string/language_service/lib/dql_language.ts b/src/plugins/data/public/query/query_string/language_service/lib/dql_language.ts index 39dc49f22fce..dfa3e2386da7 100644 --- a/src/plugins/data/public/query/query_string/language_service/lib/dql_language.ts +++ b/src/plugins/data/public/query/query_string/language_service/lib/dql_language.ts @@ -24,6 +24,6 @@ export const getDQLLanguageConfig = ( }, showDocLinks: true, editorSupportedAppNames: ['discover'], - supportedAppNames: ['discover', 'dashboards', 'visualize', 'data-explorer'], + supportedAppNames: ['discover', 'dashboards', 'visualize', 'data-explorer', 'vis-builder', '*'], }; }; diff --git a/src/plugins/data/public/query/query_string/language_service/lib/lucene_language.ts b/src/plugins/data/public/query/query_string/language_service/lib/lucene_language.ts index 742747d037e9..b5d04f9e4a29 100644 --- a/src/plugins/data/public/query/query_string/language_service/lib/lucene_language.ts +++ b/src/plugins/data/public/query/query_string/language_service/lib/lucene_language.ts @@ -24,6 +24,6 @@ export const getLuceneLanguageConfig = ( }, showDocLinks: true, editorSupportedAppNames: ['discover'], - supportedAppNames: ['discover', 'dashboards', 'visualize', 'data-explorer'], + supportedAppNames: ['discover', 'dashboards', 'visualize', 'data-explorer', 'vis-builder', '*'], }; }; diff --git a/src/plugins/data/public/query/query_string/query_string_manager.ts b/src/plugins/data/public/query/query_string/query_string_manager.ts index 23aa938ba23a..94d0eb318791 100644 --- a/src/plugins/data/public/query/query_string/query_string_manager.ts +++ b/src/plugins/data/public/query/query_string/query_string_manager.ts @@ -30,13 +30,15 @@ import { BehaviorSubject } from 'rxjs'; import { skip } from 'rxjs/operators'; -import { CoreStart } from 'opensearch-dashboards/public'; -import { isEqual } from 'lodash'; +import { CoreStart, NotificationsSetup } from 'opensearch-dashboards/public'; +import { debounce, isEqual } from 'lodash'; +import { i18n } from '@osd/i18n'; import { Dataset, DataStorage, Query, TimeRange, UI_SETTINGS } from '../../../common'; import { createHistory, QueryHistory } from './query_history'; import { DatasetService, DatasetServiceContract } from './dataset_service'; import { LanguageService, LanguageServiceContract } from './language_service'; import { ISearchInterceptor } from '../../search'; +import { getApplication } from '../../services'; export class QueryStringManager { private query$: BehaviorSubject; @@ -48,7 +50,8 @@ export class QueryStringManager { private readonly storage: DataStorage, private readonly sessionStorage: DataStorage, private readonly uiSettings: CoreStart['uiSettings'], - private readonly defaultSearchInterceptor: ISearchInterceptor + private readonly defaultSearchInterceptor: ISearchInterceptor, + private readonly notifications: NotificationsSetup ) { this.query$ = new BehaviorSubject(this.getDefaultQuery()); this.queryHistory = createHistory({ storage }); @@ -108,6 +111,40 @@ export class QueryStringManager { }; public getQuery = (): Query => { + const currentAppId = this.getCurrentAppId(); + const query = this.query$.getValue(); + + if (currentAppId) { + const currentLanguage = query.language; + if ( + containsWildcardOrValue( + this.languageService.getLanguage(currentLanguage)?.supportedAppNames, + currentAppId + ) + ) { + return this.query$.getValue(); + } + + const defaultLanguage = this.uiSettings.get('search:queryLanguage'); + const defaultLanguageTitle = this.languageService.getLanguage(defaultLanguage)?.title; + + showWarning(this.notifications, { + title: i18n.translate('data.unSupportedLanguageTitle', { + defaultMessage: 'Unsupported Language Selected', + }), + text: i18n.translate('data.unSupportedLanguageBody', { + defaultMessage: + 'Selected language {currentLanguage} is not supported. Defaulting to {defaultLanguage}.', + values: { + currentLanguage, + defaultLanguage: defaultLanguageTitle, + }, + }), + }); + + const updatedQuery = this.getInitialQueryByLanguage(defaultLanguage); + this.setQuery(updatedQuery); + } return this.query$.getValue(); }; @@ -194,6 +231,29 @@ export class QueryStringManager { this.uiSettings.get(UI_SETTINGS.SEARCH_QUERY_LANGUAGE) ); } + + private getCurrentAppId = () => { + let appId; + try { + const application = getApplication(); + if (application) { + application.currentAppId$.subscribe((val) => (appId = val)).unsubscribe(); + } + } catch (err) { + // eslint-disable-next-line no-console + console.log('Application Not available.'); + } + + return appId; + }; } +const showWarning = (notifications: NotificationsSetup, { title, text }) => { + notifications.toasts.addWarning({ title, text, id: 'unsupported_language_selected' }); +}; + +const containsWildcardOrValue = (arr: string[] | undefined, value: string) => { + return arr ? arr.includes('*') || arr.includes(value) : true; +}; + export type QueryStringContract = PublicMethodsOf; diff --git a/src/plugins/data/public/query/types.ts b/src/plugins/data/public/query/types.ts index dc59787c1637..86ef7fa7e8f6 100644 --- a/src/plugins/data/public/query/types.ts +++ b/src/plugins/data/public/query/types.ts @@ -7,6 +7,8 @@ import { ApplicationSetup, ApplicationStart, IUiSettingsClient, + NotificationsSetup, + NotificationsStart, SavedObjectsClientContract, } from 'opensearch-dashboards/public'; import { Observable } from 'rxjs'; @@ -44,6 +46,7 @@ export interface QueryServiceSetupDependencies { sessionStorage: DataStorage; defaultSearchInterceptor: ISearchInterceptor; application: ApplicationSetup; + notifications: NotificationsSetup; } /** @internal */ @@ -53,4 +56,5 @@ export interface QueryServiceStartDependencies { uiSettings: IUiSettingsClient; indexPatterns: IndexPatternsService; application: ApplicationStart; + notifications: NotificationsStart; } diff --git a/src/plugins/data/public/services.ts b/src/plugins/data/public/services.ts index d75dab2986ca..c042c2b6d9b8 100644 --- a/src/plugins/data/public/services.ts +++ b/src/plugins/data/public/services.ts @@ -28,7 +28,7 @@ * under the License. */ -import { NotificationsStart, CoreStart } from 'src/core/public'; +import { NotificationsStart, CoreStart, ApplicationStart } from 'src/core/public'; import { FieldFormatsStart } from './field_formats'; import { createGetterSetter } from '../../opensearch_dashboards_utils/public'; import { IndexPatternsContract } from './index_patterns'; @@ -61,3 +61,5 @@ export const [getSearchService, setSearchService] = createGetterSetter< >('Search'); export const [getUiService, setUiService] = createGetterSetter('Ui'); + +export const [getApplication, setApplication] = createGetterSetter('Application');