-
Notifications
You must be signed in to change notification settings - Fork 916
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support injecting DataStructureMeta
from QueryEditorExtensions
for Query Assist
#7871
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
91c47c8
fix query editor extensions enhance key
joshuali925 03dcec7
add query assist icons to clusters if available
joshuali925 555c299
allow custom icon for `DATA_STRUCTURE_META_TYPES.FEATURE`
joshuali925 bd43fd0
Changeset file for PR #7871 created/updated
opensearch-changeset-bot[bot] a249227
Merge branch 'main' into qa-ds-icon
ashwin-pc File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
feat: | ||
- Support injecting `DataStructureMeta` from `QueryEditorExtensions` for Query Assist ([#7871](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7871)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
src/plugins/data/public/query/query_string/dataset_service/lib/utils.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { DataStructure, DataStructureMeta } from '../../../../../common'; | ||
import { getQueryService } from '../../../../services'; | ||
|
||
/** | ||
* Inject {@link DataStructureMeta} to DataStructures based on | ||
* {@link QueryEditorExtensions}. | ||
* | ||
* This function combines the meta fields from QueryEditorExtensions and | ||
* provided data structures. Lower extension order is higher priority, and | ||
* existing meta fields have highest priority. | ||
* | ||
* @param dataStructures - {@link DataStructure} | ||
* @param selectDataSourceId - function to get data source id given a data structure | ||
* @returns data structures with meta | ||
*/ | ||
export const injectMetaToDataStructures = async ( | ||
dataStructures: DataStructure[], | ||
selectDataSourceId: (dataStructure: DataStructure) => string | undefined = ( | ||
dataStructure: DataStructure | ||
) => dataStructure.id | ||
) => { | ||
const queryEditorExtensions = Object.values( | ||
getQueryService().queryString.getLanguageService().getQueryEditorExtensionMap() | ||
); | ||
queryEditorExtensions.sort((a, b) => b.order - a.order); | ||
|
||
return Promise.all( | ||
dataStructures.map(async (dataStructure) => { | ||
const metaArray = await Promise.allSettled( | ||
queryEditorExtensions.map((curr) => | ||
curr.getDataStructureMeta?.(selectDataSourceId(dataStructure)) | ||
) | ||
).then((settledResults) => | ||
settledResults | ||
.filter( | ||
<T>(result: PromiseSettledResult<T>): result is PromiseFulfilledResult<T> => | ||
result.status === 'fulfilled' | ||
) | ||
.map((result) => result.value) | ||
); | ||
const meta = metaArray.reduce( | ||
(acc, curr) => (acc || curr ? ({ ...acc, ...curr } as DataStructureMeta) : undefined), | ||
undefined | ||
); | ||
if (meta || dataStructure.meta) { | ||
dataStructure.meta = { ...meta, ...dataStructure.meta } as DataStructureMeta; | ||
} | ||
return dataStructure; | ||
}) | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -95,7 +95,7 @@ export class QueryEnhancementsPlugin | |
queryString.getLanguageService().registerLanguage(sqlLanguageConfig); | ||
|
||
data.__enhance({ | ||
ui: { | ||
editor: { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry about that. Thanks for fixing. |
||
queryEditorExtension: createQueryAssistExtension(core.http, data, this.config.queryAssist), | ||
}, | ||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ | |
import { HttpSetup } from 'opensearch-dashboards/public'; | ||
import React, { useEffect, useState } from 'react'; | ||
import { distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators'; | ||
import { DEFAULT_DATA } from '../../../../data/common'; | ||
import { DATA_STRUCTURE_META_TYPES, DEFAULT_DATA } from '../../../../data/common'; | ||
import { | ||
DataPublicPluginSetup, | ||
QueryEditorExtensionConfig, | ||
|
@@ -15,16 +15,32 @@ | |
import { API } from '../../../common'; | ||
import { ConfigSchema } from '../../../common/config'; | ||
import { QueryAssistBanner, QueryAssistBar } from '../components'; | ||
import assistantMark from '../../assets/query_assist_mark.svg'; | ||
|
||
/** | ||
* @returns list of query assist supported languages for the given data source. | ||
*/ | ||
const getAvailableLanguagesForDataSource = (() => { | ||
const availableLanguagesByDataSource: Map<string | undefined, string[]> = new Map(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice way to cache the data |
||
return async (http: HttpSetup, dataSourceId: string | undefined) => { | ||
const cached = availableLanguagesByDataSource.get(dataSourceId); | ||
if (cached !== undefined) return cached; | ||
const languages = await http | ||
.get<{ configuredLanguages: string[] }>(API.QUERY_ASSIST.LANGUAGES, { | ||
query: { dataSourceId }, | ||
}) | ||
.then((response) => response.configuredLanguages) | ||
.catch(() => []); | ||
availableLanguagesByDataSource.set(dataSourceId, languages); | ||
return languages; | ||
}; | ||
})(); | ||
|
||
/** | ||
* @returns observable list of query assist agent configured languages in the | ||
* selected data source. | ||
*/ | ||
const getAvailableLanguages$ = ( | ||
availableLanguagesByDataSource: Map<string | undefined, string[]>, | ||
http: HttpSetup, | ||
data: DataPublicPluginSetup | ||
) => | ||
const getAvailableLanguages$ = (http: HttpSetup, data: DataPublicPluginSetup) => | ||
data.query.queryString.getUpdates$().pipe( | ||
startWith(data.query.queryString.getQuery()), | ||
distinctUntilChanged(), | ||
|
@@ -34,16 +50,7 @@ | |
if (query.dataset?.dataSource?.type !== DEFAULT_DATA.SOURCE_TYPES.OPENSEARCH) return []; | ||
|
||
const dataSourceId = query.dataset?.dataSource?.id; | ||
const cached = availableLanguagesByDataSource.get(dataSourceId); | ||
if (cached !== undefined) return cached; | ||
const languages = await http | ||
.get<{ configuredLanguages: string[] }>(API.QUERY_ASSIST.LANGUAGES, { | ||
query: { dataSourceId }, | ||
}) | ||
.then((response) => response.configuredLanguages) | ||
.catch(() => []); | ||
availableLanguagesByDataSource.set(dataSourceId, languages); | ||
return languages; | ||
return getAvailableLanguagesForDataSource(http, dataSourceId); | ||
}) | ||
); | ||
|
||
|
@@ -52,38 +59,35 @@ | |
data: DataPublicPluginSetup, | ||
config: ConfigSchema['queryAssist'] | ||
): QueryEditorExtensionConfig => { | ||
const availableLanguagesByDataSource: Map<string | undefined, string[]> = new Map(); | ||
|
||
return { | ||
id: 'query-assist', | ||
order: 1000, | ||
getDataStructureMeta: async (dataSourceId) => { | ||
const isEnabled = await getAvailableLanguagesForDataSource(http, dataSourceId).then( | ||
(languages) => languages.length > 0 | ||
); | ||
if (isEnabled) { | ||
return { | ||
type: DATA_STRUCTURE_META_TYPES.FEATURE, | ||
icon: { type: assistantMark }, | ||
tooltip: 'Query assist is available', | ||
}; | ||
} | ||
}, | ||
isEnabled$: () => | ||
getAvailableLanguages$(availableLanguagesByDataSource, http, data).pipe( | ||
map((languages) => languages.length > 0) | ||
), | ||
getAvailableLanguages$(http, data).pipe(map((languages) => languages.length > 0)), | ||
getComponent: (dependencies) => { | ||
// only show the component if user is on a supported language. | ||
return ( | ||
<QueryAssistWrapper | ||
availableLanguagesByDataSource={availableLanguagesByDataSource} | ||
dependencies={dependencies} | ||
http={http} | ||
data={data} | ||
> | ||
<QueryAssistWrapper dependencies={dependencies} http={http} data={data}> | ||
<QueryAssistBar dependencies={dependencies} /> | ||
</QueryAssistWrapper> | ||
); | ||
}, | ||
getBanner: (dependencies) => { | ||
// advertise query assist if user is not on a supported language. | ||
return ( | ||
<QueryAssistWrapper | ||
availableLanguagesByDataSource={availableLanguagesByDataSource} | ||
dependencies={dependencies} | ||
http={http} | ||
data={data} | ||
invert | ||
> | ||
<QueryAssistWrapper dependencies={dependencies} http={http} data={data} invert> | ||
<QueryAssistBanner | ||
dependencies={dependencies} | ||
languages={config.supportedLanguages.map((conf) => conf.language)} | ||
|
@@ -95,7 +99,6 @@ | |
}; | ||
|
||
interface QueryAssistWrapperProps { | ||
availableLanguagesByDataSource: Map<string | undefined, string[]>; | ||
dependencies: QueryEditorExtensionDependencies; | ||
http: HttpSetup; | ||
data: DataPublicPluginSetup; | ||
|
@@ -108,11 +111,7 @@ | |
useEffect(() => { | ||
let mounted = true; | ||
|
||
const subscription = getAvailableLanguages$( | ||
props.availableLanguagesByDataSource, | ||
props.http, | ||
props.data | ||
).subscribe((languages) => { | ||
const subscription = getAvailableLanguages$(props.http, props.data).subscribe((languages) => { | ||
const available = languages.includes(props.dependencies.language); | ||
if (mounted) setVisible(props.invert ? !available : available); | ||
}); | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ashwin-pc are we sure we don't want to do convert the dataset config to a class.
I was thinking it would be similar to the the interceptor class:
https://github.com/opensearch-project/OpenSearch-Dashboards/blob/main/src/plugins/data/public/search/search_interceptor.ts#L57
This way we don't have to ensure developers import this in their configs.
@joshuali925 could implement this in the base class and then it would be available for classes that extend the base class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree. will think about it later, right now just trying to add instead of refactor..