Skip to content

Commit

Permalink
Add data summary panel in discover (#8186) (#8264)
Browse files Browse the repository at this point in the history
* Add data summary panel in discover



* Fix UTs



* Add changelog



* Fix UTs



* Address comments



* Address comments



* Address comments



---------


(cherry picked from commit 8d52134)

Signed-off-by: Liyun Xiu <[email protected]>
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>
  • Loading branch information
1 parent f4fa767 commit 0515954
Show file tree
Hide file tree
Showing 27 changed files with 1,073 additions and 20 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/8186.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
feat:
- Add data summary panel in discover ([#8186](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/8186))
2 changes: 2 additions & 0 deletions src/plugins/data/common/data_frames/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import { SearchResponse } from 'elasticsearch';
import { BehaviorSubject } from 'rxjs';
import { IFieldType } from './fields';

export * from './_df_cache';
Expand All @@ -19,6 +20,7 @@ export interface DataFrameService {
get: () => IDataFrame | undefined;
set: (dataFrame: IDataFrame) => void;
clear: () => void;
df$: BehaviorSubject<IDataFrame | undefined>;
}

/**
Expand Down
30 changes: 27 additions & 3 deletions src/plugins/data/public/search/search_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
private searchInterceptor!: ISearchInterceptor;
private defaultSearchInterceptor!: ISearchInterceptor;
private usageCollector?: SearchUsageCollector;
private dataFrame$ = new BehaviorSubject<IDataFrame | undefined>(undefined);

constructor(private initializerContext: PluginInitializerContext<ConfigSchema>) {}

Expand Down Expand Up @@ -120,13 +121,31 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
expressions.registerFunction(aggShardDelay);
}

const dfService: DataFrameService = {
get: () => {
const df = this.dfCache.get();
this.dataFrame$.next(df);
return df;
},
set: (dataFrame: IDataFrame) => {
this.dfCache.set(dataFrame);
},
clear: () => {
if (this.dfCache.get() === undefined) return;
this.dfCache.clear();
this.dataFrame$.next(undefined);
},
df$: this.dataFrame$,
};

return {
aggs,
usageCollector: this.usageCollector!,
__enhance: (enhancements: SearchEnhancements) => {
this.searchInterceptor = enhancements.searchInterceptor;
},
getDefaultSearchInterceptor: () => this.defaultSearchInterceptor,
df: dfService,
};
}

Expand All @@ -152,16 +171,21 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {

const loadingCount$ = new BehaviorSubject(0);
http.addLoadingCountSource(loadingCount$);

const dfService: DataFrameService = {
get: () => this.dfCache.get(),
set: async (dataFrame: IDataFrame) => {
get: () => {
const df = this.dfCache.get();
this.dataFrame$.next(df);
return df;
},
set: (dataFrame: IDataFrame) => {
this.dfCache.set(dataFrame);
},
clear: () => {
if (this.dfCache.get() === undefined) return;
this.dfCache.clear();
this.dataFrame$.next(undefined);
},
df$: this.dataFrame$,
};

const searchSourceDependencies: SearchSourceDependencies = {
Expand Down
1 change: 1 addition & 0 deletions src/plugins/data/public/search/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export interface ISearchSetup {
*/
__enhance: (enhancements: SearchEnhancements) => void;
getDefaultSearchInterceptor: () => ISearchInterceptor;
df: DataFrameService;
}

/**
Expand Down
21 changes: 20 additions & 1 deletion src/plugins/data/public/ui/query_editor/query_editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
EuiText,
PopoverAnchorPosition,
} from '@elastic/eui';
import { BehaviorSubject } from 'rxjs';
import classNames from 'classnames';
import { isEqual } from 'lodash';
import React, { Component, createRef, RefObject } from 'react';
Expand Down Expand Up @@ -337,6 +336,25 @@ export default class QueryEditorUI extends Component<Props, State> {
return <QueryControls queryControls={queryControls} />;
};

private renderExtensionSearchBarButton = () => {
if (!this.extensionMap || Object.keys(this.extensionMap).length === 0) return null;
const sortedConfigs = Object.values(this.extensionMap).sort((a, b) => a.order - b.order);
return (
<>
{sortedConfigs.map((config) => {
return config.getSearchBarButton
? config.getSearchBarButton({
language: this.props.query.language,
onSelectLanguage: this.onSelectLanguage,
isCollapsed: this.state.isCollapsed,
setIsCollapsed: this.setIsCollapsed,
})
: null;
})}
</>
);
};

public render() {
const className = classNames(this.props.className);

Expand Down Expand Up @@ -455,6 +473,7 @@ export default class QueryEditorUI extends Component<Props, State> {
<EuiFlexGroup responsive={false} gutterSize="s" alignItems="center">
{this.renderQueryControls(languageEditor.TopBar.Controls)}
{!languageEditor.TopBar.Expanded && this.renderToggleIcon()}
{!languageEditor.TopBar.Expanded && this.renderExtensionSearchBarButton()}
{this.props.savedQueryManagement}
</EuiFlexGroup>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ export interface QueryEditorExtensionConfig {
* @returns The component the query editor extension.
*/
getBanner?: (dependencies: QueryEditorExtensionDependencies) => React.ReactElement | null;

getSearchBarButton?: (
dependencies: QueryEditorExtensionDependencies
) => React.ReactElement | null;
}
const QueryEditorExtensionPortal: React.FC<{ container: Element }> = (props) => {
if (!props.children) return null;
Expand Down
3 changes: 3 additions & 0 deletions src/plugins/query_enhancements/common/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export const configSchema = schema.object({
defaultValue: [{ language: 'PPL', agentConfig: 'os_query_assist_ppl' }],
}
),
summary: schema.object({
enabled: schema.boolean({ defaultValue: false }),
}),
}),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
* SPDX-License-Identifier: Apache-2.0
*/

export { QueryAssistParameters, QueryAssistResponse } from './types';
export { QueryAssistParameters, QueryAssistResponse, QueryAssistContextType } from './types';
6 changes: 6 additions & 0 deletions src/plugins/query_enhancements/common/query_assist/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ export interface QueryAssistParameters {
// for MDS
dataSourceId?: string;
}

export enum QueryAssistContextType {
QUESTION,
QUERY,
DATA,
}
3 changes: 2 additions & 1 deletion src/plugins/query_enhancements/opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"server": true,
"ui": true,
"requiredPlugins": ["data", "opensearchDashboardsReact", "opensearchDashboardsUtils", "savedObjects", "uiActions"],
"optionalPlugins": ["dataSource"]
"optionalPlugins": ["dataSource", "usageCollection"],
"configPath": ["queryEnhancements"]
}

11 changes: 11 additions & 0 deletions src/plugins/query_enhancements/public/assets/sparkle_hollow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions src/plugins/query_enhancements/public/assets/sparkle_mark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions src/plugins/query_enhancements/public/assets/sparkle_solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 7 additions & 2 deletions src/plugins/query_enhancements/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class QueryEnhancementsPlugin

public setup(
core: CoreSetup<QueryEnhancementsPluginStartDependencies>,
{ data }: QueryEnhancementsPluginSetupDependencies
{ data, usageCollection }: QueryEnhancementsPluginSetupDependencies
): QueryEnhancementsPluginSetup {
const { queryString } = data.query;
const pplSearchInterceptor = new PPLSearchInterceptor({
Expand Down Expand Up @@ -105,7 +105,12 @@ export class QueryEnhancementsPlugin

data.__enhance({
editor: {
queryEditorExtension: createQueryAssistExtension(core.http, data, this.config.queryAssist),
queryEditorExtension: createQueryAssistExtension(
core,
data,
this.config.queryAssist,
usageCollection
),
},
});

Expand Down
10 changes: 10 additions & 0 deletions src/plugins/query_enhancements/public/query_assist/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@
*/

.queryAssist {
&.queryAssist__summary {
margin-top: $euiSizeXS;
}

&.queryAssist__summary_banner {
/* stylelint-disable @osd/stylelint/no_restricted_values */
background: lightOrDarkTheme(linear-gradient(to left, #edf7ff, #f9f4ff), $euiColorEmptyShade);
padding: $euiSizeXS;
}

&.queryAssist__callout {
margin-top: $euiSizeXS;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@

export { QueryAssistBar } from './query_assist_bar';
export { QueryAssistBanner } from './query_assist_banner';
export { QueryAssistSummary } from './query_assist_summary';
export { QueryAssistButton } from './query_assist_button';
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { setData, setStorage } from '../../services';
import { useGenerateQuery } from '../hooks';
import { AgentError, ProhibitedQueryError } from '../utils';
import { QueryAssistInput } from './query_assist_input';
import { useQueryAssist } from '../hooks';

jest.mock('../../../../opensearch_dashboards_react/public', () => ({
useOpenSearchDashboards: jest.fn(),
Expand All @@ -25,6 +26,9 @@ jest.mock('../../../../opensearch_dashboards_react/public', () => ({

jest.mock('../hooks', () => ({
useGenerateQuery: jest.fn().mockReturnValue({ generateQuery: jest.fn(), loading: false }),
useQueryAssist: jest
.fn()
.mockReturnValue({ updateQuestion: jest.fn(), isQueryAssistCollapsed: false }),
}));

jest.mock('./query_assist_input', () => ({
Expand Down Expand Up @@ -86,6 +90,14 @@ describe('QueryAssistBar', () => {
expect(component.container).toBeEmptyDOMElement();
});

it('renders null if question assist is collapsed', () => {
useQueryAssist.mockReturnValueOnce({ updateQuestion: jest.fn(), isQueryAssistCollapsed: true });
const { component } = renderQueryAssistBar({
dependencies: { ...dependencies, isCollapsed: false },
});
expect(component.container).toBeEmptyDOMElement();
});

it('matches snapshot', () => {
const { component } = renderQueryAssistBar();
expect(component.container).toMatchSnapshot();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { getPersistedLog, AgentError, ProhibitedQueryError } from '../utils';
import { QueryAssistCallOut, QueryAssistCallOutType } from './call_outs';
import { QueryAssistInput } from './query_assist_input';
import { QueryAssistSubmitButton } from './submit_button';
import { useQueryAssist } from '../hooks';

interface QueryAssistInputProps {
dependencies: QueryEditorExtensionDependencies;
Expand All @@ -42,6 +43,7 @@ export const QueryAssistBar: React.FC<QueryAssistInputProps> = (props) => {
);
const selectedIndex = selectedDataset?.title;
const previousQuestionRef = useRef<string>();
const { updateQuestion, isQueryAssistCollapsed } = useQueryAssist();

useEffect(() => {
const subscription = queryString.getUpdates$().subscribe((query) => {
Expand All @@ -64,6 +66,7 @@ export const QueryAssistBar: React.FC<QueryAssistInputProps> = (props) => {
setAgentError(undefined);
previousQuestionRef.current = inputRef.current.value;
persistedLog.add(inputRef.current.value);
updateQuestion(inputRef.current.value);
const params: QueryAssistParameters = {
question: inputRef.current.value,
index: selectedIndex,
Expand All @@ -90,7 +93,7 @@ export const QueryAssistBar: React.FC<QueryAssistInputProps> = (props) => {
}
};

if (props.dependencies.isCollapsed) return null;
if (props.dependencies.isCollapsed || isQueryAssistCollapsed) return null;

return (
<EuiForm component="form" onSubmit={onSubmit} className="queryAssist queryAssist__form">
Expand Down
Loading

0 comments on commit 0515954

Please sign in to comment.