Skip to content

Commit 6b8cba2

Browse files
Merge pull request #14663 from logonoff/CONSOLE-4407-monaco
CONSOLE-4407, CONSOLE-4409: Update monaco and YAML language server, use PF6 CodeEditor
2 parents 7e2a383 + c2d33df commit 6b8cba2

38 files changed

Lines changed: 751 additions & 827 deletions

File tree

frontend/@types/console/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ declare interface Window {
6666
webpackSharedScope?: {}; // webpack shared scope object, contains modules shared across plugins
6767
ResizeObserver: ResizeObserver.prototype; // polyfill used by react-measure
6868
Cypress?: {};
69+
monaco?: {};
6970
}
7071

7172
// From https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html

frontend/package.json

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
"@patternfly/quickstarts": "^6.2.0-prerelease.4",
138138
"@patternfly/react-catalog-view-extension": "^6.1.0-prerelease.3",
139139
"@patternfly/react-charts": "^8.2.0-prerelease.13",
140+
"@patternfly/react-code-editor": "^6.2.0-prerelease.21",
140141
"@patternfly/react-component-groups": "^6.2.0-prerelease.4",
141142
"@patternfly/react-console": "^6.0.0",
142143
"@patternfly/react-core": "^6.2.0-prerelease.15",
@@ -180,7 +181,7 @@
180181
"js-yaml": "^3.13.1",
181182
"json-schema": "^0.3.0",
182183
"lodash-es": "^4.17.21",
183-
"monaco-languageclient": "^0.13.0",
184+
"monaco-yaml": "^5.3.1",
184185
"murmurhash-js": "1.0.x",
185186
"node-polyfill-webpack-plugin": "^4.0.0",
186187
"pluralize": "^8.0.0",
@@ -197,7 +198,6 @@
197198
"react-linkify": "^0.2.2",
198199
"react-measure": "^2.2.6",
199200
"react-modal": "^3.12.1",
200-
"react-monaco-editor": "0.46.x",
201201
"react-redux": "7.2.9",
202202
"react-router": "5.3.x",
203203
"react-router-dom": "5.3.x",
@@ -219,12 +219,10 @@
219219
"typesafe-actions": "^4.2.1",
220220
"url-search-params-polyfill": "2.x",
221221
"victory": "^37.3.6",
222-
"vscode-languageserver-types": "^3.10.0",
223222
"whatwg-fetch": "2.x",
224223
"xterm": "^4.10.0",
225224
"xterm-addon-attach": "0.6.0",
226225
"xterm-addon-fit": "0.5.0",
227-
"yaml-language-server": "0.13.0",
228226
"yup": "^0.27.0"
229227
},
230228
"devDependencies": {
@@ -304,8 +302,8 @@
304302
"mochawesome-merge": "^4.1.0",
305303
"mochawesome-report-generator": "^5.1.0",
306304
"mock-socket": "^9.0.3",
307-
"monaco-editor": "^0.28.1",
308-
"monaco-editor-webpack-plugin": "^4.2.0",
305+
"monaco-editor": "^0.51.0",
306+
"monaco-editor-webpack-plugin": "^7.1.0",
309307
"prettier": "2.0.5",
310308
"react-refresh": "^0.10.0",
311309
"read-pkg": "5.x",
@@ -318,7 +316,6 @@
318316
"ts-jest": "21.x",
319317
"ts-node": "10.9.2",
320318
"typescript": "5.7.2",
321-
"umd-compat-loader": "^2.1.2",
322319
"val-loader": "^6.0.0",
323320
"webpack": "^5.75.0",
324321
"webpack-bundle-analyzer": "4.10.2",

frontend/packages/console-dynamic-plugin-sdk/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ This section documents notable changes in the Console provided shared modules ac
170170
- Removed `@fortawesome/font-awesome` and `openshift-logos-icon`. Plugins should use PatternFly icons
171171
from `@patternfly/react-icons` instead. The `fa-spin` class remains but is deprecated and will be
172172
removed in the future. Plugins should provide their own CSS to spin icons if needed.
173+
- Upgraded `monaco-editor` to version `0.51.0`.
173174
- Removed styling for generic HTML heading elements (e.g., `<h1>`). Use PatternFly components to achieve
174175
correct styling.
175176
- Removed `co-m-horizontal-nav` styling. Use [PatternFly Tabs](https://www.patternfly.org/components/tabs/)

frontend/packages/console-dynamic-plugin-sdk/src/extensions/console-types.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import * as React from 'react';
22
import { QuickStartContextValues } from '@patternfly/quickstarts';
3+
import { CodeEditorProps as PfCodeEditorProps } from '@patternfly/react-code-editor';
34
import { ButtonProps } from '@patternfly/react-core';
45
import { ICell, OnSelect, SortByDirection, TableGridBreakpoint } from '@patternfly/react-table';
56
import { LocationDescriptor } from 'history';
6-
import MonacoEditor from 'react-monaco-editor/lib/editor';
7+
import type * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
78
import {
89
ExtensionK8sGroupKindModel,
910
K8sModel,
@@ -635,20 +636,29 @@ export type UserInfo = {
635636
extra?: object;
636637
};
637638

638-
export type CodeEditorProps = {
639-
value?: string;
640-
language?: string;
641-
options?: object;
642-
minHeight?: string | number;
639+
export type CodeEditorToolbarProps = {
640+
/** Whether to show a toolbar with shortcuts on top of the editor. */
643641
showShortcuts?: boolean;
644-
showMiniMap?: boolean;
642+
/** Toolbar links section on the left side of the editor */
645643
toolbarLinks?: React.ReactNodeArray;
646-
onChange?: (newValue, event) => void;
647-
onSave?: () => void;
648644
};
649645

646+
// Omit the ref as we have our own ref type, which is completely different
647+
export type BasicCodeEditorProps = Partial<Omit<PfCodeEditorProps, 'ref'>>;
648+
649+
export type CodeEditorProps = Omit<BasicCodeEditorProps, 'code'> &
650+
CodeEditorToolbarProps & {
651+
/** Code displayed in code editor. */
652+
value?: string;
653+
/** Minimum editor height in valid CSS height values. */
654+
minHeight?: CSSStyleDeclaration['minHeight'];
655+
/** Callback that is run when CTRL / CMD + S is pressed */
656+
onSave?: () => void;
657+
};
658+
650659
export type CodeEditorRef = {
651-
editor?: MonacoEditor['editor'];
660+
editor: monaco.editor.IStandaloneCodeEditor;
661+
monaco: typeof monaco;
652662
};
653663

654664
export type ResourceYAMLEditorProps = {

frontend/packages/console-shared/locales/en/console-shared.json

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,22 @@
108108
"true": "true",
109109
"Select {{label}}": "Select {{label}}",
110110
"Cluster does not have resource {{groupVersionKind}}": "Cluster does not have resource {{groupVersionKind}}",
111-
"Ask OpenShift Lightspeed": "Ask OpenShift Lightspeed",
112-
"Accessibility help": "Accessibility help",
111+
"Copy code to clipboard": "Copy code to clipboard",
112+
"Content copied to clipboard": "Content copied to clipboard",
113+
"Download code": "Download code",
113114
"Shortcuts": "Shortcuts",
115+
"Upload code": "Upload code",
116+
"Drag and drop a file or upload one.": "Drag and drop a file or upload one.",
117+
"Browse": "Browse",
118+
"Start from scratch": "Start from scratch",
119+
"Start editing": "Start editing",
120+
"Ask OpenShift Lightspeed": "Ask OpenShift Lightspeed",
114121
"View all editor shortcuts": "View all editor shortcuts",
115122
"Activate auto complete": "Activate auto complete",
116123
"Toggle Tab action between insert Tab character and move focus out of editor": "Toggle Tab action between insert Tab character and move focus out of editor",
117124
"View document outline": "View document outline",
118125
"View property descriptions": "View property descriptions",
119126
"Save": "Save",
120-
"View shortcuts": "View shortcuts",
121127
"Restricted access": "Restricted access",
122128
"You don't have access to this section due to cluster policy": "You don't have access to this section due to cluster policy",
123129
"Error details": "Error details",
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// match the token in theme.ts. it already matches for light theme
2+
.pf-v6-theme-dark {
3+
.co-code-editor:not(.pf-m-read-only) {
4+
--pf-v6-c-code-editor__main--BackgroundColor: var(--pf-t--color--gray--90);
5+
--pf-v6-c-code-editor__tab--BackgroundColor: var(--pf-t--color--gray--90);
6+
}
7+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import * as React from 'react';
2+
import { loader, Monaco } from '@monaco-editor/react';
3+
import { CodeEditor } from '@patternfly/react-code-editor';
4+
import classNames from 'classnames';
5+
import * as monaco from 'monaco-editor';
6+
import { useTranslation } from 'react-i18next';
7+
import { BasicCodeEditorProps } from '@console/dynamic-plugin-sdk';
8+
import { ErrorBoundaryInline } from '@console/shared/src/components/error';
9+
import { useConsoleMonacoTheme } from './theme';
10+
import './BasicCodeEditor.scss';
11+
12+
// Avoid using monaco from CDN
13+
loader.config({ monaco });
14+
15+
/**
16+
* PatternFly CodeEditor with i18n and theme applied. Does not include
17+
* YAML language integration or console-specific CSS.
18+
*
19+
* Note that it is important that this is the only component that imports
20+
* monaco-editor, to avoid fetching files from a 3rd-party CDN.
21+
*/
22+
export const BasicCodeEditor: React.FC<BasicCodeEditorProps> = (props) => {
23+
const { t } = useTranslation('console-shared');
24+
const [monacoRef, setMonacoRef] = React.useState<Monaco | null>(null);
25+
useConsoleMonacoTheme(monacoRef?.editor);
26+
27+
return (
28+
<ErrorBoundaryInline>
29+
<CodeEditor
30+
copyButtonAriaLabel={t('Copy code to clipboard')}
31+
copyButtonSuccessTooltipText={t('Content copied to clipboard')}
32+
copyButtonToolTipText={t('Copy code to clipboard')}
33+
downloadButtonAriaLabel={t('Download code')}
34+
downloadButtonToolTipText={t('Download code')}
35+
shortcutsPopoverButtonText={t('Shortcuts')}
36+
uploadButtonAriaLabel={t('Upload code')}
37+
uploadButtonToolTipText={t('Upload code')}
38+
emptyStateBody={t('Drag and drop a file or upload one.')}
39+
emptyStateButton={t('Browse')}
40+
emptyStateLink={t('Start from scratch')}
41+
emptyStateTitle={t('Start editing')}
42+
{...props}
43+
className={classNames('co-code-editor', props.className)}
44+
editorProps={{
45+
...props?.editorProps,
46+
beforeMount: (monacoInstance) => {
47+
setMonacoRef(monacoInstance);
48+
window.monaco = monacoInstance; // for e2e tests
49+
props?.editorProps?.beforeMount?.(monacoInstance);
50+
},
51+
}}
52+
/>
53+
</ErrorBoundaryInline>
54+
);
55+
};
Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,49 @@
1+
@import '../../../../../public/style/vars';
2+
13
.ocs-yaml-editor {
2-
&__root {
3-
flex: 1;
4-
position: relative;
4+
// ensure editor stays fills the parent container while remaining in bounds
5+
flex-grow: 1;
6+
display: flex;
7+
flex-direction: column;
8+
9+
.co-code-editor {
10+
flex-grow: 1;
11+
}
12+
13+
.monaco-editor {
14+
position: absolute; // part of the fix for ResizeObserver issue
15+
16+
// revert custom overrides
17+
.label-name { text-decoration: none; }
18+
label { font-weight: unset; }
19+
20+
.monaco-hover-content .markdown-hover {
21+
// matches tooltip styling seen back in OpenShift 4.18
22+
max-width: 500px;
23+
word-wrap: break-word;
24+
25+
// hide "Source: yaml" in hover tooltip
26+
p:last-of-type {
27+
display: none;
28+
}
29+
}
30+
}
31+
32+
/* Hide CodeEditor toolbar on mobile */
33+
@media (max-width: $screen-sm-max) {
34+
.pf-v6-c-code-editor__header {
35+
display: none;
36+
37+
+ .pf-v6-c-code-editor__main {
38+
border-block-start-width: var(--pf-t--global--border--width--box--default);
39+
}
40+
}
541
}
642

7-
&__wrapper {
8-
position: absolute;
9-
top: 0;
10-
right: 0;
11-
left: 0;
12-
bottom: 0;
43+
/* Needed to get the CodeEditorToolbar to place buttons on the right side */
44+
.pf-v6-c-code-editor__controls, .ocs-yaml-editor-toolbar {
45+
width: 100%;
46+
height: 100% !important;
47+
align-items: center;
1348
}
1449
}

0 commit comments

Comments
 (0)