Skip to content
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

[Discover-next] Add query editor extensions #7034

Merged
merged 10 commits into from
Jun 20, 2024

Conversation

joshuali925
Copy link
Member

@joshuali925 joshuali925 commented Jun 14, 2024

Description

see #6894

This PR picks #6894, #6895, #6933, #6972 to main. Additionally,

A query editor extension can display a UI component above the query editor and/or a banner above the language selector. The component has the ability to read and write discover search bar states to enhance the search experience for users. The configuration is part of UI Enhancements.

export interface QueryEditorExtensionDependencies {
  /**
   * Currently selected index patterns.
   */
  indexPatterns?: Array<IIndexPattern | string>;
  /**
   * Currently selected data source.
   */
  dataSource?: DataSource;
  /**
   * Currently selected query language.
   */
  language: string;
}

export interface QueryEditorExtensionConfig {
  /**
   * The id for the search bar extension.
   */
  id: string;
  /**
   * Lower order indicates higher position on UI.
   */
  order: number;
  /**
   * A function that determines if the search bar extension is enabled and should be rendered on UI.
   * @returns whether the extension is enabled.
   */
  isEnabled: (dependencies: QueryEditorExtensionDependencies) => Promise<boolean>;
  /**
   * A function that returns the search bar extension component. The component
   * will be displayed on top of the query editor in the search bar.
   * @param dependencies - The dependencies required for the extension.
   * @returns The component the search bar extension.
   */
  getComponent?: (dependencies: QueryEditorExtensionDependencies) => React.ReactElement | null;
  /**
   * A function that returns the search bar extension banner. The banner is a
   * component that will be displayed on top of the search bar.
   * @param dependencies - The dependencies required for the extension.
   * @returns The component the search bar extension.
   */
  getBanner?: (dependencies: QueryEditorExtensionDependencies) => React.ReactElement | null;
}

export interface UiEnhancements {
  query?: QueryEnhancement;
+ queryEditorExtension?: QueryEditorExtensionConfig;
}

Issues Resolved

Developers can utilize search bar extensions to add additional features to the search bar, such as query assist.

Part of #6077

Screenshot

Testing the changes

Changelog

Check List

  • All tests pass
    • yarn test:jest
    • yarn test:jest_integration
  • New functionality includes testing.
  • New functionality has been documented.
  • Update CHANGELOG.md
  • Commits are signed per the DCO using --signoff

A search bar extension can display a UI component above the query bar. The component has the ability to read and write discover search bar states to enhance the search experience for users. The configuration is part of Query Enhancements.

```ts
export interface SearchBarExtensionDependencies {
  /**
   * Currently selected index patterns.
   */
  indexPatterns?: IIndexPattern[];
}

export interface SearchBarExtensionConfig {
  /**
   * The id for the search bar extension.
   */
  id: string;
  /**
   * Lower order indicates higher position on UI.
   */
  order: number;
  /**
   * A function that determines if the search bar extension is enabled and should be rendered on UI.
   * @returns whether the extension is enabled.
   */
  isEnabled: () => Promise<boolean>;
  /**
   * A function that returns the mount point for the search bar extension.
   * @param dependencies - The dependencies required for the extension.
   * @returns The mount point for the search bar extension.
   */
  getComponent: (dependencies: SearchBarExtensionDependencies) => React.ReactElement;
}

export interface QueryEnhancement {
  ...
  searchBar?: {
    ...
    extensions?: SearchBarExtensionConfig[];
  };
}

Signed-off-by: Joshua Li <joshuali925@gmail.com>
(cherry picked from commit e748e81)
…arch-project#6895)

it adds query assist specific logic in query enhancements plugin to show a UI above the PPL search bar if user has configured PPL agent.

Issues Resolved: opensearch-project#6820

* add query assist to query enhancements

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* align language to uppercase

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* pick PR 6167

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* use useState hooks for query assist

There is a bug in data explorer `AppContainer` where memorized
`DiscoverCanvas` gets unmounted after `setQuery`. PR 6167 works around
it by memorizing `AppContainer`. As query assist is no longer being
unmounted, we can use proper hooks to persist state now.

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* Revert "pick PR 6167"

This reverts commit acb0d41.

Wait for official 6167 to merge to avoid conflict

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* address comments for PR 6894

Signed-off-by: Joshua Li <joshuali925@gmail.com>

---------

Signed-off-by: Joshua Li <joshuali925@gmail.com>
(cherry picked from commit 016e0f2)
…assist (opensearch-project#6933)

* pass dependencies to isEnabled func

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* add lazy and memo to search bar extensions

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* move ppl specific string out from query assist

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* prevent setstate after hook unmounts

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* add max-height to search bar extensions

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* prevent setstate after component unmounts

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* move ml-commons API to common/index.ts

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* improve i18n and accessibility usages

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* add hard-coded suggestions for sample data indices

Signed-off-by: Joshua Li <joshuali925@gmail.com>

---------

Signed-off-by: Joshua Li <joshuali925@gmail.com>
(cherry picked from commit 4aade0f)
…ject#6972)

* disable query assist for non-default datasource

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* disable query assist input when loading

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* support MDS for query assist

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* add unit tests for agents

Signed-off-by: Joshua Li <joshuali925@gmail.com>

* Revert "add unit tests for agents"

This reverts commit 983514e.
The test configs are not yet setup in query_enhancements plugins.

Signed-off-by: Joshua Li <joshuali925@gmail.com>

---------

Signed-off-by: Joshua Li <joshuali925@gmail.com>
(cherry picked from commit 328e08e)
SearchBar extensions depend on the currently selected dataSource, which
depends on
opensearch-project#6833 to
be ported to main

Signed-off-by: Joshua Li <joshuali925@gmail.com>
Copy link
Contributor

ℹ️ Manual Changeset Creation Reminder

Please ensure manual commit for changeset file 7034.yml under folder changelogs/fragments to complete this PR.

If you want to use the available OpenSearch Changeset Bot App to avoid manual creation of changeset file you can install it in your forked repository following this link.

For more information about formatting of changeset files, please visit OpenSearch Auto Changeset and Release Notes Tool.

Signed-off-by: Joshua Li <joshuali925@gmail.com>
Copy link

codecov bot commented Jun 14, 2024

Codecov Report

Attention: Patch coverage is 75.75758% with 8 lines in your changes missing coverage. Please review.

Project coverage is 67.45%. Comparing base (a4aa682) to head (7f0e39e).
Report is 1 commits behind head on main.

Files Patch % Lines
src/plugins/data/public/ui/ui_service.ts 0.00% 3 Missing ⚠️
...query_editor_extensions/query_editor_extension.tsx 88.23% 0 Missing and 2 partials ⚠️
src/plugins/data/public/ui/settings/settings.ts 0.00% 2 Missing ⚠️
.../ui/query_editor/query_editor_extensions/index.tsx 75.00% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7034   +/-   ##
=======================================
  Coverage   67.44%   67.45%           
=======================================
  Files        3444     3447    +3     
  Lines       67865    67905   +40     
  Branches    11027    11034    +7     
=======================================
+ Hits        45772    45802   +30     
- Misses      19429    19436    +7     
- Partials     2664     2667    +3     
Flag Coverage Δ
Linux_1 33.07% <0.00%> (-0.01%) ⬇️
Linux_2 55.11% <ø> (ø)
Linux_3 45.26% <75.75%> (+0.03%) ⬆️
Linux_4 34.85% <0.00%> (-0.01%) ⬇️
Windows_1 33.09% <0.00%> (-0.01%) ⬇️
Windows_2 55.06% <ø> (ø)
Windows_3 45.27% <75.75%> (+0.03%) ⬆️
Windows_4 34.85% <0.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

To support bannar callout for query assist in un-supported languages and
notify user the feature, the search bar extensions need to be enabled
for all languages.

Signed-off-by: Joshua Li <joshuali925@gmail.com>
kavilla
kavilla previously approved these changes Jun 15, 2024
Copy link
Member

@kavilla kavilla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome !!! looks great.

have a couple comments and nits, but nothing blocking and could just be fast follows after merging this.

src/plugins/data/public/ui/ui_service.ts Outdated Show resolved Hide resolved
@@ -497,6 +496,7 @@ class SearchBarUI extends Component<SearchBarProps, State> {
screenTitle={this.props.screenTitle}
onSubmit={this.onQueryBarSubmit}
indexPatterns={this.props.indexPatterns}
dataSource={this.props.dataSource}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quick question: do we know if this will have to be reset if toggling this feature off?

like if the select a datasource and toggle it off and that data source isn't available that should be fine right? or do we think in the future we will need to reset it like how i do here: https://github.com/opensearch-project/OpenSearch-Dashboards/blob/main/src/plugins/data/public/ui/settings/settings.ts#L52.

this 100% makes sense to me as you have it right now so I don't think we should change this because it's being passed in like index Patterns. but if we do think there might be implications on the toggle on and then off again, might be worth renaming the UI Settings service to something to else to be more descriptive and reset all that stuff in that service.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not sure what the behavior would be, i wasn't able to test with data source too much. will need to revisit when we have the test environment

src/plugins/data/public/ui/settings/settings.ts Outdated Show resolved Hide resolved
src/plugins/data/public/index.ts Outdated Show resolved Hide resolved
* A function that determines if the search bar extension is enabled and should be rendered on UI.
* @returns whether the extension is enabled.
*/
isEnabled: (dependencies: SearchBarExtensionDependencies) => Promise<boolean>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should we consider making this a behavior subject? then appending $ like isEnabled$ might be easier to distinguish that i should subscribe to it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i haven't used observables much, a quick search tells me to use const isEnabled$ = (dependencies) => from(isEnabled(dependencies)); which i can't see what the benefit is. could you elaborate more a bit?

@kavilla
Copy link
Member

kavilla commented Jun 15, 2024

@joshuali925 you just have to install the bot: #7034 (comment) to your github then within the Changelog section of the PR description:, you can add the information in the correct format there and the changelog will automatically be generated with no manually requirement which we then use for the release notes generation. More info: #5519

Plugins should be able to onboard this too. s/o @BigSamu 🎆 this has been such a time saver.

move SearchBarExtensions to QueryEditorExtensions and change config
settings from list to map.

Signed-off-by: Joshua Li <joshuali925@gmail.com>
Signed-off-by: Joshua Li <joshuali925@gmail.com>
Signed-off-by: Joshua Li <joshuali925@gmail.com>
@joshuali925 joshuali925 marked this pull request as ready for review June 17, 2024 21:07
@joshuali925 joshuali925 changed the title [Discover-next] Add search bar extensions [Discover-next] Add query editor extensions Jun 19, 2024
const { configMap, componentContainer, bannerContainer, ...dependencies } = props;

const sortedConfigs = useMemo(() => {
if (!configMap || !Object.keys(configMap)) return [];
Copy link
Collaborator

@AMoo-Miki AMoo-Miki Jun 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Object.keys will either return an array or throw. ![] is false always. If this was meant to prevent wasting time on an empty object, it fails to do that.

Suggested change
if (!configMap || !Object.keys(configMap)) return [];
if ('[object Object]' !== Object.prototype.toString.call(configMap) || Object.keys(configMap).length === 0) return [];

This will need linting though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks good point on .length === 0, i missed that

is the object check necessary or conventional in OSD?

Comment on lines +257 to +262
if (
!shouldRenderQueryEditorExtensions() ||
!queryEditorHeaderRef.current ||
!queryEditorBannerRef.current ||
!queryLanguage
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: perf

Suggested change
if (
!shouldRenderQueryEditorExtensions() ||
!queryEditorHeaderRef.current ||
!queryEditorBannerRef.current ||
!queryLanguage
)
if (!(
queryEditorHeaderRef.current &&
queryEditorBannerRef.current &&
queryLanguage &&
shouldRenderQueryEditorExtensions()
))

@@ -282,6 +304,10 @@ export default function QueryEditorTopRow(props: QueryEditorTopRowProps) {
);
}

function shouldRenderQueryEditorExtensions(): boolean {
return Boolean(queryEditorExtensionMap && Object.keys(queryEditorExtensionMap).length);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we trust that queryEditorExtensionMap is going to be a plain object? I am not sure where it is coming from and hence asking: could it possibly be manipulated in the metadata store?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private queryEditorExtensionMap: Record<string, QueryEditorExtensionConfig> = {};

if (enhancements.queryEditorExtension) {
this.queryEditorExtensionMap[enhancements.queryEditorExtension.id] =
enhancements.queryEditorExtension;
}

what is the metadata store?

@@ -43,6 +45,10 @@ export class UiService implements Plugin<IUiSetup, IUiStart> {
if (enhancements.query && enhancements.query.language) {
this.queryEnhancements.set(enhancements.query.language, enhancements.query);
}
if (enhancements.queryEditorExtension) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this maybe be?

Suggested change
if (enhancements.queryEditorExtension) {
if (enhancements.queryEditorExtension?.id) {

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

id is enforced on the type level, is type checking not enough and we prefer to also add runtime checking in osd?

@kavilla
Copy link
Member

kavilla commented Jun 20, 2024

Since this is disabled as default and @AMoo-Miki not blocking. Feel free to add to this issue with fast follows: #6957 (comment) or create a new issue than you can handle fast follows from here.

@kavilla kavilla merged commit 4f54049 into opensearch-project:main Jun 20, 2024
69 checks passed
opensearch-trigger-bot bot pushed a commit that referenced this pull request Jun 20, 2024
### Description

see #6894

This PR picks #6894, #6895, #6933, #6972 to main. Additionally,
- separates extensions from query enhancements
- adds banner support
- partially revert #6972 as it's pending on the data source commit to main
- renames search bar extension to query editor extension

A query editor extension can display a UI component above the query editor and/or a banner above the language selector. The component has the ability to read and write discover search bar states to enhance the search experience for users. The configuration is part of UI Enhancements.

```ts
export interface QueryEditorExtensionDependencies {
  /**
   * Currently selected index patterns.
   */
  indexPatterns?: Array<IIndexPattern | string>;
  /**
   * Currently selected data source.
   */
  dataSource?: DataSource;
  /**
   * Currently selected query language.
   */
  language: string;
}

export interface QueryEditorExtensionConfig {
  /**
   * The id for the search bar extension.
   */
  id: string;
  /**
   * Lower order indicates higher position on UI.
   */
  order: number;
  /**
   * A function that determines if the search bar extension is enabled and should be rendered on UI.
   * @returns whether the extension is enabled.
   */
  isEnabled: (dependencies: QueryEditorExtensionDependencies) => Promise<boolean>;
  /**
   * A function that returns the search bar extension component. The component
   * will be displayed on top of the query editor in the search bar.
   * @param dependencies - The dependencies required for the extension.
   * @returns The component the search bar extension.
   */
  getComponent?: (dependencies: QueryEditorExtensionDependencies) => React.ReactElement | null;
  /**
   * A function that returns the search bar extension banner. The banner is a
   * component that will be displayed on top of the search bar.
   * @param dependencies - The dependencies required for the extension.
   * @returns The component the search bar extension.
   */
  getBanner?: (dependencies: QueryEditorExtensionDependencies) => React.ReactElement | null;
}

export interface UiEnhancements {
  query?: QueryEnhancement;
+ queryEditorExtension?: QueryEditorExtensionConfig;
}
```
Developers can utilize search bar extensions to add additional features to the search bar, such as query assist.

Issues resolved: #6077

A search bar extension can display a UI component above the query bar. The component has the ability to read and write discover search bar states to enhance the search experience for users. The configuration is part of Query Enhancements.

Signed-off-by: Joshua Li <joshuali925@gmail.com>
(cherry picked from commit 4f54049)
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Comment on lines +96 to +100
if (isMounted.current) setIsEnabled(enabled);
});
}, [props.dependencies, props.config]);

if (!isEnabled) return null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: use braces even for single line if statements

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this would be a good linter rule. I personally prefer one line if-returns, but i agree using braces is a better practice

i'll create an issue to track this and enable eslint curly, without linter there might be missed ones or mistakes

bannerContainer: Element;
}

const QueryEditorExtensions: React.FC<QueryEditorExtensionsProps> = React.memo((props) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: is there a better name for this given its both a collection of extensions as well as specifying their destinations (and its easy to confuse components that are one character apart). perhaps its a manager as its responsibilities could include managing what gets rendered if we want more rules than rendering everything

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe QueryEditorExtensionManager and QueryEditorExtension? but I'm not very sure if a manager is something that should be rendered on the page, current impl needs QueryEditor to render QueryEditorExtensions. The one character naming existed in other places, like suggestion_component and suggestions_component, although i do find it to be confusing

} from './query_editor_extension';

interface QueryEditorExtensionsProps extends QueryEditorExtensionDependencies {
configMap?: Record<string, QueryEditorExtensionConfig>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q: is there a reason this has to be a map vs an array?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consistency with existing code, see #7034 (comment)

kavilla pushed a commit that referenced this pull request Jun 22, 2024
### Description

see #6894

This PR picks #6894, #6895, #6933, #6972 to main. Additionally,
- separates extensions from query enhancements
- adds banner support
- partially revert #6972 as it's pending on the data source commit to main
- renames search bar extension to query editor extension

A query editor extension can display a UI component above the query editor and/or a banner above the language selector. The component has the ability to read and write discover search bar states to enhance the search experience for users. The configuration is part of UI Enhancements.

```ts
export interface QueryEditorExtensionDependencies {
  /**
   * Currently selected index patterns.
   */
  indexPatterns?: Array<IIndexPattern | string>;
  /**
   * Currently selected data source.
   */
  dataSource?: DataSource;
  /**
   * Currently selected query language.
   */
  language: string;
}

export interface QueryEditorExtensionConfig {
  /**
   * The id for the search bar extension.
   */
  id: string;
  /**
   * Lower order indicates higher position on UI.
   */
  order: number;
  /**
   * A function that determines if the search bar extension is enabled and should be rendered on UI.
   * @returns whether the extension is enabled.
   */
  isEnabled: (dependencies: QueryEditorExtensionDependencies) => Promise<boolean>;
  /**
   * A function that returns the search bar extension component. The component
   * will be displayed on top of the query editor in the search bar.
   * @param dependencies - The dependencies required for the extension.
   * @returns The component the search bar extension.
   */
  getComponent?: (dependencies: QueryEditorExtensionDependencies) => React.ReactElement | null;
  /**
   * A function that returns the search bar extension banner. The banner is a
   * component that will be displayed on top of the search bar.
   * @param dependencies - The dependencies required for the extension.
   * @returns The component the search bar extension.
   */
  getBanner?: (dependencies: QueryEditorExtensionDependencies) => React.ReactElement | null;
}

export interface UiEnhancements {
  query?: QueryEnhancement;
+ queryEditorExtension?: QueryEditorExtensionConfig;
}
```
Developers can utilize search bar extensions to add additional features to the search bar, such as query assist.

Issues resolved: #6077

A search bar extension can display a UI component above the query bar. The component has the ability to read and write discover search bar states to enhance the search experience for users. The configuration is part of Query Enhancements.


(cherry picked from commit 4f54049)

Signed-off-by: Joshua Li <joshuali925@gmail.com>
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
mengweieric pushed a commit to mengweieric/OpenSearch-Dashboards that referenced this pull request Jun 24, 2024
### Description

see opensearch-project#6894 

This PR picks opensearch-project#6894, opensearch-project#6895, opensearch-project#6933, opensearch-project#6972 to main. Additionally,
- separates extensions from query enhancements
- adds banner support
- partially revert opensearch-project#6972 as it's pending on the data source commit to main
- renames search bar extension to query editor extension

A query editor extension can display a UI component above the query editor and/or a banner above the language selector. The component has the ability to read and write discover search bar states to enhance the search experience for users. The configuration is part of UI Enhancements.

```ts
export interface QueryEditorExtensionDependencies {
  /**
   * Currently selected index patterns.
   */
  indexPatterns?: Array<IIndexPattern | string>;
  /**
   * Currently selected data source.
   */
  dataSource?: DataSource;
  /**
   * Currently selected query language.
   */
  language: string;
}

export interface QueryEditorExtensionConfig {
  /**
   * The id for the search bar extension.
   */
  id: string;
  /**
   * Lower order indicates higher position on UI.
   */
  order: number;
  /**
   * A function that determines if the search bar extension is enabled and should be rendered on UI.
   * @returns whether the extension is enabled.
   */
  isEnabled: (dependencies: QueryEditorExtensionDependencies) => Promise<boolean>;
  /**
   * A function that returns the search bar extension component. The component
   * will be displayed on top of the query editor in the search bar.
   * @param dependencies - The dependencies required for the extension.
   * @returns The component the search bar extension.
   */
  getComponent?: (dependencies: QueryEditorExtensionDependencies) => React.ReactElement | null;
  /**
   * A function that returns the search bar extension banner. The banner is a
   * component that will be displayed on top of the search bar.
   * @param dependencies - The dependencies required for the extension.
   * @returns The component the search bar extension.
   */
  getBanner?: (dependencies: QueryEditorExtensionDependencies) => React.ReactElement | null;
}

export interface UiEnhancements {
  query?: QueryEnhancement;
+ queryEditorExtension?: QueryEditorExtensionConfig;
}
```
Developers can utilize search bar extensions to add additional features to the search bar, such as query assist.

Issues resolved: opensearch-project#6077

A search bar extension can display a UI component above the query bar. The component has the ability to read and write discover search bar states to enhance the search experience for users. The configuration is part of Query Enhancements.

Signed-off-by: Joshua Li <joshuali925@gmail.com>
kavilla pushed a commit that referenced this pull request Jun 28, 2024
#7077)

Follow up for #7034, this PR
- addresses #7034 (comment)
- addresses #7034 (comment)
- fixes render order
   - QueryEditorExtensions requires the container divs to be mounted first,
but in the previous implementation, extensions will be mounted first and
it relied on rerendering of queryEditorTopRow. Moving them into query
editor fixes the render order and ensures refs are set.

@AMoo-Miki I didn't use the object check `'[object Object]' !== Object.prototype.toString.call(configMap)`. I don't know what access user has, but if an attacker can arbitrarily alter `configMap`, the code will still break with something like
```tsx
        configMap={
          new Proxy(
            {},
            {
              ownKeys(target) {
                throw new Error('Accessing keys is not allowed.');
              },
            }
          )
        }
```

Given that our code creates the config map here, I think relying on static type check is enough, but feel free to comment if otherwise.
https://github.com/opensearch-project/OpenSearch-Dashboards/blob/7f0e39eb9809c95b98069cc971611edc2cbbc62b/src/plugins/data/public/ui/ui_service.ts#L31

Signed-off-by: Joshua Li <joshuali925@gmail.com>
opensearch-trigger-bot bot pushed a commit that referenced this pull request Jul 1, 2024
#7077)

Follow up for #7034, this PR
- addresses #7034 (comment)
- addresses #7034 (comment)
- fixes render order
   - QueryEditorExtensions requires the container divs to be mounted first,
but in the previous implementation, extensions will be mounted first and
it relied on rerendering of queryEditorTopRow. Moving them into query
editor fixes the render order and ensures refs are set.

@AMoo-Miki I didn't use the object check `'[object Object]' !== Object.prototype.toString.call(configMap)`. I don't know what access user has, but if an attacker can arbitrarily alter `configMap`, the code will still break with something like
```tsx
        configMap={
          new Proxy(
            {},
            {
              ownKeys(target) {
                throw new Error('Accessing keys is not allowed.');
              },
            }
          )
        }
```

Given that our code creates the config map here, I think relying on static type check is enough, but feel free to comment if otherwise.
https://github.com/opensearch-project/OpenSearch-Dashboards/blob/7f0e39eb9809c95b98069cc971611edc2cbbc62b/src/plugins/data/public/ui/ui_service.ts#L31

Signed-off-by: Joshua Li <joshuali925@gmail.com>
(cherry picked from commit b85e177)
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
kavilla pushed a commit that referenced this pull request Jul 1, 2024
#7077) (#7140)

Follow up for #7034, this PR
- addresses #7034 (comment)
- addresses #7034 (comment)
- fixes render order
   - QueryEditorExtensions requires the container divs to be mounted first,
but in the previous implementation, extensions will be mounted first and
it relied on rerendering of queryEditorTopRow. Moving them into query
editor fixes the render order and ensures refs are set.

@AMoo-Miki I didn't use the object check `'[object Object]' !== Object.prototype.toString.call(configMap)`. I don't know what access user has, but if an attacker can arbitrarily alter `configMap`, the code will still break with something like
```tsx
        configMap={
          new Proxy(
            {},
            {
              ownKeys(target) {
                throw new Error('Accessing keys is not allowed.');
              },
            }
          )
        }
```

Given that our code creates the config map here, I think relying on static type check is enough, but feel free to comment if otherwise.
https://github.com/opensearch-project/OpenSearch-Dashboards/blob/7f0e39eb9809c95b98069cc971611edc2cbbc62b/src/plugins/data/public/ui/ui_service.ts#L31


(cherry picked from commit b85e177)

Signed-off-by: Joshua Li <joshuali925@gmail.com>
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Proposal] - Query assistance
6 participants