Skip to content

Commit

Permalink
[Uptime] [Synthetics Integration] transition to monaco code editor (#…
Browse files Browse the repository at this point in the history
…102642)

* update synthetics integration code editor

* add basic support for xml and javascript

* fix types

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
dominiqueclarke and kibanamachine authored Jun 22, 2021
1 parent 564807c commit 34490a3
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 77 deletions.
4 changes: 3 additions & 1 deletion packages/kbn-monaco/src/monaco_imports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*/

/* eslint-disable @kbn/eslint/module_migration */

import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';

import 'monaco-editor/esm/vs/base/common/worker/simpleWorker';
Expand All @@ -23,4 +22,7 @@ import 'monaco-editor/esm/vs/editor/contrib/hover/hover.js'; // Needed for hover
import 'monaco-editor/esm/vs/editor/contrib/parameterHints/parameterHints.js'; // Needed for signature
import 'monaco-editor/esm/vs/editor/contrib/bracketMatching/bracketMatching.js'; // Needed for brackets matching highlight

import 'monaco-editor/esm/vs/basic-languages/javascript/javascript.contribution.js'; // Needed for basic javascript support
import 'monaco-editor/esm/vs/basic-languages/xml/xml.contribution.js'; // Needed for basic xml support

export { monaco };
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';

import styled from 'styled-components';

import { EuiPanel } from '@elastic/eui';
import { CodeEditor as MonacoCodeEditor } from '../../../../../../src/plugins/kibana_react/public';

import { MonacoEditorLangId } from './types';

const CodeEditorContainer = styled(EuiPanel)`
padding: 0;
`;

interface Props {
ariaLabel: string;
id: string;
languageId: MonacoEditorLangId;
onChange: (value: string) => void;
value: string;
}

export const CodeEditor = ({ ariaLabel, id, languageId, onChange, value }: Props) => {
return (
<CodeEditorContainer borderRadius="none" hasShadow={false} hasBorder={true}>
<div id={`${id}-editor`} aria-label={ariaLabel} data-test-subj="codeEditorContainer">
<MonacoCodeEditor
languageId={languageId}
width="100%"
height="250px"
value={value}
onChange={onChange}
options={{
renderValidationDecorations: value ? 'on' : 'off',
}}
/>
</div>
</CodeEditorContainer>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const initialValues = {
[ConfigKeys.RESPONSE_STATUS_CHECK]: [],
[ConfigKeys.REQUEST_BODY_CHECK]: {
value: '',
type: Mode.TEXT,
type: Mode.PLAINTEXT,
},
[ConfigKeys.REQUEST_HEADERS_CHECK]: {},
[ConfigKeys.REQUEST_METHOD_CHECK]: HTTPMethod.GET,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@ describe('<HeaderField />', () => {
});

it('handles content mode', async () => {
const contentMode: Mode = Mode.TEXT;
const contentMode: Mode = Mode.PLAINTEXT;
render(
<HeaderField defaultValue={defaultValue} onChange={onChange} contentMode={contentMode} />
);

await waitFor(() => {
expect(onChange).toBeCalledWith({
'Content-Type': contentTypes[Mode.TEXT],
'Content-Type': contentTypes[Mode.PLAINTEXT],
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const HeaderField = ({ contentMode, defaultValue, onChange }: Props) => {

export const contentTypes: Record<Mode, ContentType> = {
[Mode.JSON]: ContentType.JSON,
[Mode.TEXT]: ContentType.TEXT,
[Mode.PLAINTEXT]: ContentType.TEXT,
[Mode.XML]: ContentType.XML,
[Mode.FORM]: ContentType.FORM,
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* 2.0.
*/

import 'jest-canvas-mock';

import React, { useState, useCallback } from 'react';
import { fireEvent, waitFor } from '@testing-library/react';
import { render } from '../../lib/helper/rtl_helpers';
Expand All @@ -16,7 +18,7 @@ jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({
}));

describe('<RequestBodyField />', () => {
const defaultMode = Mode.TEXT;
const defaultMode = Mode.PLAINTEXT;
const defaultValue = 'sample value';
const WrappedComponent = () => {
const [config, setConfig] = useState({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,74 +5,25 @@
* 2.0.
*/
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { stringify, parse } from 'query-string';
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import { stringify, parse } from 'query-string';

import styled from 'styled-components';

import { EuiCodeEditor, EuiPanel, EuiTabbedContent } from '@elastic/eui';

import { Mode } from './types';

import { EuiTabbedContent } from '@elastic/eui';
import { Mode, MonacoEditorLangId } from './types';
import { KeyValuePairsField, Pair } from './key_value_field';

import 'brace/theme/github';
import 'brace/mode/xml';
import 'brace/mode/json';
import 'brace/ext/language_tools';

const CodeEditorContainer = styled(EuiPanel)`
padding: 0;
`;

enum ResponseBodyType {
CODE = 'code',
FORM = 'form',
}

const CodeEditor = ({
ariaLabel,
id,
mode,
onChange,
value,
}: {
ariaLabel: string;
id: string;
mode: Mode;
onChange: (value: string) => void;
value: string;
}) => {
return (
<CodeEditorContainer borderRadius="none" hasShadow={false} hasBorder={true}>
<div id={`${id}-editor`}>
<EuiCodeEditor
mode={mode}
theme="github"
width="100%"
height="250px"
value={value}
onChange={onChange}
setOptions={{
fontSize: '14px',
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true,
}}
aria-label={ariaLabel}
/>
</div>
</CodeEditorContainer>
);
};
import { CodeEditor } from './code_editor';

interface Props {
onChange: (requestBody: { type: Mode; value: string }) => void;
type: Mode;
value: string;
}

enum ResponseBodyType {
CODE = 'code',
FORM = 'form',
}

// TO DO: Look into whether or not code editor reports errors, in order to prevent form submission on an error
export const RequestBodyField = ({ onChange, type, value }: Props) => {
const [values, setValues] = useState<Record<ResponseBodyType, string>>({
Expand Down Expand Up @@ -129,9 +80,9 @@ export const RequestBodyField = ({ onChange, type, value }: Props) => {

const tabs = [
{
id: Mode.TEXT,
name: modeLabels[Mode.TEXT],
'data-test-subj': `syntheticsRequestBodyTab__${Mode.TEXT}`,
id: Mode.PLAINTEXT,
name: modeLabels[Mode.PLAINTEXT],
'data-test-subj': `syntheticsRequestBodyTab__${Mode.PLAINTEXT}`,
content: (
<CodeEditor
ariaLabel={i18n.translate(
Expand All @@ -140,8 +91,8 @@ export const RequestBodyField = ({ onChange, type, value }: Props) => {
defaultMessage: 'Text code editor',
}
)}
id={Mode.TEXT}
mode={Mode.TEXT}
id={Mode.PLAINTEXT}
languageId={MonacoEditorLangId.PLAINTEXT}
onChange={(code) =>
setValues((prevValues) => ({ ...prevValues, [ResponseBodyType.CODE]: code }))
}
Expand All @@ -162,7 +113,7 @@ export const RequestBodyField = ({ onChange, type, value }: Props) => {
}
)}
id={Mode.JSON}
mode={Mode.JSON}
languageId={MonacoEditorLangId.JSON}
onChange={(code) =>
setValues((prevValues) => ({ ...prevValues, [ResponseBodyType.CODE]: code }))
}
Expand All @@ -183,7 +134,7 @@ export const RequestBodyField = ({ onChange, type, value }: Props) => {
}
)}
id={Mode.XML}
mode={Mode.XML}
languageId={MonacoEditorLangId.XML}
onChange={(code) =>
setValues((prevValues) => ({ ...prevValues, [ResponseBodyType.CODE]: code }))
}
Expand Down Expand Up @@ -229,7 +180,7 @@ const modeLabels = {
defaultMessage: 'Form',
}
),
[Mode.TEXT]: i18n.translate(
[Mode.PLAINTEXT]: i18n.translate(
'xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.text',
{
defaultMessage: 'Text',
Expand Down
13 changes: 10 additions & 3 deletions x-pack/plugins/uptime/public/components/fleet_package/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,17 @@ export enum ResponseBodyIndexPolicy {
ON_ERROR = 'on_error',
}

export enum MonacoEditorLangId {
JSON = 'xjson',
PLAINTEXT = 'plaintext',
XML = 'xml',
JAVASCRIPT = 'javascript',
}

export enum Mode {
FORM = 'form',
JSON = 'json',
TEXT = 'text',
PLAINTEXT = 'text',
XML = 'xml',
}

Expand Down Expand Up @@ -192,11 +199,11 @@ export interface PolicyConfig {
[DataStream.ICMP]: ICMPFields;
}

export type Validation = Partial<Record<ConfigKeys, (value: unknown, ...args: any[]) => void>>;
export type Validation = Partial<Record<ConfigKeys, (value: unknown, ...args: any[]) => boolean>>;

export const contentTypesToMode = {
[ContentType.FORM]: Mode.FORM,
[ContentType.JSON]: Mode.JSON,
[ContentType.TEXT]: Mode.TEXT,
[ContentType.TEXT]: Mode.PLAINTEXT,
[ContentType.XML]: Mode.XML,
};
4 changes: 2 additions & 2 deletions x-pack/test/functional/apps/uptime/synthetics_integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
},
requestBody: {
type: 'xml',
value: '<samplexml>samplexml',
value: '<samplexml>samplexml<samplexml>',
},
indexResponseBody: false,
indexResponseHeaders: false,
Expand Down Expand Up @@ -308,7 +308,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
},
'check.response.headers': advancedConfig.responseHeaders,
'check.response.status': [advancedConfig.responseStatusCheck],
'check.request.body': `${advancedConfig.requestBody.value}</samplexml>`, // code editor adds closing tag
'check.request.body': advancedConfig.requestBody.value,
'check.response.body.positive': [advancedConfig.responseBodyCheckPositive],
'check.response.body.negative': [advancedConfig.responseBodyCheckNegative],
'response.include_body': advancedConfig.indexResponseBody ? 'on_error' : 'never',
Expand Down

0 comments on commit 34490a3

Please sign in to comment.