Skip to content

Commit

Permalink
[Multiple DataSource] Integrate multiple datasource with dev tool con…
Browse files Browse the repository at this point in the history
…sole (#3754) (#3802)

* [Multiple DataSource] Integrate multiple datasource with dev tool console
* update to support autocomplete when datasource is selected

Signed-off-by: Su <szhongna@amazon.com>
(cherry picked from commit a6af77d)
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

# Conflicts:
#	CHANGELOG.md

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
1 parent ca5cbae commit ce29555
Show file tree
Hide file tree
Showing 24 changed files with 338 additions and 104 deletions.
4 changes: 4 additions & 0 deletions src/core/public/application/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,10 @@ export interface AppMountParameters<HistoryLocationState = unknown> {
* ```
*/
setHeaderActionMenu: (menuMount: MountPoint | undefined) => void;
/**
* Optional datasource id to pass while mounting app
*/
dataSourceId?: string;
}

/**
Expand Down
9 changes: 7 additions & 2 deletions src/plugins/console/opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
"server": true,
"ui": true,
"requiredPlugins": ["devTools"],
"optionalPlugins": ["usageCollection", "home"],
"requiredBundles": ["opensearchUiShared", "opensearchDashboardsReact", "opensearchDashboardsUtils", "home"]
"optionalPlugins": ["usageCollection", "home", "dataSource"],
"requiredBundles": [
"opensearchUiShared",
"opensearchDashboardsReact",
"opensearchDashboardsUtils",
"home"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,36 +28,50 @@
* under the License.
*/

import React, { useCallback, memo } from 'react';
import React, { useCallback, memo, useEffect } from 'react';
import { debounce } from 'lodash';
import { EuiProgress } from '@elastic/eui';

import { EditorContentSpinner } from '../../components';
import { Panel, PanelsContainer } from '../../../../../opensearch_dashboards_react/public';
import { Editor as EditorUI, EditorOutput } from './legacy/console_editor';
import { StorageKeys } from '../../../services';
import { useEditorReadContext, useServicesContext, useRequestReadContext } from '../../contexts';
import {
useEditorReadContext,
useServicesContext,
useRequestReadContext,
useRequestActionContext,
} from '../../contexts';

const INITIAL_PANEL_WIDTH = 50;
const PANEL_MIN_WIDTH = '100px';

interface Props {
loading: boolean;
dataSourceId?: string;
}

export const Editor = memo(({ loading }: Props) => {
export const Editor = memo(({ loading, dataSourceId }: Props) => {
const {
services: { storage },
} = useServicesContext();

const { currentTextObject } = useEditorReadContext();
const { requestInFlight } = useRequestReadContext();
const dispatch = useRequestActionContext();

const [firstPanelWidth, secondPanelWidth] = storage.get(StorageKeys.WIDTH, [
INITIAL_PANEL_WIDTH,
INITIAL_PANEL_WIDTH,
]);

useEffect(() => {
dispatch({
type: 'resetLastResult',
payload: undefined,
});
}, [dispatch, dataSourceId]);

/* eslint-disable-next-line react-hooks/exhaustive-deps */
const onPanelWidthChange = useCallback(
debounce((widths: number[]) => {
Expand All @@ -83,7 +97,7 @@ export const Editor = memo(({ loading }: Props) => {
{loading ? (
<EditorContentSpinner />
) : (
<EditorUI initialTextValue={currentTextObject.text} />
<EditorUI initialTextValue={currentTextObject.text} dataSourceId={dataSourceId} />
)}
</Panel>
<Panel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const { useUIAceKeyboardMode } = ace;

export interface EditorProps {
initialTextValue: string;
dataSourceId?: string;
}

interface QueryParams {
Expand All @@ -76,15 +77,15 @@ const DEFAULT_INPUT_VALUE = `GET _search

const inputId = 'ConAppInputTextarea';

function EditorUI({ initialTextValue }: EditorProps) {
function EditorUI({ initialTextValue, dataSourceId }: EditorProps) {
const {
services: { history, notifications, settings: settingsService, opensearchHostService, http },
docLinkVersion,
} = useServicesContext();

const { settings } = useEditorReadContext();
const setInputEditor = useSetInputEditor();
const sendCurrentRequestToOpenSearch = useSendCurrentRequestToOpenSearch();
const sendCurrentRequestToOpenSearch = useSendCurrentRequestToOpenSearch(dataSourceId);
const saveCurrentTextObject = useSaveCurrentTextObject();

const editorRef = useRef<HTMLDivElement | null>(null);
Expand Down Expand Up @@ -184,7 +185,12 @@ function EditorUI({ initialTextValue }: EditorProps) {
setInputEditor(editor);
setTextArea(editorRef.current!.querySelector('textarea'));

retrieveAutoCompleteInfo(http, settingsService, settingsService.getAutocomplete());
retrieveAutoCompleteInfo(
http,
settingsService,
settingsService.getAutocomplete(),
dataSourceId
);

const unsubscribeResizer = subscribeResizeChecker(editorRef.current!, editor);
setupAutosave();
Expand All @@ -197,7 +203,15 @@ function EditorUI({ initialTextValue }: EditorProps) {
editorInstanceRef.current.getCoreEditor().destroy();
}
};
}, [saveCurrentTextObject, initialTextValue, history, setInputEditor, settingsService, http]);
}, [
saveCurrentTextObject,
initialTextValue,
history,
setInputEditor,
settingsService,
http,
dataSourceId,
]);

useEffect(() => {
const { current: editor } = editorInstanceRef;
Expand Down
14 changes: 10 additions & 4 deletions src/plugins/console/public/application/containers/main/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
* under the License.
*/

import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { i18n } from '@osd/i18n';
import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiPageContent } from '@elastic/eui';
import { ConsoleHistory } from '../console_history';
Expand All @@ -48,7 +48,11 @@ import { useDataInit } from '../../hooks';

import { getTopNavConfig } from './get_top_nav';

export function Main() {
interface MainProps {
dataSourceId?: string;
}

export function Main({ dataSourceId }: MainProps) {
const {
services: { storage },
} = useServicesContext();
Expand Down Expand Up @@ -130,7 +134,7 @@ export function Main() {
</EuiFlexItem>
{showingHistory ? <EuiFlexItem grow={false}>{renderConsoleHistory()}</EuiFlexItem> : null}
<EuiFlexItem>
<Editor loading={!done} />
<Editor loading={!done} dataSourceId={dataSourceId} />
</EuiFlexItem>
</EuiFlexGroup>

Expand All @@ -143,7 +147,9 @@ export function Main() {
/>
) : null}

{showSettings ? <Settings onClose={() => setShowSettings(false)} /> : null}
{showSettings ? (
<Settings onClose={() => setShowSettings(false)} dataSourceId={dataSourceId} />
) : null}

{showHelp ? <HelpPanel onClose={() => setShowHelp(false)} /> : null}
</div>
Expand Down
14 changes: 8 additions & 6 deletions src/plugins/console/public/application/containers/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ const getAutocompleteDiff = (newSettings: DevToolsSettings, prevSettings: DevToo
const refreshAutocompleteSettings = (
http: HttpSetup,
settings: SettingsService,
selectedSettings: any
selectedSettings: any,
dataSourceId?: string
) => {
retrieveAutoCompleteInfo(http, settings, selectedSettings);
retrieveAutoCompleteInfo(http, settings, selectedSettings, dataSourceId);
};

const fetchAutocompleteSettingsIfNeeded = (
Expand Down Expand Up @@ -79,19 +80,20 @@ const fetchAutocompleteSettingsIfNeeded = (
},
{}
);
retrieveAutoCompleteInfo(http, settings, changedSettings);
retrieveAutoCompleteInfo(http, settings, changedSettings, dataSourceId);
} else if (isPollingChanged && newSettings.polling) {
// If the user has turned polling on, then we'll fetch all selected autocomplete settings.
retrieveAutoCompleteInfo(http, settings, settings.getAutocomplete());
retrieveAutoCompleteInfo(http, settings, settings.getAutocomplete(), dataSourceId);
}
}
};

export interface Props {
onClose: () => void;
dataSourceId?: string;
}

export function Settings({ onClose }: Props) {
export function Settings({ onClose, dataSourceId }: Props) {
const {
services: { settings, http },
} = useServicesContext();
Expand All @@ -118,7 +120,7 @@ export function Settings({ onClose }: Props) {
onClose={onClose}
onSaveSettings={onSaveSettings}
refreshAutocompleteSettings={(selectedSettings: any) =>
refreshAutocompleteSettings(http, settings, selectedSettings)
refreshAutocompleteSettings(http, settings, selectedSettings, dataSourceId)
}
settings={settings.toJSON()}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { BaseResponseType } from '../../../types';
export interface OpenSearchRequestArgs {
http: HttpSetup;
requests: any;
dataSourceId?: string;
}

export interface OpenSearchRequestObject {
Expand Down Expand Up @@ -101,7 +102,8 @@ export function sendRequestToOpenSearch(
args.http,
opensearchMethod,
opensearchPath,
opensearchData
opensearchData,
args.dataSourceId
);
if (reqId !== CURRENT_REQ_ID) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { track } from './track';
// @ts-ignore
import { retrieveAutoCompleteInfo } from '../../../lib/mappings/mappings';

export const useSendCurrentRequestToOpenSearch = () => {
export const useSendCurrentRequestToOpenSearch = (dataSourceId?: string) => {
const {
services: { history, settings, notifications, trackUiMetric, http },
} = useServicesContext();
Expand All @@ -64,7 +64,7 @@ export const useSendCurrentRequestToOpenSearch = () => {
// Fire and forget
setTimeout(() => track(requests, editor, trackUiMetric), 0);

const results = await sendRequestToOpenSearch({ http, requests });
const results = await sendRequestToOpenSearch({ http, requests, dataSourceId });

results.forEach(({ request: { path, method, data } }) => {
try {
Expand All @@ -85,7 +85,7 @@ export const useSendCurrentRequestToOpenSearch = () => {
// or templates may have changed, so we'll need to update this data. Assume that if
// the user disables polling they're trying to optimize performance or otherwise
// preserve resources, so they won't want this request sent either.
retrieveAutoCompleteInfo(http, settings, settings.getAutocomplete());
retrieveAutoCompleteInfo(http, settings, settings.getAutocomplete(), dataSourceId);
}

dispatch({
Expand All @@ -112,5 +112,5 @@ export const useSendCurrentRequestToOpenSearch = () => {
});
}
}
}, [dispatch, settings, history, notifications, trackUiMetric, http]);
}, [dispatch, http, dataSourceId, settings, notifications.toasts, trackUiMetric, history]);
};
4 changes: 3 additions & 1 deletion src/plugins/console/public/application/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export interface BootDependencies {
notifications: NotificationsSetup;
usageCollection?: UsageCollectionSetup;
element: HTMLElement;
dataSourceId?: string;
}

export function renderApp({
Expand All @@ -55,6 +56,7 @@ export function renderApp({
usageCollection,
element,
http,
dataSourceId,
}: BootDependencies) {
const trackUiMetric = createUsageTracker(usageCollection);
trackUiMetric.load('opened_app');
Expand Down Expand Up @@ -88,7 +90,7 @@ export function renderApp({
>
<RequestContextProvider>
<EditorContextProvider settings={settings.toJSON()}>
<Main />
<Main dataSourceId={dataSourceId} />
</EditorContextProvider>
</RequestContextProvider>
</ServicesContextProvider>
Expand Down
10 changes: 9 additions & 1 deletion src/plugins/console/public/application/stores/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ import { OpenSearchRequestResult } from '../hooks/use_send_current_request_to_op
export type Actions =
| { type: 'sendRequest'; payload: undefined }
| { type: 'requestSuccess'; payload: { data: OpenSearchRequestResult[] } }
| { type: 'requestFail'; payload: OpenSearchRequestResult<string> | undefined };
| { type: 'requestFail'; payload: OpenSearchRequestResult<string> | undefined }
| { type: 'resetLastResult'; payload: undefined };

export interface Store {
requestInFlight: boolean;
Expand Down Expand Up @@ -79,4 +80,11 @@ export const reducer: Reducer<Store, Actions> = (state, action) =>
draft.lastResult = { ...initialResultValue, error: action.payload };
return;
}

if (action.type === 'resetLastResult') {
draft.lastResult = initialResultValue;
return;
}

return draft;
});
Loading

0 comments on commit ce29555

Please sign in to comment.