From 9674128105e5ebe73de926ea720ee48dcc346881 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Yulia=20=C4=8Cech?=
<6585477+yuliacech@users.noreply.github.com>
Date: Mon, 19 Feb 2024 12:57:17 +0100
Subject: [PATCH] [Console] Add a dev config for the editor migration (#176520)
## Summary
This PR adds a dev config to Console to enable a migration to the Monaco
editor. The config value is `false` by default and can be changed by
adding `console.dev.enableMonaco: true` to `kibana.dev.yml`. Also a new
custom Monaco language is registered for Console in the package
`kbn/monaco` and will be worked on behind the config flag iteratively in
the next weeks.
To not let the dev config get into 8.13 release, this PR will only be
merged **after** 8.13 has been branched.
After this PR is merged, the team will start re-implementing existing
Console features in the new Monaco editor, see
https://github.com/elastic/kibana/issues/176723 and
https://github.com/elastic/kibana/issues/176926
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
---
packages/kbn-monaco/index.ts | 2 +
packages/kbn-monaco/src/console/constants.ts | 9 +++
packages/kbn-monaco/src/console/index.ts | 10 ++++
packages/kbn-monaco/src/console/language.ts | 60 +++++++++++++++++++
packages/kbn-monaco/src/register_globals.ts | 2 +
.../application/containers/editor/editor.tsx | 4 ++
.../editor/monaco/monaco_editor.tsx | 25 ++++++++
.../contexts/services_context.mock.ts | 3 +
.../application/contexts/services_context.tsx | 3 +
.../console/public/application/index.tsx | 5 ++
src/plugins/console/public/plugin.ts | 2 +
src/plugins/console/public/types/config.ts | 3 +
src/plugins/console/server/config.ts | 2 +
src/plugins/console/tsconfig.json | 2 +
.../test_suites/core_plugins/rendering.ts | 1 +
15 files changed, 133 insertions(+)
create mode 100644 packages/kbn-monaco/src/console/constants.ts
create mode 100644 packages/kbn-monaco/src/console/index.ts
create mode 100644 packages/kbn-monaco/src/console/language.ts
create mode 100644 src/plugins/console/public/application/containers/editor/monaco/monaco_editor.tsx
diff --git a/packages/kbn-monaco/index.ts b/packages/kbn-monaco/index.ts
index c764bc679c1ab..49f93e85e77d1 100644
--- a/packages/kbn-monaco/index.ts
+++ b/packages/kbn-monaco/index.ts
@@ -31,3 +31,5 @@ import { registerLanguage } from './src/helpers';
export { BarePluginApi, registerLanguage };
export * from './src/types';
+
+export { CONSOLE_LANG_ID } from './src/console';
diff --git a/packages/kbn-monaco/src/console/constants.ts b/packages/kbn-monaco/src/console/constants.ts
new file mode 100644
index 0000000000000..b777e6eb22532
--- /dev/null
+++ b/packages/kbn-monaco/src/console/constants.ts
@@ -0,0 +1,9 @@
+/*
+ * 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.
+ */
+
+export const CONSOLE_LANG_ID = 'console';
diff --git a/packages/kbn-monaco/src/console/index.ts b/packages/kbn-monaco/src/console/index.ts
new file mode 100644
index 0000000000000..ba35b66f2156f
--- /dev/null
+++ b/packages/kbn-monaco/src/console/index.ts
@@ -0,0 +1,10 @@
+/*
+ * 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.
+ */
+
+export { CONSOLE_LANG_ID } from './constants';
+export { ConsoleLang } from './language';
diff --git a/packages/kbn-monaco/src/console/language.ts b/packages/kbn-monaco/src/console/language.ts
new file mode 100644
index 0000000000000..77c795d76d9ea
--- /dev/null
+++ b/packages/kbn-monaco/src/console/language.ts
@@ -0,0 +1,60 @@
+/*
+ * 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 { LangModuleType } from '../types';
+import { CONSOLE_LANG_ID } from './constants';
+import { monaco } from '../monaco_imports';
+
+export const languageConfiguration: monaco.languages.LanguageConfiguration = {};
+
+export const lexerRules: monaco.languages.IMonarchLanguage = {
+ defaultToken: 'invalid',
+ regex_method: /get|post|put|patch|delete/,
+ regex_url: /.*$/,
+ // C# style strings
+ escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
+ ignoreCase: true,
+ tokenizer: {
+ root: [
+ // whitespace
+ { include: '@rule_whitespace' },
+ // start a multi-line comment
+ { include: '@rule_start_multi_comment' },
+ // a one-line comment
+ [/\/\/.*$/, 'comment'],
+ // method
+ [/@regex_method/, 'keyword'],
+ // url
+ [/@regex_url/, 'identifier'],
+ ],
+ rule_whitespace: [[/[ \t\r\n]+/, 'WHITESPACE']],
+ rule_start_multi_comment: [[/\/\*/, 'comment', '@rule_multi_comment']],
+ rule_multi_comment: [
+ // match everything on a single line inside the comment except for chars / and *
+ [/[^\/*]+/, 'comment'],
+ // start a nested comment by going 1 level down
+ [/\/\*/, 'comment', '@push'],
+ // match the closing of the comment and return 1 level up
+ ['\\*/', 'comment', '@pop'],
+ // match individual chars inside a multi-line comment
+ [/[\/*]/, 'comment'],
+ ],
+ string: [
+ [/[^\\"]+/, 'string'],
+ [/@escapes/, 'string.escape'],
+ [/\\./, 'string.escape.invalid'],
+ [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }],
+ ],
+ },
+};
+
+export const ConsoleLang: LangModuleType = {
+ ID: CONSOLE_LANG_ID,
+ lexerRules,
+ languageConfiguration,
+};
diff --git a/packages/kbn-monaco/src/register_globals.ts b/packages/kbn-monaco/src/register_globals.ts
index 159563a8d0d9c..5483c5d377194 100644
--- a/packages/kbn-monaco/src/register_globals.ts
+++ b/packages/kbn-monaco/src/register_globals.ts
@@ -13,6 +13,7 @@ import { monaco } from './monaco_imports';
import { ESQL_THEME_ID, ESQLLang, buildESQlTheme } from './esql';
import { YAML_LANG_ID } from './yaml';
import { registerLanguage, registerTheme } from './helpers';
+import { ConsoleLang } from './console';
export const DEFAULT_WORKER_ID = 'default';
const langSpecificWorkerIds = [
@@ -30,6 +31,7 @@ registerLanguage(XJsonLang);
registerLanguage(PainlessLang);
registerLanguage(SQLLang);
registerLanguage(ESQLLang);
+registerLanguage(ConsoleLang);
/**
* Register custom themes
diff --git a/src/plugins/console/public/application/containers/editor/editor.tsx b/src/plugins/console/public/application/containers/editor/editor.tsx
index 788039a2dc606..580232048b28f 100644
--- a/src/plugins/console/public/application/containers/editor/editor.tsx
+++ b/src/plugins/console/public/application/containers/editor/editor.tsx
@@ -16,6 +16,7 @@ import { Editor as EditorUI, EditorOutput } from './legacy/console_editor';
import { getAutocompleteInfo, StorageKeys } from '../../../services';
import { useEditorReadContext, useServicesContext, useRequestReadContext } from '../../contexts';
import type { SenseEditor } from '../../models';
+import { MonacoEditor } from './monaco/monaco_editor';
const INITIAL_PANEL_WIDTH = 50;
const PANEL_MIN_WIDTH = '100px';
@@ -28,6 +29,7 @@ interface Props {
export const Editor = memo(({ loading, setEditorInstance }: Props) => {
const {
services: { storage },
+ config: { isMonacoEnabled } = {},
} = useServicesContext();
const { currentTextObject } = useEditorReadContext();
@@ -71,6 +73,8 @@ export const Editor = memo(({ loading, setEditorInstance }: Props) => {
>
{loading ? (
+ ) : isMonacoEnabled ? (
+
) : (
{
+ const [value, setValue] = useState('GET /.kibana/_search');
+ return (
+
+
+
+ );
+};
diff --git a/src/plugins/console/public/application/contexts/services_context.mock.ts b/src/plugins/console/public/application/contexts/services_context.mock.ts
index 5d3c7ea6e172d..f02a6df5ff996 100644
--- a/src/plugins/console/public/application/contexts/services_context.mock.ts
+++ b/src/plugins/console/public/application/contexts/services_context.mock.ts
@@ -44,6 +44,9 @@ export const serviceContextMock = {
docLinkVersion: 'NA',
theme$: themeServiceMock.create().start().theme$,
docLinks: docLinksServiceMock.createStartContract().links,
+ config: {
+ isMonacoEnabled: false,
+ },
};
},
};
diff --git a/src/plugins/console/public/application/contexts/services_context.tsx b/src/plugins/console/public/application/contexts/services_context.tsx
index a9fb86175d02c..d2c91e7c73604 100644
--- a/src/plugins/console/public/application/contexts/services_context.tsx
+++ b/src/plugins/console/public/application/contexts/services_context.tsx
@@ -32,6 +32,9 @@ export interface ContextValue {
docLinkVersion: string;
theme$: Observable;
docLinks: DocLinksStart['links'];
+ config?: {
+ isMonacoEnabled: boolean;
+ };
}
interface ContextProps {
diff --git a/src/plugins/console/public/application/index.tsx b/src/plugins/console/public/application/index.tsx
index 83ee337fdac1e..e211e1557476a 100644
--- a/src/plugins/console/public/application/index.tsx
+++ b/src/plugins/console/public/application/index.tsx
@@ -43,6 +43,7 @@ export interface BootDependencies {
theme$: Observable;
docLinks: DocLinksStart['links'];
autocompleteInfo: AutocompleteInfo;
+ isMonacoEnabled: boolean;
}
export async function renderApp({
@@ -55,6 +56,7 @@ export async function renderApp({
theme$,
docLinks,
autocompleteInfo,
+ isMonacoEnabled,
}: BootDependencies) {
const trackUiMetric = createUsageTracker(usageCollection);
trackUiMetric.load('opened_app');
@@ -92,6 +94,9 @@ export async function renderApp({
autocompleteInfo,
},
theme$,
+ config: {
+ isMonacoEnabled,
+ },
}}
>
diff --git a/src/plugins/console/public/plugin.ts b/src/plugins/console/public/plugin.ts
index ca097322486ea..45a28e0e0c445 100644
--- a/src/plugins/console/public/plugin.ts
+++ b/src/plugins/console/public/plugin.ts
@@ -34,6 +34,7 @@ export class ConsoleUIPlugin implements Plugin();
this.autocompleteInfo.setup(http);
@@ -83,6 +84,7 @@ export class ConsoleUIPlugin implements Plugin = {
exposeToBrowser: {
ui: true,
autocompleteDefinitions: true,
+ dev: true,
},
schema: schemaLatest,
deprecations: () => [],
diff --git a/src/plugins/console/tsconfig.json b/src/plugins/console/tsconfig.json
index 925cef9cbbbab..28583a28bfcde 100644
--- a/src/plugins/console/tsconfig.json
+++ b/src/plugins/console/tsconfig.json
@@ -27,6 +27,8 @@
"@kbn/core-elasticsearch-server",
"@kbn/core-http-browser-mocks",
"@kbn/react-kibana-context-theme",
+ "@kbn/code-editor",
+ "@kbn/monaco",
],
"exclude": [
"target/**/*",
diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts
index e6434471a08cf..d58da62a8a956 100644
--- a/test/plugin_functional/test_suites/core_plugins/rendering.ts
+++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts
@@ -101,6 +101,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
// When plugin owners make a change that exposes additional config values, the changes will be reflected in this test assertion.
// Ensure that your change does not unintentionally expose any sensitive values!
'console.autocompleteDefinitions.endpointsAvailability (alternatives)',
+ 'console.dev.enableMonaco (boolean)',
'console.ui.enabled (boolean)',
'console.ui.embeddedEnabled (boolean)',
'dashboard.allowByValueEmbeddables (boolean)',