Skip to content

Commit

Permalink
[Discover-next] add datasource container
Browse files Browse the repository at this point in the history
Enables the editor to let plugins to mount their own data source component
to the data source container.

Issue partially resolved:
opensearch-project#7129

Signed-off-by: Kawika Avilla <[email protected]>
  • Loading branch information
kavilla committed Jul 2, 2024
1 parent 5212f09 commit 2a59f2a
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 7 deletions.
16 changes: 16 additions & 0 deletions src/plugins/data/public/ui/query_editor/_query_editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@
}

.osdQueryEditor__dataSourceWrapper {
.dataSourceSelect {
border-bottom: $euiBorderThin !important;

:first-child {
box-shadow: none !important;
height: 100%;
border-radius: 0;
}

div:is([class$="--group"]) {
padding: 0 !important;
}
}
}

.osdQueryEditor__dataSetWrapper {
.dataExplorerDSSelect {
border-bottom: $euiBorderThin !important;

Expand Down
31 changes: 26 additions & 5 deletions src/plugins/data/public/ui/query_editor/query_editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface QueryEditorProps {
indexPatterns: Array<IIndexPattern | string>;
dataSource?: DataSource;
query: Query;
dataSourceContainerRef?: React.RefCallback<HTMLDivElement>;
containerRef?: React.RefCallback<HTMLDivElement>;
settings: Settings;
disableAutoFocus?: boolean;
Expand Down Expand Up @@ -54,6 +55,7 @@ interface Props extends QueryEditorProps {

interface State {
isDataSourcesVisible: boolean;
isDataSetsVisible: boolean;
isSuggestionsVisible: boolean;
index: number | null;
suggestions: QuerySuggestion[];
Expand All @@ -77,7 +79,8 @@ const KEY_CODES = {
// eslint-disable-next-line import/no-default-export
export default class QueryEditorUI extends Component<Props, State> {
public state: State = {
isDataSourcesVisible: true,
isDataSourcesVisible: false,
isDataSetsVisible: true,
isSuggestionsVisible: false,
index: null,
suggestions: [],
Expand Down Expand Up @@ -212,7 +215,10 @@ export default class QueryEditorUI extends Component<Props, State> {
: undefined;
this.onChange(newQuery, dateRange);
this.onSubmit(newQuery, dateRange);
this.setState({ isDataSourcesVisible: enhancement?.searchBar?.showDataSourceSelector ?? true });
this.setState({ isDataSetsVisible: enhancement?.searchBar?.showDataSetsSelector ?? true });
this.setState({
isDataSourcesVisible: enhancement?.searchBar?.showDataSourcesSelector ?? true,
});
};

private initPersistedLog = () => {
Expand All @@ -227,10 +233,19 @@ export default class QueryEditorUI extends Component<Props, State> {

const isDataSourcesVisible =
this.props.settings.getQueryEnhancements(this.props.query.language)?.searchBar
?.showDataSourceSelector ?? true;
?.showDataSourcesSelector ?? true;
this.setState({ isDataSourcesVisible });
};

private initDataSetsVisibility = () => {
if (this.componentIsUnmounting) return;

const isDataSetsVisible =
this.props.settings.getQueryEnhancements(this.props.query.language)?.searchBar
?.showDataSetsSelector ?? true;
this.setState({ isDataSetsVisible });
};

public onMouseEnterSuggestion = (index: number) => {
this.setState({ index });
};
Expand All @@ -246,6 +261,7 @@ export default class QueryEditorUI extends Component<Props, State> {
this.initPersistedLog();
// this.fetchIndexPatterns().then(this.updateSuggestions);
this.initDataSourcesVisibility();
this.initDataSetsVisibility();
}

public componentDidUpdate(prevProps: Props) {
Expand Down Expand Up @@ -280,6 +296,11 @@ export default class QueryEditorUI extends Component<Props, State> {
<EuiFlexItem grow={false}>
<EuiFlexGroup gutterSize="xs" alignItems="center" className={`${className}__wrapper`}>
<EuiFlexItem grow={false}>{this.props.prepend}</EuiFlexItem>
{this.state.isDataSourcesVisible && (
<EuiFlexItem grow={false} className={`${className}__dataSourceWrapper`}>
<div ref={this.props.dataSourceContainerRef} />
</EuiFlexItem>
)}
<EuiFlexItem grow={false} className={`${className}__languageWrapper`}>
<QueryLanguageSelector
language={this.props.query.language}
Expand All @@ -288,8 +309,8 @@ export default class QueryEditorUI extends Component<Props, State> {
appName={this.services.appName}
/>
</EuiFlexItem>
{this.state.isDataSourcesVisible && (
<EuiFlexItem grow={false} className={`${className}__dataSourceWrapper`}>
{this.state.isDataSetsVisible && (
<EuiFlexItem grow={false} className={`${className}__dataSetWrapper`}>
<div ref={this.props.containerRef} />
</EuiFlexItem>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
} from '@elastic/eui';
import classNames from 'classnames';
import { compact, isEqual } from 'lodash';
import React, { useRef, useState } from 'react';
import React, { useState } from 'react';
import {
DataSource,
IDataPluginServices,
Expand All @@ -38,6 +38,7 @@ const QueryEditor = withOpenSearchDashboards(QueryEditorUI);
// @internal
export interface QueryEditorTopRowProps {
query?: Query;
dataSourceContainerRef?: React.RefCallback<HTMLDivElement>;
containerRef?: React.RefCallback<HTMLDivElement>;
settings?: Settings;
onSubmit: (payload: { dateRange: TimeRange; query?: Query }) => void;
Expand Down Expand Up @@ -234,6 +235,7 @@ export default function QueryEditorTopRow(props: QueryEditorTopRowProps) {
dataSource={props.dataSource}
prepend={props.prepend}
query={parsedQuery}
dataSourceContainerRef={props.dataSourceContainerRef}
containerRef={props.containerRef}
settings={props.settings!}
screenTitle={props.screenTitle}
Expand Down
9 changes: 9 additions & 0 deletions src/plugins/data/public/ui/search_bar/create_search_bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ interface StatefulSearchBarDeps {
data: Omit<DataPublicPluginStart, 'ui'>;
storage: IStorageWrapper;
settings: Settings;
setDataSourceContainerRef: (ref: HTMLDivElement | null) => void;
setContainerRef: (ref: HTMLDivElement | null) => void;
}

Expand Down Expand Up @@ -138,6 +139,7 @@ export function createSearchBar({
storage,
data,
settings,
setDataSourceContainerRef,
setContainerRef,
}: StatefulSearchBarDeps) {
// App name should come from the core application service.
Expand Down Expand Up @@ -174,6 +176,12 @@ export function createSearchBar({
notifications: core.notifications,
});

const dataSourceContainerRef = useCallback((node) => {
if (node) {
setDataSourceContainerRef(node);
}
}, []);

const containerRef = useCallback((node) => {
if (node) {
setContainerRef(node);
Expand Down Expand Up @@ -220,6 +228,7 @@ export function createSearchBar({
filters={filters}
query={query}
settings={settings}
dataSourceContainerRef={dataSourceContainerRef}
containerRef={containerRef}
onFiltersUpdated={defaultFiltersUpdated(data.query)}
onRefreshChange={defaultOnRefreshChange(data.query)}
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/data/public/ui/search_bar/search_bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export interface SearchBarOwnProps {
// Query bar - should be in SearchBarInjectedDeps
query?: Query;
settings?: Settings;
dataSourceContainerRef?: React.RefCallback<HTMLDivElement>;
containerRef?: React.RefCallback<HTMLDivElement>;
// Show when user has privileges to save
showSaveQuery?: boolean;
Expand Down Expand Up @@ -490,6 +491,7 @@ class SearchBarUI extends Component<SearchBarProps, State> {
queryEditor = (
<QueryEditorTopRow
timeHistory={this.props.timeHistory}
dataSourceContainerRef={this.props.dataSourceContainerRef}
containerRef={this.props.containerRef}
settings={this.props.settings}
query={this.state.query}
Expand Down
4 changes: 3 additions & 1 deletion src/plugins/data/public/ui/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export interface QueryEnhancement {
// Leave blank to support all data sources
// supportedDataSourceTypes?: Record<string, GenericDataSource>;
searchBar?: {
showDataSourceSelector?: boolean;
showDataSetsSelector?: boolean;
showDataSourcesSelector?: boolean;
showQueryInput?: boolean;
showFilterBar?: boolean;
showDatePicker?: boolean;
Expand Down Expand Up @@ -66,5 +67,6 @@ export interface IUiStart {
SearchBar: React.ComponentType<StatefulSearchBarProps>;
SuggestionsComponent: React.ComponentType<SuggestionsComponentProps>;
Settings: Settings;
dataSourceContainer$: Observable<HTMLDivElement | null>;
container$: Observable<HTMLDivElement | null>;
}
7 changes: 7 additions & 0 deletions src/plugins/data/public/ui/ui_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class UiService implements Plugin<IUiSetup, IUiStart> {
enhancementsConfig: ConfigSchema['enhancements'];
private queryEnhancements: Map<string, QueryEnhancement> = new Map();
private queryEditorExtensionMap: Record<string, QueryEditorExtensionConfig> = {};
private dataSourceContainer$ = new BehaviorSubject<HTMLDivElement | null>(null);
private container$ = new BehaviorSubject<HTMLDivElement | null>(null);

constructor(initializerContext: PluginInitializerContext<ConfigSchema>) {
Expand Down Expand Up @@ -62,6 +63,10 @@ export class UiService implements Plugin<IUiSetup, IUiStart> {
queryEditorExtensionMap: this.queryEditorExtensionMap,
});

const setDataSourceContainerRef = (ref: HTMLDivElement | null) => {
this.dataSourceContainer$.next(ref);
};

const setContainerRef = (ref: HTMLDivElement | null) => {
this.container$.next(ref);
};
Expand All @@ -71,6 +76,7 @@ export class UiService implements Plugin<IUiSetup, IUiStart> {
data: dataServices,
storage,
settings: Settings,
setDataSourceContainerRef,
setContainerRef,
});

Expand All @@ -79,6 +85,7 @@ export class UiService implements Plugin<IUiSetup, IUiStart> {
SearchBar,
SuggestionsComponent,
Settings,
dataSourceContainer$: this.dataSourceContainer$,
container$: this.container$,
};
}
Expand Down

0 comments on commit 2a59f2a

Please sign in to comment.