mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Console Monaco migration] Implement history (#183181)
## Summary
Fixes https://github.com/elastic/kibana/issues/182948
This PR migrates history component from ace to monaco and re-implements
the logic to insert the saved requests into the monaco editor.
To test:
1. click the "History" tab and check that the component is using Monaco
to display requests
2. Check that "Clear history" button works
3. Check that a request from history can be inserted into the editor
- when the cursor is on the 1st line of the request, the history request
is inserted before the request in the editor
- if the cursor is not on the 1st line of the request, the history
request is inserted after the request in the editor
### Screen recording
6031ee6a
-8211-4ca7-96d7-3aafbaee0509
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
7e21a1e130
commit
9194c8857c
14 changed files with 419 additions and 39 deletions
|
@ -23,6 +23,7 @@ import {
|
|||
|
||||
import { useServicesContext } from '../../contexts';
|
||||
import { HistoryViewer } from './history_viewer';
|
||||
import { HistoryViewer as HistoryViewerMonaco } from './history_viewer_monaco';
|
||||
import { useEditorReadContext } from '../../contexts/editor_context';
|
||||
import { useRestoreRequestFromHistory } from '../../hooks';
|
||||
|
||||
|
@ -35,6 +36,7 @@ const CHILD_ELEMENT_PREFIX = 'historyReq';
|
|||
export function ConsoleHistory({ close }: Props) {
|
||||
const {
|
||||
services: { history },
|
||||
config: { isMonacoEnabled },
|
||||
} = useServicesContext();
|
||||
|
||||
const { settings: readOnlySettings } = useEditorReadContext();
|
||||
|
@ -91,7 +93,7 @@ export function ConsoleHistory({ close }: Props) {
|
|||
initialize();
|
||||
};
|
||||
|
||||
const restoreRequestFromHistory = useRestoreRequestFromHistory();
|
||||
const restoreRequestFromHistory = useRestoreRequestFromHistory(isMonacoEnabled);
|
||||
|
||||
useEffect(() => {
|
||||
initialize();
|
||||
|
@ -181,7 +183,11 @@ export function ConsoleHistory({ close }: Props) {
|
|||
|
||||
<div className="conHistory__body__spacer" />
|
||||
|
||||
<HistoryViewer settings={readOnlySettings} req={viewingReq} />
|
||||
{isMonacoEnabled ? (
|
||||
<HistoryViewerMonaco settings={readOnlySettings} req={viewingReq} />
|
||||
) : (
|
||||
<HistoryViewer settings={readOnlySettings} req={viewingReq} />
|
||||
)}
|
||||
</div>
|
||||
|
||||
<EuiSpacer size="s" />
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useRef } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import { CONSOLE_LANG_ID, CONSOLE_THEME_ID, monaco } from '@kbn/monaco';
|
||||
import { CodeEditor } from '@kbn/code-editor';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { formatRequestBodyDoc } from '../../../lib/utils';
|
||||
import { DevToolsSettings } from '../../../services';
|
||||
import { useResizeCheckerUtils } from '../editor/monaco/hooks';
|
||||
|
||||
export const HistoryViewer = ({
|
||||
settings,
|
||||
req,
|
||||
}: {
|
||||
settings: DevToolsSettings;
|
||||
req: { method: string; endpoint: string; data: string; time: string } | null;
|
||||
}) => {
|
||||
const divRef = useRef<HTMLDivElement | null>(null);
|
||||
const { setupResizeChecker, destroyResizeChecker } = useResizeCheckerUtils();
|
||||
|
||||
const editorDidMountCallback = useCallback(
|
||||
(editor: monaco.editor.IStandaloneCodeEditor) => {
|
||||
setupResizeChecker(divRef.current!, editor);
|
||||
},
|
||||
[setupResizeChecker]
|
||||
);
|
||||
|
||||
const editorWillUnmountCallback = useCallback(() => {
|
||||
destroyResizeChecker();
|
||||
}, [destroyResizeChecker]);
|
||||
let renderedHistoryRequest: string;
|
||||
if (req) {
|
||||
const indent = true;
|
||||
const formattedData = req.data ? formatRequestBodyDoc([req.data], indent).data : '';
|
||||
renderedHistoryRequest = req.method + ' ' + req.endpoint + '\n' + formattedData;
|
||||
} else {
|
||||
renderedHistoryRequest = i18n.translate('console.historyPage.noHistoryTextMessage', {
|
||||
defaultMessage: 'No history available',
|
||||
});
|
||||
}
|
||||
return (
|
||||
<div
|
||||
css={css`
|
||||
width: 100%;
|
||||
`}
|
||||
ref={divRef}
|
||||
>
|
||||
<CodeEditor
|
||||
languageId={CONSOLE_LANG_ID}
|
||||
value={renderedHistoryRequest}
|
||||
fullWidth={true}
|
||||
editorDidMount={editorDidMountCallback}
|
||||
editorWillUnmount={editorWillUnmountCallback}
|
||||
options={{
|
||||
readOnly: true,
|
||||
fontSize: settings.fontSize,
|
||||
wordWrap: settings.wrapMode ? 'on' : 'off',
|
||||
theme: CONSOLE_THEME_ID,
|
||||
automaticLayout: true,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -30,6 +30,7 @@ interface SetInitialValueParams {
|
|||
/**
|
||||
* Util function for reading the load_from parameter from the current url.
|
||||
*/
|
||||
|
||||
export const readLoadFromParam = () => {
|
||||
const [, queryString] = (window.location.hash || window.location.search || '').split('?');
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import { css } from '@emotion/react';
|
|||
import { CodeEditor } from '@kbn/code-editor';
|
||||
import { CONSOLE_LANG_ID, CONSOLE_THEME_ID, monaco } from '@kbn/monaco';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useSetInputEditor } from '../../../hooks';
|
||||
import { ConsoleMenu } from '../../../components';
|
||||
import {
|
||||
useServicesContext,
|
||||
|
@ -33,17 +34,11 @@ export interface EditorProps {
|
|||
}
|
||||
|
||||
export const MonacoEditor = ({ initialTextValue }: EditorProps) => {
|
||||
const context = useServicesContext();
|
||||
const {
|
||||
services: {
|
||||
notifications,
|
||||
esHostService,
|
||||
trackUiMetric,
|
||||
http,
|
||||
settings: settingsService,
|
||||
autocompleteInfo,
|
||||
},
|
||||
services: { notifications, esHostService, settings: settingsService, autocompleteInfo },
|
||||
docLinkVersion,
|
||||
} = useServicesContext();
|
||||
} = context;
|
||||
const { toasts } = notifications;
|
||||
const { settings } = useEditorReadContext();
|
||||
|
||||
|
@ -55,6 +50,7 @@ export const MonacoEditor = ({ initialTextValue }: EditorProps) => {
|
|||
const actionsProvider = useRef<MonacoEditorActionsProvider | null>(null);
|
||||
const [editorActionsCss, setEditorActionsCss] = useState<CSSProperties>({});
|
||||
|
||||
const setInputEditor = useSetInputEditor();
|
||||
const getCurlCallback = useCallback(async (): Promise<string> => {
|
||||
const curl = await actionsProvider.current?.getCurl(esHostService.getHost());
|
||||
return curl ?? '';
|
||||
|
@ -69,12 +65,14 @@ export const MonacoEditor = ({ initialTextValue }: EditorProps) => {
|
|||
}, []);
|
||||
|
||||
const sendRequestsCallback = useCallback(async () => {
|
||||
await actionsProvider.current?.sendRequests(toasts, dispatch, trackUiMetric, http);
|
||||
}, [dispatch, http, toasts, trackUiMetric]);
|
||||
await actionsProvider.current?.sendRequests(dispatch, context);
|
||||
}, [dispatch, context]);
|
||||
|
||||
const editorDidMountCallback = useCallback(
|
||||
(editor: monaco.editor.IStandaloneCodeEditor) => {
|
||||
actionsProvider.current = new MonacoEditorActionsProvider(editor, setEditorActionsCss);
|
||||
const provider = new MonacoEditorActionsProvider(editor, setEditorActionsCss);
|
||||
setInputEditor(provider);
|
||||
actionsProvider.current = provider;
|
||||
setupResizeChecker(divRef.current!, editor);
|
||||
registerKeyboardCommands({
|
||||
editor,
|
||||
|
@ -86,7 +84,13 @@ export const MonacoEditor = ({ initialTextValue }: EditorProps) => {
|
|||
moveToNextRequestEdge: async () => await actionsProvider.current?.moveToNextRequestEdge(),
|
||||
});
|
||||
},
|
||||
[getDocumenationLink, registerKeyboardCommands, sendRequestsCallback, setupResizeChecker]
|
||||
[
|
||||
getDocumenationLink,
|
||||
registerKeyboardCommands,
|
||||
sendRequestsCallback,
|
||||
setupResizeChecker,
|
||||
setInputEditor,
|
||||
]
|
||||
);
|
||||
|
||||
const editorWillUnmountCallback = useCallback(() => {
|
||||
|
|
|
@ -69,6 +69,7 @@ describe('Editor actions provider', () => {
|
|||
getPosition: jest.fn(),
|
||||
getTopForLineNumber: jest.fn(),
|
||||
getScrollTop: jest.fn(),
|
||||
executeEdits: jest.fn(),
|
||||
setPosition: jest.fn(),
|
||||
} as unknown as jest.Mocked<monaco.editor.IStandaloneCodeEditor>;
|
||||
|
||||
|
@ -401,4 +402,160 @@ describe('Editor actions provider', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('restoreRequestFromHistory', () => {
|
||||
const testHistoryRequest = 'GET _alias';
|
||||
beforeEach(() => {
|
||||
/*
|
||||
* The editor has the text
|
||||
* "POST _search" on line 1
|
||||
* { "test": "test" } on lines 2-4
|
||||
* and "GET _analyze" on line 5
|
||||
*/
|
||||
mockGetParsedRequests.mockReturnValue([
|
||||
{
|
||||
startOffset: 0,
|
||||
method: 'POST',
|
||||
url: '_search',
|
||||
endOffset: 35,
|
||||
data: [
|
||||
{
|
||||
test: 'test',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
startOffset: 36,
|
||||
method: 'GET',
|
||||
url: '_analyze',
|
||||
endOffset: 48,
|
||||
},
|
||||
]);
|
||||
|
||||
editor.getModel.mockReturnValue({
|
||||
getLineMaxColumn: (lineNumber: number) => {
|
||||
// mock this function for line 4
|
||||
return 2;
|
||||
},
|
||||
getPositionAt: (offset: number) => {
|
||||
// mock this function for start offsets of the mocked requests
|
||||
if (offset === 0) {
|
||||
return { lineNumber: 1, column: 1 };
|
||||
}
|
||||
if (offset === 36) {
|
||||
return { lineNumber: 5, column: 1 };
|
||||
}
|
||||
// mock this function for end offsets of the mocked requests
|
||||
if (offset === 35) {
|
||||
return { lineNumber: 4, column: 2 };
|
||||
}
|
||||
if (offset === 48) {
|
||||
return { lineNumber: 5, column: 13 };
|
||||
}
|
||||
},
|
||||
getLineContent: (lineNumber: number) => {
|
||||
// mock this functions for line 1 and line 2
|
||||
if (lineNumber === 1) {
|
||||
return 'POST _search';
|
||||
}
|
||||
if (lineNumber === 2) {
|
||||
return '{';
|
||||
}
|
||||
if (lineNumber === 3) {
|
||||
return ' "test": "test"';
|
||||
}
|
||||
if (lineNumber === 4) {
|
||||
return '}';
|
||||
}
|
||||
if (lineNumber === 5) {
|
||||
return 'GET _analyze';
|
||||
}
|
||||
},
|
||||
} as unknown as monaco.editor.ITextModel);
|
||||
});
|
||||
|
||||
it('insert the request at the beginning of the selected request', async () => {
|
||||
// the position of the cursor is in the middle of line 5
|
||||
editor.getPosition.mockReturnValue({
|
||||
lineNumber: 5,
|
||||
column: 4,
|
||||
} as monaco.Position);
|
||||
editor.getSelection.mockReturnValue({
|
||||
startLineNumber: 5,
|
||||
endLineNumber: 5,
|
||||
} as monaco.Selection);
|
||||
|
||||
await editorActionsProvider.restoreRequestFromHistory(testHistoryRequest);
|
||||
const expectedRange = {
|
||||
startLineNumber: 5,
|
||||
startColumn: 1,
|
||||
endLineNumber: 5,
|
||||
endColumn: 1,
|
||||
};
|
||||
const expectedText = testHistoryRequest + '\n';
|
||||
const expectedEdit = {
|
||||
range: expectedRange,
|
||||
text: expectedText,
|
||||
forceMoveMarkers: true,
|
||||
};
|
||||
expect(editor.executeEdits).toHaveBeenCalledTimes(1);
|
||||
expect(editor.executeEdits).toHaveBeenCalledWith('restoreFromHistory', [expectedEdit]);
|
||||
});
|
||||
|
||||
it('insert the request at the end of the selected request', async () => {
|
||||
// the position of the cursor is at the end of line 4
|
||||
editor.getPosition.mockReturnValue({
|
||||
lineNumber: 4,
|
||||
column: 2,
|
||||
} as monaco.Position);
|
||||
editor.getSelection.mockReturnValue({
|
||||
startLineNumber: 4,
|
||||
endLineNumber: 4,
|
||||
} as monaco.Selection);
|
||||
await editorActionsProvider.restoreRequestFromHistory(testHistoryRequest);
|
||||
const expectedRange = {
|
||||
startLineNumber: 4,
|
||||
startColumn: 2,
|
||||
endLineNumber: 4,
|
||||
endColumn: 2,
|
||||
};
|
||||
const expectedText = '\n' + testHistoryRequest;
|
||||
const expectedEdit = {
|
||||
range: expectedRange,
|
||||
text: expectedText,
|
||||
forceMoveMarkers: true,
|
||||
};
|
||||
expect(editor.executeEdits).toHaveBeenCalledTimes(1);
|
||||
expect(editor.executeEdits).toHaveBeenCalledWith('restoreFromHistory', [expectedEdit]);
|
||||
});
|
||||
|
||||
it('insert at the beginning of the line, if no selected request', async () => {
|
||||
// mock no parsed requests
|
||||
mockGetParsedRequests.mockReturnValue([]);
|
||||
// the position of the cursor is at the end of line 4
|
||||
editor.getPosition.mockReturnValue({
|
||||
lineNumber: 4,
|
||||
column: 2,
|
||||
} as monaco.Position);
|
||||
editor.getSelection.mockReturnValue({
|
||||
startLineNumber: 4,
|
||||
endLineNumber: 4,
|
||||
} as monaco.Selection);
|
||||
await editorActionsProvider.restoreRequestFromHistory(testHistoryRequest);
|
||||
const expectedRange = {
|
||||
startLineNumber: 4,
|
||||
startColumn: 1,
|
||||
endLineNumber: 4,
|
||||
endColumn: 1,
|
||||
};
|
||||
const expectedText = testHistoryRequest + '\n';
|
||||
const expectedEdit = {
|
||||
range: expectedRange,
|
||||
text: expectedText,
|
||||
forceMoveMarkers: true,
|
||||
};
|
||||
expect(editor.executeEdits).toHaveBeenCalledTimes(1);
|
||||
expect(editor.executeEdits).toHaveBeenCalledWith('restoreFromHistory', [expectedEdit]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,13 +9,12 @@
|
|||
import { CSSProperties, Dispatch } from 'react';
|
||||
import { debounce } from 'lodash';
|
||||
import { ConsoleParsedRequestsProvider, getParsedRequestsProvider, monaco } from '@kbn/monaco';
|
||||
import { IToasts } from '@kbn/core-notifications-browser';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { HttpSetup } from '@kbn/core-http-browser';
|
||||
import { toMountPoint } from '@kbn/react-kibana-mount';
|
||||
import { isQuotaExceededError } from '../../../../services/history';
|
||||
import { DEFAULT_VARIABLES } from '../../../../../common/constants';
|
||||
import { getStorage, StorageKeys } from '../../../../services';
|
||||
import { sendRequest } from '../../../hooks';
|
||||
import { MetricsTracker } from '../../../../types';
|
||||
import { Actions } from '../../../stores/request';
|
||||
|
||||
import {
|
||||
|
@ -38,6 +37,8 @@ import {
|
|||
} from './utils';
|
||||
|
||||
import type { AdjustedParsedRequest } from './types';
|
||||
import { StorageQuotaError } from '../../../components/storage_quota_error';
|
||||
import { ContextValue } from '../../../contexts';
|
||||
|
||||
const AUTO_INDENTATION_ACTION_LABEL = 'Apply indentations';
|
||||
|
||||
|
@ -180,12 +181,12 @@ export class MonacoEditorActionsProvider {
|
|||
return curlRequests.join('\n');
|
||||
}
|
||||
|
||||
public async sendRequests(
|
||||
toasts: IToasts,
|
||||
dispatch: Dispatch<Actions>,
|
||||
trackUiMetric: MetricsTracker,
|
||||
http: HttpSetup
|
||||
): Promise<void> {
|
||||
public async sendRequests(dispatch: Dispatch<Actions>, context: ContextValue): Promise<void> {
|
||||
const {
|
||||
services: { notifications, trackUiMetric, http, settings, history, autocompleteInfo },
|
||||
startServices,
|
||||
} = context;
|
||||
const { toasts } = notifications;
|
||||
try {
|
||||
const requests = await this.getRequests();
|
||||
if (!requests.length) {
|
||||
|
@ -205,8 +206,63 @@ export class MonacoEditorActionsProvider {
|
|||
|
||||
const results = await sendRequest({ http, requests });
|
||||
|
||||
// TODO save to history
|
||||
// TODO restart autocomplete polling
|
||||
let saveToHistoryError: undefined | Error;
|
||||
const isHistoryEnabled = settings.getIsHistoryEnabled();
|
||||
|
||||
if (isHistoryEnabled) {
|
||||
results.forEach(({ request: { path, method, data } }) => {
|
||||
try {
|
||||
history.addToHistory(path, method, data);
|
||||
} catch (e) {
|
||||
// Grab only the first error
|
||||
if (!saveToHistoryError) {
|
||||
saveToHistoryError = e;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (saveToHistoryError) {
|
||||
const errorTitle = i18n.translate('console.notification.error.couldNotSaveRequestTitle', {
|
||||
defaultMessage: 'Could not save request to Console history.',
|
||||
});
|
||||
if (isQuotaExceededError(saveToHistoryError)) {
|
||||
const toast = notifications.toasts.addWarning({
|
||||
title: i18n.translate('console.notification.error.historyQuotaReachedMessage', {
|
||||
defaultMessage:
|
||||
'Request history is full. Clear the console history or disable saving new requests.',
|
||||
}),
|
||||
text: toMountPoint(
|
||||
StorageQuotaError({
|
||||
onClearHistory: () => {
|
||||
history.clearHistory();
|
||||
notifications.toasts.remove(toast);
|
||||
},
|
||||
onDisableSavingToHistory: () => {
|
||||
settings.setIsHistoryEnabled(false);
|
||||
notifications.toasts.remove(toast);
|
||||
},
|
||||
}),
|
||||
startServices
|
||||
),
|
||||
});
|
||||
} else {
|
||||
// Best effort, but still notify the user.
|
||||
notifications.toasts.addError(saveToHistoryError, {
|
||||
title: errorTitle,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const polling = settings.getPolling();
|
||||
if (polling) {
|
||||
// If the user has submitted a request against ES, something in the fields, indices, aliases,
|
||||
// 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.
|
||||
autocompleteInfo.retrieve(settings, settings.getAutocomplete());
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: 'requestSuccess',
|
||||
payload: {
|
||||
|
@ -347,6 +403,54 @@ export class MonacoEditorActionsProvider {
|
|||
return this.getSuggestions(model, position, context);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function inserts a request from the history into the editor
|
||||
*/
|
||||
public async restoreRequestFromHistory(request: string) {
|
||||
const model = this.editor.getModel();
|
||||
if (!model) {
|
||||
return;
|
||||
}
|
||||
let position = this.editor.getPosition() as monaco.IPosition;
|
||||
const requests = await this.getSelectedParsedRequests();
|
||||
let prefix = '';
|
||||
let suffix = '';
|
||||
// if there are requests at the cursor/selection, insert either before or after
|
||||
if (requests.length > 0) {
|
||||
// if on the 1st line of the 1st request, insert at the beginning of that line
|
||||
if (position && position.lineNumber === requests[0].startLineNumber) {
|
||||
position = { column: 1, lineNumber: position.lineNumber };
|
||||
suffix = '\n';
|
||||
} else {
|
||||
// otherwise insert at the end of the last line of the last request
|
||||
const lastLineNumber = requests[requests.length - 1].endLineNumber;
|
||||
position = { column: model.getLineMaxColumn(lastLineNumber), lineNumber: lastLineNumber };
|
||||
prefix = '\n';
|
||||
}
|
||||
} else {
|
||||
// if not inside a request, insert the request at the cursor line
|
||||
if (position) {
|
||||
// insert at the beginning of the cursor line
|
||||
position = { lineNumber: position.lineNumber, column: 1 };
|
||||
} else {
|
||||
// otherwise insert on line 1
|
||||
position = { lineNumber: 1, column: 1 };
|
||||
}
|
||||
suffix = '\n';
|
||||
}
|
||||
const edit: monaco.editor.IIdentifiedSingleEditOperation = {
|
||||
range: {
|
||||
startLineNumber: position.lineNumber,
|
||||
startColumn: position.column,
|
||||
endLineNumber: position.lineNumber,
|
||||
endColumn: position.column,
|
||||
},
|
||||
text: prefix + request + suffix,
|
||||
forceMoveMarkers: true,
|
||||
};
|
||||
this.editor.executeEdits('restoreFromHistory', [edit]);
|
||||
}
|
||||
|
||||
/*
|
||||
This function returns the text in the provided range.
|
||||
If no range is provided, it returns all text in the editor.
|
||||
|
|
|
@ -308,7 +308,6 @@ const getInsertText = (
|
|||
} else {
|
||||
templateLines = JSON.stringify(template, null, 2).split(newLineRegex);
|
||||
}
|
||||
// TODO add correct indentation
|
||||
insertText += ': ' + templateLines.join('\n');
|
||||
} else if (value === '{') {
|
||||
insertText += '{}';
|
||||
|
|
|
@ -6,12 +6,13 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { MonacoEditorActionsProvider } from '../../containers/editor/monaco/monaco_editor_actions_provider';
|
||||
import { SenseEditor } from '../../models/sense_editor';
|
||||
|
||||
export class EditorRegistry {
|
||||
private inputEditor: SenseEditor | undefined;
|
||||
private inputEditor: SenseEditor | MonacoEditorActionsProvider | undefined;
|
||||
|
||||
setInputEditor(inputEditor: SenseEditor) {
|
||||
setInputEditor(inputEditor: SenseEditor | MonacoEditorActionsProvider) {
|
||||
this.inputEditor = inputEditor;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ export interface ContextValue {
|
|||
services: ContextServices;
|
||||
docLinkVersion: string;
|
||||
docLinks: DocLinksStart['links'];
|
||||
config?: {
|
||||
config: {
|
||||
isMonacoEnabled: boolean;
|
||||
};
|
||||
startServices: ConsoleStartServices;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { formatRequestBodyDoc } from '../../../lib/utils';
|
||||
import { MonacoEditorActionsProvider } from '../../containers/editor/monaco/monaco_editor_actions_provider';
|
||||
import { ESRequest } from '../../../types';
|
||||
|
||||
export async function restoreRequestFromHistoryToMonaco(
|
||||
provider: MonacoEditorActionsProvider,
|
||||
req: ESRequest
|
||||
) {
|
||||
let s = req.method + ' ' + req.endpoint;
|
||||
if (req.data) {
|
||||
const indent = true;
|
||||
const formattedData = formatRequestBodyDoc([req.data], indent);
|
||||
s += '\n' + formattedData.data;
|
||||
}
|
||||
await provider.restoreRequestFromHistory(s);
|
||||
}
|
|
@ -7,13 +7,23 @@
|
|||
*/
|
||||
|
||||
import { useCallback } from 'react';
|
||||
import { SenseEditor } from '../../models';
|
||||
import { instance as registry } from '../../contexts/editor_context/editor_registry';
|
||||
import { ESRequest } from '../../../types';
|
||||
import { restoreRequestFromHistory } from './restore_request_from_history';
|
||||
import { restoreRequestFromHistoryToMonaco } from './restore_request_from_history_to_monaco';
|
||||
import { MonacoEditorActionsProvider } from '../../containers/editor/monaco/monaco_editor_actions_provider';
|
||||
|
||||
export const useRestoreRequestFromHistory = () => {
|
||||
return useCallback((req: ESRequest) => {
|
||||
const editor = registry.getInputEditor();
|
||||
restoreRequestFromHistory(editor, req);
|
||||
}, []);
|
||||
export const useRestoreRequestFromHistory = (isMonacoEnabled: boolean) => {
|
||||
return useCallback(
|
||||
async (req: ESRequest) => {
|
||||
const editor = registry.getInputEditor();
|
||||
if (isMonacoEnabled) {
|
||||
await restoreRequestFromHistoryToMonaco(editor as MonacoEditorActionsProvider, req);
|
||||
} else {
|
||||
restoreRequestFromHistory(editor as SenseEditor, req);
|
||||
}
|
||||
},
|
||||
[isMonacoEnabled]
|
||||
);
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@ import { track } from './track';
|
|||
import { replaceVariables } from '../../../lib/utils';
|
||||
import { StorageKeys } from '../../../services';
|
||||
import { DEFAULT_VARIABLES } from '../../../../common/constants';
|
||||
import { SenseEditor } from '../../models';
|
||||
|
||||
export const useSendCurrentRequest = () => {
|
||||
const {
|
||||
|
@ -30,7 +31,7 @@ export const useSendCurrentRequest = () => {
|
|||
|
||||
return useCallback(async () => {
|
||||
try {
|
||||
const editor = registry.getInputEditor();
|
||||
const editor = registry.getInputEditor() as SenseEditor;
|
||||
const variables = storage.get(StorageKeys.VARIABLES, DEFAULT_VARIABLES);
|
||||
let requests = await editor.getRequestsInRange();
|
||||
requests = replaceVariables(requests, variables);
|
||||
|
@ -47,7 +48,7 @@ export const useSendCurrentRequest = () => {
|
|||
dispatch({ type: 'sendRequest', payload: undefined });
|
||||
|
||||
// Fire and forget
|
||||
setTimeout(() => track(requests, editor, trackUiMetric), 0);
|
||||
setTimeout(() => track(requests, editor as SenseEditor, trackUiMetric), 0);
|
||||
|
||||
const results = await sendRequest({ http, requests });
|
||||
|
||||
|
|
|
@ -10,12 +10,13 @@ import { useCallback } from 'react';
|
|||
import { useEditorActionContext } from '../contexts/editor_context';
|
||||
import { instance as registry } from '../contexts/editor_context/editor_registry';
|
||||
import { SenseEditor } from '../models';
|
||||
import { MonacoEditorActionsProvider } from '../containers/editor/monaco/monaco_editor_actions_provider';
|
||||
|
||||
export const useSetInputEditor = () => {
|
||||
const dispatch = useEditorActionContext();
|
||||
|
||||
return useCallback(
|
||||
(editor: SenseEditor) => {
|
||||
(editor: SenseEditor | MonacoEditorActionsProvider) => {
|
||||
dispatch({ type: 'setInputEditor', payload: editor });
|
||||
registry.setInputEditor(editor);
|
||||
},
|
||||
|
|
|
@ -12,6 +12,7 @@ import { identity } from 'fp-ts/lib/function';
|
|||
import { DevToolsSettings, DEFAULT_SETTINGS } from '../../services';
|
||||
import { TextObject } from '../../../common/text_object';
|
||||
import { SenseEditor } from '../models';
|
||||
import { MonacoEditorActionsProvider } from '../containers/editor/monaco/monaco_editor_actions_provider';
|
||||
|
||||
export interface Store {
|
||||
ready: boolean;
|
||||
|
@ -29,7 +30,7 @@ export const initialValue: Store = produce<Store>(
|
|||
);
|
||||
|
||||
export type Action =
|
||||
| { type: 'setInputEditor'; payload: SenseEditor }
|
||||
| { type: 'setInputEditor'; payload: SenseEditor | MonacoEditorActionsProvider }
|
||||
| { type: 'setCurrentTextObject'; payload: TextObject }
|
||||
| { type: 'updateSettings'; payload: DevToolsSettings };
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue