mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Remove legacy kibana react code editor (#171047)
## Summary
This PR removes the legacy kibana react code-editor, alongside replacing
all import declarations of this legacy component to the one offered by
shared-ux, i.e import declaration source of `'@kbn/kibana-react/public'`
is switched to `@kbn/code-editor`.
Also in this PR an helper for writing jest tests has been included
through the package `@kbn/code-editor-mock`, this would facilitate
mocking the editor, especially given that the code editor leverages
couple of APIs that are aren't included by default in jsdom, among them,
`matchMedia`, `ResizeObserver`. The provided mock is sufficient for most
use cases and can be setup in any package within kibana as a
[`node_module`
mock](https://jestjs.io/docs/manual-mocks#mocking-node-modules) without
having to repeatedly manually mock the editor within individual test
files. An example for how this might be done can be found here
ec5ba25368
### Checklist
<!-- Delete any items that are not applicable to this PR.
- [ ] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
-->
- [x]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
<!--
- [ ] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [ ] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [ ] If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)
- [ ] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [ ] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
### Risk Matrix
Delete this section if it is not applicable to this PR.
Before closing this PR, invite QA, stakeholders, and other developers to
identify risks that should be tested prior to the change/feature
release.
When forming the risk matrix, consider some of the following examples
and how they may potentially impact the change:
| Risk | Probability | Severity | Mitigation/Notes |
|---------------------------|-------------|----------|-------------------------|
| Multiple Spaces—unexpected behavior in non-default Kibana Space.
| Low | High | Integration tests will verify that all features are still
supported in non-default Kibana Space and when user switches between
spaces. |
| Multiple nodes—Elasticsearch polling might have race conditions
when multiple Kibana nodes are polling for the same tasks. | High | Low
| Tasks are idempotent, so executing them multiple times will not result
in logical error, but will degrade performance. To test for this case we
add plenty of unit tests around this logic and document manual testing
procedure. |
| Code should gracefully handle cases when feature X or plugin Y are
disabled. | Medium | High | Unit tests will verify that any feature flag
or plugin combination still results in our service operational. |
| [See more potential risk
examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) |
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
-->
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
35cccc2963
commit
d458b5382f
256 changed files with 671 additions and 696 deletions
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
|
@ -86,7 +86,8 @@ x-pack/test/cloud_integration/plugins/saml_provider @elastic/kibana-core
|
|||
x-pack/plugins/cloud_integrations/cloud_links @elastic/kibana-core
|
||||
x-pack/plugins/cloud @elastic/kibana-core
|
||||
x-pack/plugins/cloud_security_posture @elastic/kibana-cloud-security-posture
|
||||
packages/shared-ux/code_editor @elastic/appex-sharedux
|
||||
packages/shared-ux/code_editor/impl @elastic/appex-sharedux
|
||||
packages/shared-ux/code_editor/mocks @elastic/appex-sharedux
|
||||
packages/kbn-code-owners @elastic/appex-qa
|
||||
packages/kbn-coloring @elastic/kibana-visualizations
|
||||
packages/kbn-config @elastic/kibana-core
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { CodeEditor } from '@kbn/kibana-react-plugin/public';
|
||||
import { CodeEditor } from '@kbn/code-editor';
|
||||
|
||||
interface Props {
|
||||
value: string;
|
||||
|
|
|
@ -22,5 +22,6 @@
|
|||
"@kbn/i18n",
|
||||
"@kbn/i18n-react",
|
||||
"@kbn/core-ui-settings-browser",
|
||||
"@kbn/code-editor",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -192,7 +192,8 @@
|
|||
"@kbn/cloud-links-plugin": "link:x-pack/plugins/cloud_integrations/cloud_links",
|
||||
"@kbn/cloud-plugin": "link:x-pack/plugins/cloud",
|
||||
"@kbn/cloud-security-posture-plugin": "link:x-pack/plugins/cloud_security_posture",
|
||||
"@kbn/code-editor": "link:packages/shared-ux/code_editor",
|
||||
"@kbn/code-editor": "link:packages/shared-ux/code_editor/impl",
|
||||
"@kbn/code-editor-mock": "link:packages/shared-ux/code_editor/mocks",
|
||||
"@kbn/coloring": "link:packages/kbn-coloring",
|
||||
"@kbn/config": "link:packages/kbn-config",
|
||||
"@kbn/config-mocks": "link:packages/kbn-config-mocks",
|
||||
|
|
|
@ -15,11 +15,12 @@
|
|||
|
||||
import React, { useCallback } from 'react';
|
||||
import { monaco, XJsonLang } from '@kbn/monaco';
|
||||
|
||||
import {
|
||||
CodeEditor as KibanaReactCodeEditor,
|
||||
MarkdownLang,
|
||||
type CodeEditorProps as KibanaReactCodeEditorProps,
|
||||
} from '@kbn/kibana-react-plugin/public';
|
||||
MarkdownLang,
|
||||
} from '@kbn/code-editor';
|
||||
|
||||
type Props = Pick<KibanaReactCodeEditorProps, 'aria-label' | 'value' | 'onChange'>;
|
||||
type Options = KibanaReactCodeEditorProps['options'];
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
"@kbn/management-settings-types",
|
||||
"@kbn/management-settings-field-definition",
|
||||
"@kbn/monaco",
|
||||
"@kbn/kibana-react-plugin",
|
||||
"@kbn/management-settings-utilities",
|
||||
"@kbn/i18n-react",
|
||||
"@kbn/i18n",
|
||||
|
@ -30,5 +29,6 @@
|
|||
"@kbn/core-i18n-browser",
|
||||
"@kbn/core-analytics-browser-mocks",
|
||||
"@kbn/core-ui-settings-browser",
|
||||
"@kbn/code-editor",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -8,7 +8,15 @@
|
|||
|
||||
import './src/register_globals';
|
||||
|
||||
export { monaco } from './src/monaco_imports';
|
||||
export {
|
||||
monaco,
|
||||
cssConf,
|
||||
cssLanguage,
|
||||
markdownConf,
|
||||
markdownLanguage,
|
||||
yamlConf,
|
||||
yamlLanguage,
|
||||
} from './src/monaco_imports';
|
||||
export { XJsonLang } from './src/xjson';
|
||||
export { SQLLang } from './src/sql';
|
||||
export { ESQL_LANG_ID, ESQL_THEME_ID, ESQLLang } from './src/esql';
|
||||
|
|
|
@ -28,4 +28,18 @@ import 'monaco-editor/esm/vs/basic-languages/javascript/javascript.contribution.
|
|||
import 'monaco-editor/esm/vs/basic-languages/xml/xml.contribution.js'; // Needed for basic xml support
|
||||
import 'monaco-editor/esm/vs/basic-languages/yaml/yaml.contribution'; // Needed for yaml support
|
||||
|
||||
// config for supported base languages
|
||||
export {
|
||||
conf as cssConf,
|
||||
language as cssLanguage,
|
||||
} from 'monaco-editor/esm/vs/basic-languages/css/css';
|
||||
export {
|
||||
conf as markdownConf,
|
||||
language as markdownLanguage,
|
||||
} from 'monaco-editor/esm/vs/basic-languages/markdown/markdown';
|
||||
export {
|
||||
conf as yamlConf,
|
||||
language as yamlLanguage,
|
||||
} from 'monaco-editor/esm/vs/basic-languages/yaml/yaml';
|
||||
|
||||
export { monaco };
|
||||
|
|
12
packages/kbn-monaco/src/typings.d.ts
vendored
Normal file
12
packages/kbn-monaco/src/typings.d.ts
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Monaco languages support
|
||||
declare module 'monaco-editor/esm/vs/basic-languages/markdown/markdown';
|
||||
declare module 'monaco-editor/esm/vs/basic-languages/css/css';
|
||||
declare module 'monaco-editor/esm/vs/basic-languages/yaml/yaml';
|
|
@ -39,8 +39,7 @@ import {
|
|||
EuiOutsideClickDetector,
|
||||
EuiToolTip,
|
||||
} from '@elastic/eui';
|
||||
import { CodeEditor } from '@kbn/kibana-react-plugin/public';
|
||||
import type { CodeEditorProps } from '@kbn/kibana-react-plugin/public';
|
||||
import { CodeEditor, CodeEditorProps } from '@kbn/code-editor';
|
||||
|
||||
import {
|
||||
textBasedLanguagedEditorStyles,
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
"@kbn/expressions-plugin",
|
||||
"@kbn/data-views-plugin",
|
||||
"@kbn/index-management-plugin",
|
||||
"@kbn/visualization-utils"
|
||||
"@kbn/visualization-utils",
|
||||
"@kbn/code-editor",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -35,6 +35,7 @@ webpack_cli(
|
|||
"//packages/kbn-peggy-loader",
|
||||
"//packages/shared-ux/error_boundary",
|
||||
"//packages/kbn-rison",
|
||||
"//packages/shared-ux/code_editor/impl:code_editor",
|
||||
],
|
||||
output_dir = True,
|
||||
args = [
|
||||
|
|
|
@ -98,6 +98,7 @@ const externals = {
|
|||
classnames: '__kbnSharedDeps__.Classnames',
|
||||
'@tanstack/react-query': '__kbnSharedDeps__.ReactQuery',
|
||||
'@tanstack/react-query-devtools': '__kbnSharedDeps__.ReactQueryDevtools',
|
||||
'@kbn/code-editor': '__kbnSharedDeps__.KbnCodeEditor',
|
||||
};
|
||||
|
||||
module.exports = { distDir, jsFilename, cssDistFilename, externals };
|
||||
|
|
|
@ -74,3 +74,4 @@ export const History = require('history');
|
|||
export const Classnames = require('classnames');
|
||||
export const ReactQuery = require('@tanstack/react-query');
|
||||
export const ReactQueryDevtools = require('@tanstack/react-query-devtools');
|
||||
export const KbnCodeEditor = require('@kbn/code-editor');
|
||||
|
|
|
@ -13,7 +13,8 @@ import { findTestSubject } from '@elastic/eui/lib/test';
|
|||
import { mountWithIntl } from '@kbn/test-jest-helpers';
|
||||
import { getRenderCellValueFn } from './get_render_cell_value';
|
||||
import { dataViewMock } from '@kbn/discover-utils/src/__mocks__';
|
||||
import { CodeEditorProps, KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { CodeEditorProps } from '@kbn/code-editor';
|
||||
import { buildDataTableRecord } from '@kbn/discover-utils';
|
||||
import type { EsHitRecord } from '@kbn/discover-utils/types';
|
||||
import { FieldFormatsStart } from '@kbn/field-formats-plugin/public';
|
||||
|
|
37
packages/shared-ux/code_editor/impl/BUILD.bazel
Normal file
37
packages/shared-ux/code_editor/impl/BUILD.bazel
Normal file
|
@ -0,0 +1,37 @@
|
|||
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
|
||||
|
||||
SRCS = glob(
|
||||
[
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
],
|
||||
exclude = [
|
||||
"**/test_helpers.ts",
|
||||
"**/*.config.js",
|
||||
"**/*.mock.*",
|
||||
"**/*.test.*",
|
||||
"**/*.stories.*",
|
||||
"**/__snapshots__/**",
|
||||
"**/integration_tests/**",
|
||||
"**/mocks/**",
|
||||
"**/scripts/**",
|
||||
"**/storybook/**",
|
||||
"**/test_fixtures/**",
|
||||
"**/test_helpers/**",
|
||||
],
|
||||
)
|
||||
|
||||
BUNDLER_DEPS = [
|
||||
"@npm//react",
|
||||
"@npm//tslib",
|
||||
"@npm//react-monaco-editor",
|
||||
"@npm//react-resize-detector",
|
||||
]
|
||||
|
||||
js_library(
|
||||
name = "code_editor",
|
||||
package_name = "@kbn/code-editor",
|
||||
srcs = SRCS + ["package.json"],
|
||||
deps = BUNDLER_DEPS,
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -290,7 +290,7 @@ exports[`<CodeEditor /> is rendered 1`] = `
|
|||
</EuiToolTipAnchor>
|
||||
</EuiToolTip>
|
||||
<Component>
|
||||
<mockMonacoEditor
|
||||
<MockedMonacoEditor
|
||||
editorDidMount={[Function]}
|
||||
editorWillMount={[Function]}
|
||||
height={250}
|
||||
|
@ -328,10 +328,40 @@ exports[`<CodeEditor /> is rendered 1`] = `
|
|||
<div />
|
||||
<textarea
|
||||
data-test-subj="monacoEditorTextarea"
|
||||
height={250}
|
||||
language="loglang"
|
||||
onChange={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
options={
|
||||
Object {
|
||||
"fontFamily": "Roboto Mono",
|
||||
"fontSize": 12,
|
||||
"lineHeight": 21,
|
||||
"matchBrackets": "never",
|
||||
"minimap": Object {
|
||||
"enabled": false,
|
||||
},
|
||||
"padding": Object {},
|
||||
"renderLineHighlight": "none",
|
||||
"scrollBeyondLastLine": false,
|
||||
"scrollbar": Object {
|
||||
"alwaysConsumeMouseWheel": false,
|
||||
"useShadows": false,
|
||||
},
|
||||
"wordBasedSuggestions": false,
|
||||
"wordWrap": "on",
|
||||
"wrappingIndent": "indent",
|
||||
}
|
||||
}
|
||||
theme="euiColors"
|
||||
value="
|
||||
[Sun Mar 7 20:54:27 2004] [notice] [client xx.xx.xx.xx] This is a notice!
|
||||
[Sun Mar 7 20:58:27 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
|
||||
[Sun Mar 7 21:16:17 2004] [error] [client xx.xx.xx.xx] File does not exist: /home/httpd/twiki/view/Main/WebHome
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</mockMonacoEditor>
|
||||
</MockedMonacoEditor>
|
||||
</Component>
|
||||
</div>
|
||||
</CodeEditor>
|
|
@ -13,10 +13,28 @@ import { monaco } from '@kbn/monaco';
|
|||
|
||||
import { keys } from '@elastic/eui';
|
||||
|
||||
import { mockedEditorInstance } from './code_editor.test.helpers';
|
||||
import { MockedMonacoEditor, mockedEditorInstance } from '@kbn/code-editor-mock/monaco_mock';
|
||||
|
||||
import { CodeEditor } from './code_editor';
|
||||
|
||||
jest.mock('react-monaco-editor', () => {
|
||||
return function JestMockEditor() {
|
||||
return MockedMonacoEditor;
|
||||
};
|
||||
});
|
||||
|
||||
// Mock the htmlIdGenerator to generate predictable ids for snapshot tests
|
||||
jest.mock('@elastic/eui', () => {
|
||||
const original = jest.requireActual('@elastic/eui');
|
||||
|
||||
return {
|
||||
...original,
|
||||
htmlIdGenerator: () => {
|
||||
return () => '1234';
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
// A sample language definition with a few example tokens
|
||||
const simpleLogLang: monaco.languages.IMonarchLanguage = {
|
||||
tokenizer: {
|
83
packages/shared-ux/code_editor/impl/index.tsx
Normal file
83
packages/shared-ux/code_editor/impl/index.tsx
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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 from 'react';
|
||||
import { euiLightVars as lightTheme, euiDarkVars as darkTheme } from '@kbn/ui-theme';
|
||||
import {
|
||||
EuiDelayRender,
|
||||
EuiSkeletonText,
|
||||
EuiFormControlLayout,
|
||||
EuiErrorBoundary,
|
||||
} from '@elastic/eui';
|
||||
import type { CodeEditorProps } from './code_editor';
|
||||
export type { CodeEditorProps } from './code_editor';
|
||||
export * from './languages/constants';
|
||||
|
||||
const LazyCodeEditorBase = React.lazy(() =>
|
||||
import(/* webpackChunkName: "code-editor-entry" */ './code_editor').then((m) => ({
|
||||
default: m.CodeEditor,
|
||||
}))
|
||||
);
|
||||
|
||||
const Fallback: React.FunctionComponent<{ height: CodeEditorProps['height'] }> = ({ height }) => {
|
||||
return (
|
||||
<>
|
||||
{/* when height is known, set minHeight to avoid layout shift */}
|
||||
<div style={{ ...(height ? { minHeight: height } : {}), width: '100%' }}>
|
||||
<EuiDelayRender>
|
||||
<EuiSkeletonText lines={3} />
|
||||
</EuiDelayRender>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a Monaco code editor with EUI color theme.
|
||||
*
|
||||
* @see CodeEditorField to render a code editor in the same style as other EUI form fields.
|
||||
*/
|
||||
export const CodeEditor: React.FunctionComponent<CodeEditorProps> = (props) => {
|
||||
return (
|
||||
<EuiErrorBoundary>
|
||||
<React.Suspense fallback={<Fallback height={props.height} />}>
|
||||
<LazyCodeEditorBase {...props} />
|
||||
</React.Suspense>
|
||||
</EuiErrorBoundary>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a Monaco code editor in the same style as other EUI form fields.
|
||||
*/
|
||||
export const CodeEditorField: React.FunctionComponent<CodeEditorProps> = (props) => {
|
||||
const { width, height, options, fullWidth, useDarkTheme } = props;
|
||||
const theme = useDarkTheme ? darkTheme : lightTheme;
|
||||
const style = {
|
||||
width,
|
||||
height,
|
||||
backgroundColor: options?.readOnly
|
||||
? theme.euiFormBackgroundReadOnlyColor
|
||||
: theme.euiFormBackgroundColor,
|
||||
};
|
||||
|
||||
return (
|
||||
<EuiErrorBoundary>
|
||||
<React.Suspense fallback={<Fallback height={props.height} />}>
|
||||
<EuiFormControlLayout
|
||||
append={<div hidden />}
|
||||
style={style}
|
||||
readOnly={options?.readOnly}
|
||||
fullWidth={fullWidth}
|
||||
>
|
||||
<LazyCodeEditorBase {...props} transparentBackground />
|
||||
</EuiFormControlLayout>
|
||||
</React.Suspense>
|
||||
</EuiErrorBoundary>
|
||||
);
|
||||
};
|
|
@ -8,6 +8,6 @@
|
|||
|
||||
module.exports = {
|
||||
preset: '@kbn/test',
|
||||
rootDir: '../../..',
|
||||
rootDir: '../../../..',
|
||||
roots: ['<rootDir>/packages/shared-ux/code_editor'],
|
||||
};
|
|
@ -6,7 +6,6 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
/* eslint-disable @kbn/eslint/module_migration */
|
||||
import { conf, language } from 'monaco-editor/esm/vs/basic-languages/css/css';
|
||||
import { cssConf, cssLanguage } from '@kbn/monaco';
|
||||
|
||||
export { conf as languageConfiguration, language as lexerRules };
|
||||
export { cssConf as languageConfiguration, cssLanguage as lexerRules };
|
|
@ -6,7 +6,6 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
/* eslint-disable @kbn/eslint/module_migration */
|
||||
import { conf, language } from 'monaco-editor/esm/vs/basic-languages/yaml/yaml';
|
||||
import { markdownConf, markdownLanguage } from '@kbn/monaco';
|
||||
|
||||
export { conf as languageConfiguration, language as lexerRules };
|
||||
export { markdownConf as languageConfiguration, markdownLanguage as lexerRules };
|
|
@ -6,7 +6,6 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
/* eslint-disable @kbn/eslint/module_migration */
|
||||
import { conf, language } from 'monaco-editor/esm/vs/basic-languages/markdown/markdown';
|
||||
import { yamlConf, yamlLanguage } from '@kbn/monaco';
|
||||
|
||||
export { conf as languageConfiguration, language as lexerRules };
|
||||
export { yamlConf as languageConfiguration, yamlLanguage as lexerRules };
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "target/types",
|
||||
"types": [
|
||||
|
@ -13,7 +13,7 @@
|
|||
"include": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
"../../../typings/**/*",
|
||||
"../../../../typings/**/*",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*"
|
||||
|
@ -25,5 +25,6 @@
|
|||
"@kbn/ui-theme",
|
||||
"@kbn/test-jest-helpers",
|
||||
"@kbn/shared-ux-storybook-mock",
|
||||
"@kbn/code-editor-mock",
|
||||
]
|
||||
}
|
23
packages/shared-ux/code_editor/mocks/README.md
Normal file
23
packages/shared-ux/code_editor/mocks/README.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
# @kbn/code-editor-mock
|
||||
|
||||
This package exposes mock to help with testing components that are composed of the code editor, especially that the code editor leverages
|
||||
specific browser APIs that are not available in jsdom (i.e. window.matchMedia, window.ResizeObserver).
|
||||
|
||||
#### How to use
|
||||
|
||||
This package exposes a mocked version of the code-editor named `MockedCodeEditor`. This component can be used by leveraging the default [mocking capabilities](https://jestjs.io/docs/manual-mocks#mocking-node-modules) for modules of jest. One might go about this by creating a directory at `__mocks__/@kbn/code-editor` within your package, and an index file in the afore created directory that exports a named declaration that references `MockedCodeEditor`, like so;
|
||||
|
||||
|
||||
```ts
|
||||
|
||||
export { MockedCodeEditor as CodeEditor } from '@kbn/code-editor-mock';
|
||||
|
||||
```
|
||||
|
||||
Alternatively for single use within a specific test suite or in the case where a setup file is in use, one can simply add the included test helper that auto mocks `@kbn/code-editor`, like so;
|
||||
|
||||
```ts
|
||||
import '@kbn/code-editor-mock/jest_helper';
|
||||
```
|
||||
|
||||
When using this helper within a single test suite, this import declaration must be placed before the import declaration of the components that imports `@kbn/code-editor`.
|
28
packages/shared-ux/code_editor/mocks/code_editor_mock.tsx
Normal file
28
packages/shared-ux/code_editor/mocks/code_editor_mock.tsx
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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, { type ComponentProps } from 'react';
|
||||
import { MockedMonacoEditor } from './monaco_mock';
|
||||
|
||||
type MockedCodeEditorProps = ComponentProps<typeof MockedMonacoEditor>;
|
||||
|
||||
export const MockedCodeEditor = (props: MockedCodeEditorProps) => {
|
||||
return (
|
||||
<MockedMonacoEditor
|
||||
editorDidMount={props.editorDidMount}
|
||||
editorWillMount={props.editorWillMount}
|
||||
data-currentvalue={props.value}
|
||||
value={props.value}
|
||||
{...props}
|
||||
/**
|
||||
* place this after spreading props, so the fallback value is set
|
||||
*/
|
||||
data-test-subj={props['data-test-subj'] || 'mockedCodeEditor'}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -6,4 +6,4 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { CodeEditor, type CodeEditorProps } from './code_editor';
|
||||
export { MockedCodeEditor } from './code_editor_mock';
|
|
@ -6,11 +6,14 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export type { CodeEditorProps as Props } from '@kbn/code-editor';
|
||||
import { MockedCodeEditor } from './code_editor_mock';
|
||||
|
||||
import { CodeEditor } from '@kbn/code-editor';
|
||||
export { CodeEditor };
|
||||
jest.mock('@kbn/code-editor', () => {
|
||||
const module = jest.requireActual('@kbn/code-editor');
|
||||
|
||||
// React.lazy requires default export
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default CodeEditor;
|
||||
return {
|
||||
...module,
|
||||
CodeEditorField: MockedCodeEditor,
|
||||
CodeEditor: MockedCodeEditor,
|
||||
};
|
||||
});
|
5
packages/shared-ux/code_editor/mocks/kibana.jsonc
Normal file
5
packages/shared-ux/code_editor/mocks/kibana.jsonc
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"type": "shared-common",
|
||||
"id": "@kbn/code-editor-mock",
|
||||
"owner": "@elastic/appex-sharedux"
|
||||
}
|
|
@ -5,7 +5,9 @@
|
|||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { useEffect, KeyboardEventHandler } from 'react';
|
||||
import { type MonacoEditorProps } from 'react-monaco-editor';
|
||||
import { monaco } from '@kbn/monaco';
|
||||
|
||||
function createEditorInstance() {
|
||||
|
@ -15,8 +17,23 @@ function createEditorInstance() {
|
|||
let placeholderDiv: undefined | HTMLDivElement;
|
||||
let areSuggestionsVisible = false;
|
||||
|
||||
const editorInstance = {
|
||||
// Mock monaco editor API
|
||||
/**
|
||||
* Mocks for monaco editor API
|
||||
*/
|
||||
const editorInstanceMethods = {
|
||||
focus: jest.fn(),
|
||||
layout: jest.fn(),
|
||||
applyFontInfo: jest.fn(),
|
||||
executeEdits: jest.fn(),
|
||||
removeContentWidget: jest.fn((widget: monaco.editor.IContentWidget) => {
|
||||
placeholderDiv?.removeChild(widget.getDomNode());
|
||||
}),
|
||||
getValue: jest.fn(),
|
||||
getModel: jest.fn(),
|
||||
getDomNode: jest.fn(),
|
||||
getPosition: jest.fn(),
|
||||
getSelection: jest.fn(),
|
||||
getContentHeight: jest.fn(),
|
||||
getContribution: jest.fn((id: string) => {
|
||||
if (id === 'editor.contrib.suggestController') {
|
||||
return {
|
||||
|
@ -33,19 +50,20 @@ function createEditorInstance() {
|
|||
};
|
||||
}
|
||||
}),
|
||||
focus: jest.fn(),
|
||||
onDidBlurEditorText: jest.fn(),
|
||||
onKeyDown: jest.fn((listener) => {
|
||||
keyDownListeners.push(listener);
|
||||
}),
|
||||
addCommand: jest.fn(),
|
||||
addContentWidget: jest.fn((widget: monaco.editor.IContentWidget) => {
|
||||
placeholderDiv?.appendChild(widget.getDomNode());
|
||||
}),
|
||||
applyFontInfo: jest.fn(),
|
||||
removeContentWidget: jest.fn((widget: monaco.editor.IContentWidget) => {
|
||||
placeholderDiv?.removeChild(widget.getDomNode());
|
||||
onKeyDown: jest.fn((listener) => {
|
||||
keyDownListeners.push(listener);
|
||||
}),
|
||||
onDidBlurEditorText: jest.fn(),
|
||||
onDidChangeModelContent: jest.fn((cb) => cb()),
|
||||
onDidFocusEditorText: jest.fn((cb) => cb()),
|
||||
onDidContentSizeChange: jest.fn((cb) => cb()),
|
||||
onDidBlurEditorWidget: () => ({
|
||||
dispose: jest.fn(),
|
||||
}),
|
||||
getDomNode: jest.fn(),
|
||||
// Helpers for our tests
|
||||
__helpers__: {
|
||||
areSuggestionsVisible: () => areSuggestionsVisible,
|
||||
|
@ -58,7 +76,7 @@ function createEditorInstance() {
|
|||
|
||||
// Close the suggestions when hitting the ESC key
|
||||
if (e.keyCode === monaco.KeyCode.Escape && areSuggestionsVisible) {
|
||||
editorInstance.__helpers__.hideSuggestions();
|
||||
editorInstanceMethods.__helpers__.hideSuggestions();
|
||||
}
|
||||
}) as KeyboardEventHandler,
|
||||
showSuggestions: () => {
|
||||
|
@ -72,50 +90,44 @@ function createEditorInstance() {
|
|||
},
|
||||
};
|
||||
|
||||
return editorInstance;
|
||||
return editorInstanceMethods;
|
||||
}
|
||||
|
||||
type MockedEditor = ReturnType<typeof createEditorInstance>;
|
||||
export const mockedEditorInstance = createEditorInstance();
|
||||
|
||||
export const mockedEditorInstance: MockedEditor = createEditorInstance();
|
||||
|
||||
// <MonacoEditor /> mock
|
||||
const mockMonacoEditor = ({
|
||||
editorWillMount,
|
||||
export const MockedMonacoEditor = ({
|
||||
editorDidMount,
|
||||
}: Record<string, (...args: unknown[]) => void>) => {
|
||||
editorWillMount(monaco);
|
||||
editorWillMount,
|
||||
onChange,
|
||||
value,
|
||||
...rest
|
||||
}: MonacoEditorProps & {
|
||||
['data-test-subj']?: string;
|
||||
}) => {
|
||||
editorWillMount?.(monaco);
|
||||
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
useEffect(() => {
|
||||
editorDidMount(mockedEditorInstance, monaco);
|
||||
editorDidMount?.(
|
||||
mockedEditorInstance as unknown as monaco.editor.IStandaloneCodeEditor,
|
||||
monaco
|
||||
);
|
||||
}, [editorDidMount]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div ref={mockedEditorInstance?.__helpers__.getPlaceholderRef} />
|
||||
<textarea
|
||||
value={value ?? ''}
|
||||
onKeyDown={mockedEditorInstance?.__helpers__.onTextareaKeyDown}
|
||||
data-test-subj="monacoEditorTextarea"
|
||||
onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
onChange?.(e.target.value, {} as unknown as monaco.editor.IModelContentChangedEvent);
|
||||
}}
|
||||
{...rest}
|
||||
/**
|
||||
* place this after spreading props, so the fallback value is set
|
||||
*/
|
||||
data-test-subj={rest['data-test-subj'] || 'monacoEditorTextarea'}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
jest.mock('react-monaco-editor', () => {
|
||||
return function JestMockEditor() {
|
||||
return mockMonacoEditor;
|
||||
};
|
||||
});
|
||||
|
||||
// Mock the htmlIdGenerator to generate predictable ids for snapshot tests
|
||||
jest.mock('@elastic/eui', () => {
|
||||
const original = jest.requireActual('@elastic/eui');
|
||||
|
||||
return {
|
||||
...original,
|
||||
htmlIdGenerator: () => {
|
||||
return () => '1234';
|
||||
},
|
||||
};
|
||||
});
|
6
packages/shared-ux/code_editor/mocks/package.json
Normal file
6
packages/shared-ux/code_editor/mocks/package.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"name": "@kbn/code-editor-mock",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"license": "SSPL-1.0 OR Elastic License 2.0"
|
||||
}
|
24
packages/shared-ux/code_editor/mocks/tsconfig.json
Normal file
24
packages/shared-ux/code_editor/mocks/tsconfig.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "target/types",
|
||||
"types": [
|
||||
"jest",
|
||||
"node",
|
||||
"react",
|
||||
"@emotion/react/types/css-prop",
|
||||
"@kbn/ambient-ui-types",
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
"../../../../typings/**/*",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
],
|
||||
"kbn_references": [
|
||||
"@kbn/monaco",
|
||||
]
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
import React from 'react';
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
import { shallowWithI18nProvider, mountWithI18nProvider } from '@kbn/test-jest-helpers';
|
||||
import '@kbn/code-editor-mock/jest_helper';
|
||||
import { mount, ReactWrapper } from 'enzyme';
|
||||
import { FieldSetting } from '../../types';
|
||||
import { UiSettingsType } from '@kbn/core/public';
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
|
||||
import React, { useCallback } from 'react';
|
||||
import { monaco, XJsonLang } from '@kbn/monaco';
|
||||
import { CodeEditor, MarkdownLang } from '@kbn/kibana-react-plugin/public';
|
||||
|
||||
import { CodeEditor, MarkdownLang } from '@kbn/code-editor';
|
||||
|
||||
interface FieldCodeEditorProps {
|
||||
value: string;
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
"@kbn/core-plugins-server",
|
||||
"@kbn/management-settings-section-registry",
|
||||
"@kbn/react-kibana-context-render",
|
||||
"@kbn/code-editor",
|
||||
"@kbn/code-editor-mock",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -10,11 +10,8 @@ import { EuiFlyoutBody, EuiFlyoutHeader, EuiSpacer, EuiText, EuiTitle } from '@e
|
|||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import React, { Fragment } from 'react';
|
||||
import { CoreStart } from '@kbn/core/public';
|
||||
import {
|
||||
CodeEditor,
|
||||
createKibanaReactContext,
|
||||
toMountPoint,
|
||||
} from '@kbn/kibana-react-plugin/public';
|
||||
import { createKibanaReactContext, toMountPoint } from '@kbn/kibana-react-plugin/public';
|
||||
import { CodeEditor } from '@kbn/code-editor';
|
||||
import { UISession } from '../../types';
|
||||
import { IClickActionDescriptor } from '..';
|
||||
import './inspect_button.scss';
|
||||
|
|
|
@ -51,7 +51,8 @@
|
|||
"@kbn/search-response-warnings",
|
||||
"@kbn/shared-ux-link-redirect-app",
|
||||
"@kbn/bfetch-error",
|
||||
"@kbn/es-types"
|
||||
"@kbn/es-types",
|
||||
"@kbn/code-editor"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -13,12 +13,9 @@ export type {
|
|||
} from '@kbn/data-plugin/public';
|
||||
export type { DataView, DataViewField, DataViewSpec } from '@kbn/data-views-plugin/public';
|
||||
|
||||
export {
|
||||
createKibanaReactContext,
|
||||
toMountPoint,
|
||||
CodeEditor,
|
||||
useKibana,
|
||||
} from '@kbn/kibana-react-plugin/public';
|
||||
export { createKibanaReactContext, toMountPoint, useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
|
||||
export { CodeEditor } from '@kbn/code-editor';
|
||||
|
||||
export type {
|
||||
FormSchema,
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
"@kbn/ui-theme",
|
||||
"@kbn/kibana-utils-plugin",
|
||||
"@kbn/react-kibana-mount",
|
||||
"@kbn/code-editor",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -75,8 +75,8 @@ jest.mock('react-use/lib/useDebounce', () => {
|
|||
};
|
||||
});
|
||||
|
||||
jest.mock('@kbn/kibana-react-plugin/public', () => {
|
||||
const original = jest.requireActual('@kbn/kibana-react-plugin/public');
|
||||
jest.mock('@kbn/code-editor', () => {
|
||||
const original = jest.requireActual('@kbn/code-editor');
|
||||
|
||||
/**
|
||||
* We mock the CodeEditor because it requires the <KibanaReactContextProvider>
|
||||
|
|
|
@ -27,11 +27,9 @@ export type {
|
|||
} from '@kbn/data-views-plugin/common';
|
||||
export { KBN_FIELD_TYPES, ES_FIELD_TYPES } from '@kbn/data-plugin/common';
|
||||
|
||||
export {
|
||||
createKibanaReactContext,
|
||||
toMountPoint,
|
||||
CodeEditor,
|
||||
} from '@kbn/kibana-react-plugin/public';
|
||||
export { createKibanaReactContext, toMountPoint } from '@kbn/kibana-react-plugin/public';
|
||||
|
||||
export { CodeEditor } from '@kbn/code-editor';
|
||||
|
||||
export type { FieldFormat, SerializedFieldFormat } from '@kbn/field-formats-plugin/common';
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
"@kbn/utility-types",
|
||||
"@kbn/config-schema",
|
||||
"@kbn/react-kibana-mount",
|
||||
"@kbn/code-editor",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -39,8 +39,8 @@ jest.mock('@elastic/eui', () => ({
|
|||
euiPaletteColorBlind: () => ['red'],
|
||||
}));
|
||||
|
||||
jest.mock('@kbn/kibana-react-plugin/public', () => {
|
||||
const original = jest.requireActual('@kbn/kibana-react-plugin/public');
|
||||
jest.mock('@kbn/code-editor', () => {
|
||||
const original = jest.requireActual('@kbn/code-editor');
|
||||
|
||||
return {
|
||||
...original,
|
||||
|
|
|
@ -46,7 +46,8 @@ import {
|
|||
DataViewsPublicPluginStart,
|
||||
FieldSpec,
|
||||
} from '@kbn/data-views-plugin/public';
|
||||
import { context as contextType, CodeEditor } from '@kbn/kibana-react-plugin/public';
|
||||
import { context as contextType } from '@kbn/kibana-react-plugin/public';
|
||||
import { CodeEditor } from '@kbn/code-editor';
|
||||
import {
|
||||
getEnabledScriptingLanguages,
|
||||
getDeprecatedScriptingLanguages,
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
"@kbn/shared-ux-router",
|
||||
"@kbn/core-ui-settings-browser",
|
||||
"@kbn/react-kibana-context-render",
|
||||
"@kbn/code-editor",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
"server": true,
|
||||
"browser": true,
|
||||
"requiredBundles": [
|
||||
"dataViews",
|
||||
"kibanaReact"
|
||||
"dataViews"
|
||||
],
|
||||
"extraPublicDirs": [
|
||||
"static/validators/string",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import React, { useCallback, useMemo } from 'react';
|
||||
import { EuiFormRow } from '@elastic/eui';
|
||||
import { debounce } from 'lodash';
|
||||
import { CodeEditor } from '@kbn/kibana-react-plugin/public';
|
||||
import { CodeEditor } from '@kbn/code-editor';
|
||||
|
||||
import { useJson, OnJsonEditorUpdateHandler } from './use_json';
|
||||
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
"@kbn/i18n-react",
|
||||
"@kbn/test-jest-helpers",
|
||||
"@kbn/share-plugin",
|
||||
"@kbn/kibana-react-plugin",
|
||||
"@kbn/safer-lodash-set",
|
||||
"@kbn/storybook",
|
||||
"@kbn/shared-ux-link-redirect-app",
|
||||
"@kbn/code-editor",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -17,7 +17,8 @@ import { i18n } from '@kbn/i18n';
|
|||
import { XJsonLang } from '@kbn/monaco';
|
||||
import { compressToEncodedURIComponent } from 'lz-string';
|
||||
import React, { useCallback } from 'react';
|
||||
import { CodeEditor, useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { CodeEditor } from '@kbn/code-editor';
|
||||
import { InspectorPluginStartDeps } from '../../../../plugin';
|
||||
|
||||
interface RequestCodeViewerProps {
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
"@kbn/core-ui-settings-browser",
|
||||
"@kbn/std",
|
||||
"@kbn/es-types",
|
||||
"@kbn/ui-theme"
|
||||
"@kbn/ui-theme",
|
||||
"@kbn/code-editor"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
# Code Editor Component
|
||||
|
||||
This re-usable code editor component was built as a layer of abstraction on top of the [Monaco Code Editor](https://microsoft.github.io/monaco-editor/) (and the [React Monaco Editor component](https://github.com/react-monaco-editor/react-monaco-editor)). The goal of this component is to expose a set of the most-used, most-helpful features from Monaco in a way that's easy to use out of the box. If a use case requires additional features, this component still allows access to all other Monaco features.
|
||||
|
||||
This editor component allows easy access to:
|
||||
|
||||
- [Syntax highlighting (including custom language highlighting)](https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-custom-languages)
|
||||
- [Suggestion/autocompletion widget](https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-completion-provider-example)
|
||||
- Function signature widget
|
||||
- [Hover widget](https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-hover-provider-example)
|
||||
|
||||
The Monaco editor doesn't automatically resize the editor area on window or container resize so this component includes a [resize detector](https://github.com/maslianok/react-resize-detector) to cause the Monaco editor to re-layout and adjust its size when the window or container size changes
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* 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 from 'react';
|
||||
import { euiLightVars as lightTheme, euiDarkVars as darkTheme } from '@kbn/ui-theme';
|
||||
import { EuiFormControlLayout } from '@elastic/eui';
|
||||
import { CodeEditor, Props } from './code_editor';
|
||||
|
||||
/**
|
||||
* Renders a Monaco code editor in the same style as other EUI form fields.
|
||||
*/
|
||||
export const CodeEditorField: React.FunctionComponent<Props> = (props) => {
|
||||
const { width, height, options, fullWidth, useDarkTheme } = props;
|
||||
const theme = useDarkTheme ? darkTheme : lightTheme;
|
||||
const style = {
|
||||
width,
|
||||
height,
|
||||
backgroundColor: options?.readOnly
|
||||
? theme.euiFormBackgroundReadOnlyColor
|
||||
: theme.euiFormBackgroundColor,
|
||||
};
|
||||
|
||||
return (
|
||||
<EuiFormControlLayout
|
||||
append={<div hidden />}
|
||||
style={style}
|
||||
readOnly={options?.readOnly}
|
||||
fullWidth={fullWidth}
|
||||
>
|
||||
<CodeEditor {...props} transparentBackground />
|
||||
</EuiFormControlLayout>
|
||||
);
|
||||
};
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* 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 from 'react';
|
||||
import { EuiDelayRender, EuiErrorBoundary, EuiSkeletonText, useEuiTheme } from '@elastic/eui';
|
||||
|
||||
import type { Props } from './code_editor';
|
||||
|
||||
export * from '@kbn/code-editor/languages/constants';
|
||||
|
||||
const LazyBaseEditor = React.lazy(() => import('./code_editor'));
|
||||
const LazyCodeEditorField = React.lazy(() =>
|
||||
import('./code_editor_field').then((m) => ({ default: m.CodeEditorField }))
|
||||
);
|
||||
|
||||
const Fallback: React.FunctionComponent<{ height: Props['height'] }> = ({ height }) => {
|
||||
return (
|
||||
<>
|
||||
{/* when height is known, set minHeight to avoid layout shift */}
|
||||
<div style={height ? { minHeight: height } : {}}>
|
||||
<EuiDelayRender>
|
||||
<EuiSkeletonText lines={3} />
|
||||
</EuiDelayRender>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export type CodeEditorProps = Props;
|
||||
|
||||
/**
|
||||
* Renders a Monaco code editor with EUI color theme.
|
||||
*
|
||||
* @see CodeEditorField to render a code editor in the same style as other EUI form fields.
|
||||
*/
|
||||
export const CodeEditor: React.FunctionComponent<Props> = (props) => {
|
||||
const { colorMode } = useEuiTheme();
|
||||
|
||||
return (
|
||||
<EuiErrorBoundary>
|
||||
<React.Suspense fallback={<Fallback height={props.height} />}>
|
||||
<LazyBaseEditor {...props} useDarkTheme={colorMode === 'DARK'} />
|
||||
</React.Suspense>
|
||||
</EuiErrorBoundary>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a Monaco code editor in the same style as other EUI form fields.
|
||||
*/
|
||||
export const CodeEditorField: React.FunctionComponent<Props> = (props) => {
|
||||
const { colorMode } = useEuiTheme();
|
||||
|
||||
return (
|
||||
<EuiErrorBoundary>
|
||||
<React.Suspense fallback={<Fallback height={props.height} />}>
|
||||
<LazyCodeEditorField {...props} useDarkTheme={colorMode === 'DARK'} />
|
||||
</React.Suspense>
|
||||
</EuiErrorBoundary>
|
||||
);
|
||||
};
|
|
@ -6,18 +6,6 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export type { CodeEditorProps } from './code_editor';
|
||||
export {
|
||||
CssLang,
|
||||
MarkdownLang,
|
||||
YamlLang,
|
||||
HandlebarsLang,
|
||||
HJsonLang,
|
||||
GrokLang,
|
||||
CodeEditor,
|
||||
CodeEditorField,
|
||||
} from './code_editor';
|
||||
|
||||
export type { UrlTemplateEditorVariable, UrlTemplateEditorProps } from './url_template_editor';
|
||||
export { UrlTemplateEditor } from './url_template_editor';
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
import { storiesOf } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import React from 'react';
|
||||
import { CodeEditor } from '@kbn/code-editor';
|
||||
import { UrlTemplateEditor } from './url_template_editor';
|
||||
import { CodeEditor } from '../code_editor/code_editor';
|
||||
|
||||
storiesOf('UrlTemplateEditor', module)
|
||||
.add('default', () => (
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
|
||||
import * as React from 'react';
|
||||
import { monaco } from '@kbn/monaco';
|
||||
import { Props as CodeEditorProps } from '../code_editor/code_editor';
|
||||
import { CodeEditor, HandlebarsLang } from '../code_editor';
|
||||
import { CodeEditor, HandlebarsLang, type CodeEditorProps } from '@kbn/code-editor';
|
||||
|
||||
import './styles.scss';
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
],
|
||||
"kbn_references": [
|
||||
"@kbn/storybook",
|
||||
"@kbn/ui-theme",
|
||||
"@kbn/core",
|
||||
"@kbn/monaco",
|
||||
"@kbn/test-jest-helpers",
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { CodeEditorProps } from '@kbn/kibana-react-plugin/public';
|
||||
import { CodeEditorProps } from '@kbn/code-editor';
|
||||
|
||||
export const LANGUAGE_CONFIGURATION = {
|
||||
autoClosingPairs: [
|
||||
|
|
|
@ -12,7 +12,7 @@ import { debounce } from 'lodash';
|
|||
import type { monaco } from '@kbn/monaco';
|
||||
import usePrevious from 'react-use/lib/usePrevious';
|
||||
|
||||
import { CodeEditor } from '@kbn/kibana-react-plugin/public';
|
||||
import { CodeEditor } from '@kbn/code-editor';
|
||||
|
||||
import { ExpressionInputProps } from '../types';
|
||||
import { EXPRESSIONS_LANGUAGE_ID } from '../../../common';
|
||||
|
|
|
@ -32,7 +32,8 @@
|
|||
"@kbn/saved-objects-finder-plugin",
|
||||
"@kbn/content-management-plugin",
|
||||
"@kbn/shared-ux-button-toolbar",
|
||||
"@kbn/calculate-width-from-char-count"
|
||||
"@kbn/code-editor",
|
||||
"@kbn/calculate-width-from-char-count",
|
||||
],
|
||||
"exclude": ["target/**/*"]
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { XJsonLang } from '@kbn/monaco';
|
||||
import { omit } from 'lodash';
|
||||
import { EuiButtonEmpty, EuiCopy, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
|
||||
import { CodeEditor } from '@kbn/kibana-react-plugin/public';
|
||||
import { CodeEditor } from '@kbn/code-editor';
|
||||
import { SavedObjectWithMetadata } from '../../../../common';
|
||||
|
||||
export interface InspectProps {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
"@kbn/core-ui-settings-browser",
|
||||
"@kbn/core-saved-objects-api-server",
|
||||
"@kbn/shared-ux-link-redirect-app",
|
||||
"@kbn/code-editor",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"id": "unifiedDocViewer",
|
||||
"server": false,
|
||||
"browser": true,
|
||||
"requiredBundles": ["kibanaUtils", "kibanaReact"],
|
||||
"requiredBundles": ["kibanaUtils"],
|
||||
"requiredPlugins": ["data", "fieldFormats"],
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { mountWithIntl } from '@kbn/test-jest-helpers';
|
||||
import '@kbn/code-editor-mock/jest_helper';
|
||||
import { DocViewerSource } from './source';
|
||||
import * as hooks from '../../hooks/use_es_doc_search';
|
||||
import * as useUiSettingHook from '@kbn/kibana-react-plugin/public/ui_settings/use_ui_setting';
|
||||
|
|
|
@ -12,7 +12,7 @@ import React from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { monaco, XJsonLang } from '@kbn/monaco';
|
||||
import { EuiButtonEmpty, EuiCopy, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
|
||||
import { CodeEditor } from '@kbn/kibana-react-plugin/public';
|
||||
import { CodeEditor } from '@kbn/code-editor';
|
||||
|
||||
const codeEditorAriaLabel = i18n.translate('unifiedDocViewer.json.codeEditorAriaLabel', {
|
||||
defaultMessage: 'Read only JSON view of an elasticsearch document',
|
||||
|
|
|
@ -23,7 +23,9 @@
|
|||
"@kbn/shared-ux-utility",
|
||||
"@kbn/core-analytics-browser-mocks",
|
||||
"@kbn/core-ui-settings-browser-mocks",
|
||||
"@kbn/field-utils"
|
||||
"@kbn/field-utils",
|
||||
"@kbn/code-editor",
|
||||
"@kbn/code-editor-mock"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -13,8 +13,8 @@ import { coreMock } from '@kbn/core/public/mocks';
|
|||
import type { FilterEditorProps } from '.';
|
||||
import { FilterEditor } from '.';
|
||||
|
||||
jest.mock('@kbn/kibana-react-plugin/public', () => {
|
||||
const original = jest.requireActual('@kbn/kibana-react-plugin/public');
|
||||
jest.mock('@kbn/code-editor', () => {
|
||||
const original = jest.requireActual('@kbn/code-editor');
|
||||
|
||||
return {
|
||||
...original,
|
||||
|
|
|
@ -44,7 +44,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { XJsonLang } from '@kbn/monaco';
|
||||
import { DataView } from '@kbn/data-views-plugin/common';
|
||||
import { getIndexPatternFromFilter } from '@kbn/data-plugin/public';
|
||||
import { CodeEditor } from '@kbn/kibana-react-plugin/public';
|
||||
import { CodeEditor } from '@kbn/code-editor';
|
||||
import { cx } from '@emotion/css';
|
||||
import { WithEuiThemeProps } from '@elastic/eui/src/services/theme';
|
||||
import type { DocLinksStart } from '@kbn/core-doc-links-browser';
|
||||
|
|
|
@ -42,7 +42,8 @@
|
|||
"@kbn/core-doc-links-browser",
|
||||
"@kbn/core-lifecycle-browser",
|
||||
"@kbn/ml-string-hash",
|
||||
"@kbn/calculate-width-from-char-count"
|
||||
"@kbn/code-editor",
|
||||
"@kbn/calculate-width-from-char-count",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -11,7 +11,7 @@ import React, { useState, useMemo, useCallback } from 'react';
|
|||
import { EuiFormRow, EuiIconTip } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { XJsonLang } from '@kbn/monaco';
|
||||
import { CodeEditor } from '@kbn/kibana-react-plugin/public';
|
||||
import { CodeEditor } from '@kbn/code-editor';
|
||||
import { XJson } from '@kbn/es-ui-shared-plugin/public';
|
||||
|
||||
import { AggParamEditorProps } from '../agg_param_props';
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
"@kbn/es-ui-shared-plugin",
|
||||
"@kbn/utility-types",
|
||||
"@kbn/saved-search-plugin",
|
||||
"@kbn/code-editor",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -11,7 +11,8 @@ import { EuiFormLabel } from '@elastic/eui';
|
|||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { monaco } from '@kbn/monaco';
|
||||
|
||||
import { CodeEditor, useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { CodeEditor } from '@kbn/code-editor';
|
||||
import { suggest, getSuggestion } from './timelion_expression_input_helpers';
|
||||
import { getArgValueSuggestions } from '../helpers/arg_value_suggestions';
|
||||
import { ITimelionFunction, TimelionFunctionArgs } from '../../common/types';
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue