Replace EuiCodeEditor with CodeEditor in app-services code (#114316)

* code editor scripted fields

* filter_editor

* embeddable example

* clean

* update tests

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Anton Dosov 2021-10-13 14:52:48 +02:00 committed by GitHub
parent 708f06fc15
commit 2afb43b869
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 85 additions and 75 deletions

View file

@ -16,6 +16,5 @@
"githubTeam": "kibana-presentation"
},
"description": "Example app that shows how to embed a dashboard in an application",
"optionalPlugins": [],
"requiredBundles": ["esUiShared"]
"optionalPlugins": []
}

View file

@ -18,9 +18,10 @@ import {
EuiSideNav,
} from '@elastic/eui';
import 'brace/mode/json';
import { AppMountParameters } from '../../../src/core/public';
import { AppMountParameters, IUiSettingsClient } from '../../../src/core/public';
import { DashboardEmbeddableByValue } from './by_value/embeddable';
import { DashboardStart } from '../../../src/plugins/dashboard/public';
import { KibanaContextProvider } from '../../../src/plugins/kibana_react/public';
interface PageDef {
title: string;
@ -58,9 +59,14 @@ interface Props {
DashboardContainerByValueRenderer: ReturnType<
DashboardStart['getDashboardContainerByValueRenderer']
>;
uiSettings: IUiSettingsClient;
}
const DashboardEmbeddableExplorerApp = ({ basename, DashboardContainerByValueRenderer }: Props) => {
const DashboardEmbeddableExplorerApp = ({
basename,
DashboardContainerByValueRenderer,
uiSettings,
}: Props) => {
const pages: PageDef[] = [
{
title: 'By value dashboard embeddable',
@ -83,16 +89,18 @@ const DashboardEmbeddableExplorerApp = ({ basename, DashboardContainerByValueRen
));
return (
<Router basename={basename}>
<EuiPage>
<EuiPageSideBar>
<Nav pages={pages} />
</EuiPageSideBar>
<EuiPageContent>
<EuiPageContentBody>{routes}</EuiPageContentBody>
</EuiPageContent>
</EuiPage>
</Router>
<KibanaContextProvider services={{ uiSettings }}>
<Router basename={basename}>
<EuiPage>
<EuiPageSideBar>
<Nav pages={pages} />
</EuiPageSideBar>
<EuiPageContent>
<EuiPageContentBody>{routes}</EuiPageContentBody>
</EuiPageContent>
</EuiPage>
</Router>
</KibanaContextProvider>
);
};

View file

@ -8,7 +8,7 @@
import React from 'react';
import { EuiButton } from '@elastic/eui';
import { JsonEditor } from '../../../../src/plugins/es_ui_shared/public';
import { CodeEditor } from '../../../../src/plugins/kibana_react/public';
export const InputEditor = <T,>(props: { input: T; onSubmit: (value: T) => void }) => {
const input = JSON.stringify(props.input, null, 4);
@ -26,12 +26,13 @@ export const InputEditor = <T,>(props: { input: T; onSubmit: (value: T) => void
}, [input]);
return (
<>
<JsonEditor
<CodeEditor
languageId={'json'}
value={value}
onUpdate={(v) => setValue(v.data.raw)}
euiCodeEditorProps={{
'data-test-subj': 'dashboardEmbeddableByValueInputEditor',
}}
width={'100%'}
height={'400px'}
onChange={(v) => setValue(v)}
data-test-subj={'dashboardEmbeddableByValueInputEditor'}
/>
<EuiButton
onClick={() => props.onSubmit(JSON.parse(value))}

View file

@ -27,7 +27,7 @@ export class DashboardEmbeddableExamples implements Plugin<void, void, {}, Start
title: 'Dashboard embeddable examples',
navLinkStatus: AppNavLinkStatus.hidden,
async mount(params: AppMountParameters) {
const [, depsStart] = await core.getStartServices();
const [coreStart, depsStart] = await core.getStartServices();
const { renderApp } = await import('./app');
await depsStart.embeddableExamples.createSampleData();
return renderApp(
@ -35,6 +35,7 @@ export class DashboardEmbeddableExamples implements Plugin<void, void, {}, Start
basename: params.appBasePath,
DashboardContainerByValueRenderer:
depsStart.dashboard.getDashboardContainerByValueRenderer(),
uiSettings: coreStart.uiSettings,
},
params.element
);

View file

@ -15,7 +15,7 @@
{ "path": "../../src/core/tsconfig.json" },
{ "path": "../../src/plugins/dashboard/tsconfig.json" },
{ "path": "../../src/plugins/embeddable/tsconfig.json" },
{ "path": "../../src/plugins/es_ui_shared/tsconfig.json" },
{ "path": "../../src/plugins/kibana_react/tsconfig.json" },
{ "path": "../embeddable_examples/tsconfig.json" },
{ "path": "../developer_examples/tsconfig.json" },
]

View file

@ -10,14 +10,14 @@ import { registerTestBed, TestBed } from '@kbn/test/jest';
import { FilterEditor, Props } from '.';
import React from 'react';
jest.mock('@elastic/eui', () => {
const original = jest.requireActual('@elastic/eui');
jest.mock('../../../../../kibana_react/public', () => {
const original = jest.requireActual('../../../../../kibana_react/public');
return {
...original,
EuiCodeEditor: (props: any) => (
CodeEditor: (props: any) => (
<input
data-test-subj={props['data-test-subj'] || 'mockEuiCodeEditor'}
data-test-subj={props['data-test-subj'] || 'mockCodeEditor'}
value={props.value}
onChange={async (eve: any) => {
props.onChange(eve.target.value);

View file

@ -9,8 +9,6 @@
import {
EuiButton,
EuiButtonEmpty,
// @ts-ignore
EuiCodeEditor,
EuiFieldText,
EuiFlexGroup,
EuiFlexItem,
@ -33,6 +31,7 @@ import {
} from '@kbn/es-query';
import { get } from 'lodash';
import React, { Component } from 'react';
import { XJsonLang } from '@kbn/monaco';
import { GenericComboBox, GenericComboBoxProps } from './generic_combo_box';
import {
getFieldFromFilter,
@ -47,6 +46,7 @@ import { PhrasesValuesInput } from './phrases_values_input';
import { RangeValueInput } from './range_value_input';
import { getIndexPatternFromFilter } from '../../../query';
import { IIndexPattern, IFieldType } from '../../..';
import { CodeEditor } from '../../../../../kibana_react/public';
export interface Props {
filter: Filter;
@ -328,13 +328,16 @@ class FilterEditorUI extends Component<Props, State> {
defaultMessage: 'Elasticsearch Query DSL',
})}
>
<EuiCodeEditor
<CodeEditor
languageId={XJsonLang.ID}
width="100%"
height={'250px'}
value={this.state.queryDsl}
onChange={this.onQueryDslChange}
mode="json"
width="100%"
height="250px"
data-test-subj="customEditorInput"
aria-label={i18n.translate('data.filter.filterEditor.queryDslAriaLabel', {
defaultMessage: 'Elasticsearch Query DSL editor',
})}
/>
</EuiFormRow>
);

View file

@ -172,11 +172,13 @@ exports[`FieldEditor should render create new scripted field correctly 1`] = `
isInvalid={true}
label="Script"
>
<eui-code-editor
<code-editor
aria-label="Script editor"
data-test-subj="editorFieldScript"
height="300px"
mode="groovy"
languageId="painless"
onChange={[Function]}
value=""
width="100%"
/>
</eui-form-row>
@ -407,10 +409,11 @@ exports[`FieldEditor should render edit scripted field correctly 1`] = `
isInvalid={false}
label="Script"
>
<eui-code-editor
<code-editor
aria-label="Script editor"
data-test-subj="editorFieldScript"
height="300px"
mode="groovy"
languageId="painless"
onChange={[Function]}
value="doc.test.value"
width="100%"
@ -705,11 +708,13 @@ exports[`FieldEditor should show conflict field warning 1`] = `
isInvalid={true}
label="Script"
>
<eui-code-editor
<code-editor
aria-label="Script editor"
data-test-subj="editorFieldScript"
height="300px"
mode="groovy"
languageId="painless"
onChange={[Function]}
value=""
width="100%"
/>
</eui-form-row>
@ -1033,10 +1038,11 @@ exports[`FieldEditor should show deprecated lang warning 1`] = `
isInvalid={false}
label="Script"
>
<eui-code-editor
<code-editor
aria-label="Script editor"
data-test-subj="editorFieldScript"
height="300px"
mode="groovy"
languageId="painless"
onChange={[Function]}
value="doc.test.value"
width="100%"
@ -1387,11 +1393,13 @@ exports[`FieldEditor should show multiple type field warning with a table contai
isInvalid={true}
label="Script"
>
<eui-code-editor
<code-editor
aria-label="Script editor"
data-test-subj="editorFieldScript"
height="300px"
mode="groovy"
languageId="painless"
onChange={[Function]}
value=""
width="100%"
/>
</eui-form-row>

View file

@ -10,8 +10,6 @@ import { IndexPattern, IndexPatternField, IndexPatternsService } from 'src/plugi
import { FieldFormatInstanceType } from 'src/plugins/field_formats/common';
import { findTestSubject } from '@elastic/eui/lib/test';
jest.mock('brace/mode/groovy', () => ({}));
import { FieldEditor, FieldEdiorProps } from './field_editor';
import { mockManagementPlugin } from '../../mocks';
@ -23,7 +21,6 @@ jest.mock('@elastic/eui', () => ({
EuiButtonEmpty: 'eui-button-empty',
EuiCallOut: 'eui-call-out',
EuiCode: 'eui-code',
EuiCodeEditor: 'eui-code-editor',
EuiConfirmModal: 'eui-confirm-modal',
EuiFieldNumber: 'eui-field-number',
EuiFieldText: 'eui-field-text',
@ -42,6 +39,15 @@ jest.mock('@elastic/eui', () => ({
euiPaletteColorBlind: () => ['red'],
}));
jest.mock('../../../../kibana_react/public', () => {
const original = jest.requireActual('../../../../kibana_react/public');
return {
...original,
CodeEditor: `code-editor`,
};
});
jest.mock('../../scripting_languages', () => ({
getEnabledScriptingLanguages: () => ['painless', 'testlang'],
getSupportedScriptingLanguages: () => ['painless'],

View file

@ -15,7 +15,6 @@ import {
EuiButtonEmpty,
EuiCallOut,
EuiCode,
EuiCodeEditor,
EuiConfirmModal,
EuiFieldNumber,
EuiFieldText,
@ -33,6 +32,7 @@ import {
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { PainlessLang } from '@kbn/monaco';
import type { FieldFormatInstanceType } from 'src/plugins/field_formats/common';
import {
getEnabledScriptingLanguages,
@ -46,7 +46,7 @@ import {
ES_FIELD_TYPES,
DataPublicPluginStart,
} from '../../../../../plugins/data/public';
import { context as contextType } from '../../../../kibana_react/public';
import { context as contextType, CodeEditor } from '../../../../kibana_react/public';
import {
ScriptingDisabledCallOut,
ScriptingWarningCallOut,
@ -59,9 +59,6 @@ import { IndexPatternManagmentContextValue } from '../../types';
import { FIELD_TYPES_BY_LANG, DEFAULT_FIELD_TYPES } from './constants';
import { executeScript, isScriptValid } from './lib';
// This loads Ace editor's "groovy" mode, used below to highlight the script.
import 'brace/mode/groovy';
const getFieldTypeFormatsList = (
field: IndexPatternField['spec'],
defaultFieldFormat: FieldFormatInstanceType,
@ -594,13 +591,16 @@ export class FieldEditor extends PureComponent<FieldEdiorProps, FieldEditorState
isInvalid={isInvalid}
error={isInvalid ? errorMsg : null}
>
<EuiCodeEditor
value={spec.script}
data-test-subj="editorFieldScript"
onChange={this.onScriptChange}
mode="groovy"
<CodeEditor
languageId={PainlessLang.ID}
width="100%"
height="300px"
value={spec.script ?? ''}
onChange={this.onScriptChange}
data-test-subj="editorFieldScript"
aria-label={i18n.translate('indexPatternManagement.scriptLabelAriaLabel', {
defaultMessage: 'Script editor',
})}
/>
</EuiFormRow>

View file

@ -95,10 +95,10 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide
const esArchiver = getService('esArchiver');
const testSubjects = getService('testSubjects');
const pieChart = getService('pieChart');
const browser = getService('browser');
const dashboardExpect = getService('dashboardExpect');
const elasticChart = getService('elasticChart');
const PageObjects = getPageObjects(['common', 'visChart']);
const monacoEditor = getService('monacoEditor');
describe('dashboard container', () => {
before(async () => {
@ -128,17 +128,7 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide
});
async function updateInput(input: string) {
const editorWrapper = await (
await testSubjects.find('dashboardEmbeddableByValueInputEditor')
).findByClassName('ace_editor');
const editorId = await editorWrapper.getAttribute('id');
await browser.execute(
(_editorId: string, _input: string) => {
return (window as any).ace.edit(_editorId).setValue(_input);
},
editorId,
input
);
await monacoEditor.setCodeEditorValue(input);
await testSubjects.click('dashboardEmbeddableByValueInputSubmit');
}
}

View file

@ -21,6 +21,7 @@ export class SettingsPageObject extends FtrService {
private readonly header = this.ctx.getPageObject('header');
private readonly common = this.ctx.getPageObject('common');
private readonly savedObjects = this.ctx.getPageObject('savedObjects');
private readonly monacoEditor = this.ctx.getService('monacoEditor');
async clickNavigation() {
await this.find.clickDisplayedByCssSelector('.app-link:nth-child(5) a');
@ -725,14 +726,7 @@ export class SettingsPageObject extends FtrService {
async setScriptedFieldScript(script: string) {
this.log.debug('set scripted field script = ' + script);
const aceEditorCssSelector = '[data-test-subj="editorFieldScript"] .ace_editor';
const editor = await this.find.byCssSelector(aceEditorCssSelector);
await editor.click();
const existingText = await editor.getVisibleText();
for (let i = 0; i < existingText.length; i++) {
await this.browser.pressKeys(this.browser.keys.BACK_SPACE);
}
await this.browser.pressKeys(...script.split(''));
await this.monacoEditor.setCodeEditorValue(script);
}
async openScriptedFieldHelp(activeTab: string) {