diff --git a/frontend/@types/console/index.d.ts b/frontend/@types/console/index.d.ts index 927f6147a93..023a486eae9 100644 --- a/frontend/@types/console/index.d.ts +++ b/frontend/@types/console/index.d.ts @@ -66,6 +66,7 @@ declare interface Window { webpackSharedScope?: {}; // webpack shared scope object, contains modules shared across plugins ResizeObserver: ResizeObserver.prototype; // polyfill used by react-measure Cypress?: {}; + monaco?: {}; } // From https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html diff --git a/frontend/package.json b/frontend/package.json index 0ed2cba9aac..4d224db480c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -137,6 +137,7 @@ "@patternfly/quickstarts": "^6.2.0-prerelease.4", "@patternfly/react-catalog-view-extension": "^6.1.0-prerelease.3", "@patternfly/react-charts": "^8.2.0-prerelease.13", + "@patternfly/react-code-editor": "^6.2.0-prerelease.21", "@patternfly/react-component-groups": "^6.2.0-prerelease.4", "@patternfly/react-console": "^6.0.0", "@patternfly/react-core": "^6.2.0-prerelease.15", @@ -180,7 +181,7 @@ "js-yaml": "^3.13.1", "json-schema": "^0.3.0", "lodash-es": "^4.17.21", - "monaco-languageclient": "^0.13.0", + "monaco-yaml": "^5.3.1", "murmurhash-js": "1.0.x", "node-polyfill-webpack-plugin": "^4.0.0", "pluralize": "^8.0.0", @@ -197,7 +198,6 @@ "react-linkify": "^0.2.2", "react-measure": "^2.2.6", "react-modal": "^3.12.1", - "react-monaco-editor": "0.46.x", "react-redux": "7.2.9", "react-router": "5.3.x", "react-router-dom": "5.3.x", @@ -219,12 +219,10 @@ "typesafe-actions": "^4.2.1", "url-search-params-polyfill": "2.x", "victory": "^37.3.6", - "vscode-languageserver-types": "^3.10.0", "whatwg-fetch": "2.x", "xterm": "^4.10.0", "xterm-addon-attach": "0.6.0", "xterm-addon-fit": "0.5.0", - "yaml-language-server": "0.13.0", "yup": "^0.27.0" }, "devDependencies": { @@ -304,8 +302,8 @@ "mochawesome-merge": "^4.1.0", "mochawesome-report-generator": "^5.1.0", "mock-socket": "^9.0.3", - "monaco-editor": "^0.28.1", - "monaco-editor-webpack-plugin": "^4.2.0", + "monaco-editor": "^0.51.0", + "monaco-editor-webpack-plugin": "^7.1.0", "prettier": "2.0.5", "react-refresh": "^0.10.0", "read-pkg": "5.x", @@ -318,7 +316,6 @@ "ts-jest": "21.x", "ts-node": "10.9.2", "typescript": "5.7.2", - "umd-compat-loader": "^2.1.2", "val-loader": "^6.0.0", "webpack": "^5.75.0", "webpack-bundle-analyzer": "4.10.2", diff --git a/frontend/packages/console-dynamic-plugin-sdk/README.md b/frontend/packages/console-dynamic-plugin-sdk/README.md index d3c620e08b1..07f3f36a269 100644 --- a/frontend/packages/console-dynamic-plugin-sdk/README.md +++ b/frontend/packages/console-dynamic-plugin-sdk/README.md @@ -170,6 +170,7 @@ This section documents notable changes in the Console provided shared modules ac - Removed `@fortawesome/font-awesome` and `openshift-logos-icon`. Plugins should use PatternFly icons from `@patternfly/react-icons` instead. The `fa-spin` class remains but is deprecated and will be removed in the future. Plugins should provide their own CSS to spin icons if needed. +- Upgraded `monaco-editor` to version `0.51.0`. - Removed styling for generic HTML heading elements (e.g., `

`). Use PatternFly components to achieve correct styling. - Removed `co-m-horizontal-nav` styling. Use [PatternFly Tabs](https://www.patternfly.org/components/tabs/) diff --git a/frontend/packages/console-dynamic-plugin-sdk/src/extensions/console-types.ts b/frontend/packages/console-dynamic-plugin-sdk/src/extensions/console-types.ts index 23148ba111e..9c175bec342 100644 --- a/frontend/packages/console-dynamic-plugin-sdk/src/extensions/console-types.ts +++ b/frontend/packages/console-dynamic-plugin-sdk/src/extensions/console-types.ts @@ -1,9 +1,10 @@ import * as React from 'react'; import { QuickStartContextValues } from '@patternfly/quickstarts'; +import { CodeEditorProps as PfCodeEditorProps } from '@patternfly/react-code-editor'; import { ButtonProps } from '@patternfly/react-core'; import { ICell, OnSelect, SortByDirection, TableGridBreakpoint } from '@patternfly/react-table'; import { LocationDescriptor } from 'history'; -import MonacoEditor from 'react-monaco-editor/lib/editor'; +import type * as monaco from 'monaco-editor/esm/vs/editor/editor.api'; import { ExtensionK8sGroupKindModel, K8sModel, @@ -635,20 +636,29 @@ export type UserInfo = { extra?: object; }; -export type CodeEditorProps = { - value?: string; - language?: string; - options?: object; - minHeight?: string | number; +export type CodeEditorToolbarProps = { + /** Whether to show a toolbar with shortcuts on top of the editor. */ showShortcuts?: boolean; - showMiniMap?: boolean; + /** Toolbar links section on the left side of the editor */ toolbarLinks?: React.ReactNodeArray; - onChange?: (newValue, event) => void; - onSave?: () => void; }; +// Omit the ref as we have our own ref type, which is completely different +export type BasicCodeEditorProps = Partial>; + +export type CodeEditorProps = Omit & + CodeEditorToolbarProps & { + /** Code displayed in code editor. */ + value?: string; + /** Minimum editor height in valid CSS height values. */ + minHeight?: CSSStyleDeclaration['minHeight']; + /** Callback that is run when CTRL / CMD + S is pressed */ + onSave?: () => void; + }; + export type CodeEditorRef = { - editor?: MonacoEditor['editor']; + editor: monaco.editor.IStandaloneCodeEditor; + monaco: typeof monaco; }; export type ResourceYAMLEditorProps = { diff --git a/frontend/packages/console-shared/locales/en/console-shared.json b/frontend/packages/console-shared/locales/en/console-shared.json index 6d30c3f5891..747024bef21 100644 --- a/frontend/packages/console-shared/locales/en/console-shared.json +++ b/frontend/packages/console-shared/locales/en/console-shared.json @@ -108,16 +108,22 @@ "true": "true", "Select {{label}}": "Select {{label}}", "Cluster does not have resource {{groupVersionKind}}": "Cluster does not have resource {{groupVersionKind}}", - "Ask OpenShift Lightspeed": "Ask OpenShift Lightspeed", - "Accessibility help": "Accessibility help", + "Copy code to clipboard": "Copy code to clipboard", + "Content copied to clipboard": "Content copied to clipboard", + "Download code": "Download code", "Shortcuts": "Shortcuts", + "Upload code": "Upload code", + "Drag and drop a file or upload one.": "Drag and drop a file or upload one.", + "Browse": "Browse", + "Start from scratch": "Start from scratch", + "Start editing": "Start editing", + "Ask OpenShift Lightspeed": "Ask OpenShift Lightspeed", "View all editor shortcuts": "View all editor shortcuts", "Activate auto complete": "Activate auto complete", "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", "View document outline": "View document outline", "View property descriptions": "View property descriptions", "Save": "Save", - "View shortcuts": "View shortcuts", "Restricted access": "Restricted access", "You don't have access to this section due to cluster policy": "You don't have access to this section due to cluster policy", "Error details": "Error details", diff --git a/frontend/packages/console-shared/src/components/editor/BasicCodeEditor.scss b/frontend/packages/console-shared/src/components/editor/BasicCodeEditor.scss new file mode 100644 index 00000000000..c2b76cc9de8 --- /dev/null +++ b/frontend/packages/console-shared/src/components/editor/BasicCodeEditor.scss @@ -0,0 +1,7 @@ +// match the token in theme.ts. it already matches for light theme +.pf-v6-theme-dark { + .co-code-editor:not(.pf-m-read-only) { + --pf-v6-c-code-editor__main--BackgroundColor: var(--pf-t--color--gray--90); + --pf-v6-c-code-editor__tab--BackgroundColor: var(--pf-t--color--gray--90); + } +} diff --git a/frontend/packages/console-shared/src/components/editor/BasicCodeEditor.tsx b/frontend/packages/console-shared/src/components/editor/BasicCodeEditor.tsx new file mode 100644 index 00000000000..281e8ce03d6 --- /dev/null +++ b/frontend/packages/console-shared/src/components/editor/BasicCodeEditor.tsx @@ -0,0 +1,55 @@ +import * as React from 'react'; +import { loader, Monaco } from '@monaco-editor/react'; +import { CodeEditor } from '@patternfly/react-code-editor'; +import classNames from 'classnames'; +import * as monaco from 'monaco-editor'; +import { useTranslation } from 'react-i18next'; +import { BasicCodeEditorProps } from '@console/dynamic-plugin-sdk'; +import { ErrorBoundaryInline } from '@console/shared/src/components/error'; +import { useConsoleMonacoTheme } from './theme'; +import './BasicCodeEditor.scss'; + +// Avoid using monaco from CDN +loader.config({ monaco }); + +/** + * PatternFly CodeEditor with i18n and theme applied. Does not include + * YAML language integration or console-specific CSS. + * + * Note that it is important that this is the only component that imports + * monaco-editor, to avoid fetching files from a 3rd-party CDN. + */ +export const BasicCodeEditor: React.FC = (props) => { + const { t } = useTranslation('console-shared'); + const [monacoRef, setMonacoRef] = React.useState(null); + useConsoleMonacoTheme(monacoRef?.editor); + + return ( + + { + setMonacoRef(monacoInstance); + window.monaco = monacoInstance; // for e2e tests + props?.editorProps?.beforeMount?.(monacoInstance); + }, + }} + /> + + ); +}; diff --git a/frontend/packages/console-shared/src/components/editor/CodeEditor.scss b/frontend/packages/console-shared/src/components/editor/CodeEditor.scss index 51a1c002fce..2c8aedbc3a7 100644 --- a/frontend/packages/console-shared/src/components/editor/CodeEditor.scss +++ b/frontend/packages/console-shared/src/components/editor/CodeEditor.scss @@ -1,14 +1,49 @@ +@import '../../../../../public/style/vars'; + .ocs-yaml-editor { - &__root { - flex: 1; - position: relative; + // ensure editor stays fills the parent container while remaining in bounds + flex-grow: 1; + display: flex; + flex-direction: column; + + .co-code-editor { + flex-grow: 1; + } + + .monaco-editor { + position: absolute; // part of the fix for ResizeObserver issue + + // revert custom overrides + .label-name { text-decoration: none; } + label { font-weight: unset; } + + .monaco-hover-content .markdown-hover { + // matches tooltip styling seen back in OpenShift 4.18 + max-width: 500px; + word-wrap: break-word; + + // hide "Source: yaml" in hover tooltip + p:last-of-type { + display: none; + } + } + } + + /* Hide CodeEditor toolbar on mobile */ + @media (max-width: $screen-sm-max) { + .pf-v6-c-code-editor__header { + display: none; + + + .pf-v6-c-code-editor__main { + border-block-start-width: var(--pf-t--global--border--width--box--default); + } + } } - &__wrapper { - position: absolute; - top: 0; - right: 0; - left: 0; - bottom: 0; + /* Needed to get the CodeEditorToolbar to place buttons on the right side */ + .pf-v6-c-code-editor__controls, .ocs-yaml-editor-toolbar { + width: 100%; + height: 100% !important; + align-items: center; } } diff --git a/frontend/packages/console-shared/src/components/editor/CodeEditor.tsx b/frontend/packages/console-shared/src/components/editor/CodeEditor.tsx index bbe9d8b4c9f..29015c0ee4e 100644 --- a/frontend/packages/console-shared/src/components/editor/CodeEditor.tsx +++ b/frontend/packages/console-shared/src/components/editor/CodeEditor.tsx @@ -1,36 +1,34 @@ import * as React from 'react'; -import Measure from 'react-measure'; -import MonacoEditor from 'react-monaco-editor'; -import { CodeEditorProps } from '@console/dynamic-plugin-sdk'; -import { ThemeContext } from '@console/internal/components/ThemeProvider'; -import CodeEditorToolbar from './CodeEditorToolbar'; -import { registerYAMLinMonaco, defaultEditorOptions } from './yaml-editor-utils'; -import './theme'; +import { EditorDidMount, Language } from '@patternfly/react-code-editor'; +import { getResizeObserver } from '@patternfly/react-core'; +import { CodeEditorRef, CodeEditorProps } from '@console/dynamic-plugin-sdk'; +import { BasicCodeEditor } from './BasicCodeEditor'; +import { CodeEditorToolbar } from './CodeEditorToolbar'; +import { useShortcutPopover } from './ShortcutsPopover'; +import { registerYAMLinMonaco, registerAutoFold, defaultEditorOptions } from './yaml-editor-utils'; import './CodeEditor.scss'; -const CodeEditor = React.forwardRef((props, ref) => { - const { - value, - options = defaultEditorOptions, - showShortcuts, - showMiniMap, - toolbarLinks, - minHeight, - onChange, - onSave, - language, - } = props; +const CodeEditor = React.forwardRef((props, ref) => { + const { value, minHeight, showShortcuts, toolbarLinks, onSave, onEditorDidMount } = props; - const theme = React.useContext(ThemeContext); + const [editorRef, setEditorRef] = React.useState(null); + const [monacoRef, setMonacoRef] = React.useState(null); const [usesValue] = React.useState(value !== undefined); - const editorDidMount = React.useCallback( + + const shortcutPopover = useShortcutPopover(); + + const editorDidMount: EditorDidMount = React.useCallback( (editor, monaco) => { - const currentLanguage = editor.getModel()?.getModeId(); + setEditorRef(editor); + setMonacoRef(monaco); + editor.getModel()?.updateOptions({ tabSize: 2 }); + const currentLanguage = editor.getModel()?.getLanguageId(); editor.layout(); editor.focus(); switch (currentLanguage) { case 'yaml': - registerYAMLinMonaco(editor, monaco, usesValue); + registerYAMLinMonaco(monaco); + registerAutoFold(editor, usesValue); break; case 'json': editor.getAction('editor.action.formatDocument').run(); @@ -38,44 +36,59 @@ const CodeEditor = React.forwardRef((props, ref) default: break; } - monaco.editor.getModels()[0]?.updateOptions({ tabSize: 2 }); - onSave && editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S, onSave); // eslint-disable-line no-bitwise + onSave && editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, onSave); // eslint-disable-line no-bitwise + onEditorDidMount && onEditorDidMount(editor, monaco); }, - [onSave, usesValue], + [onSave, usesValue, onEditorDidMount], + ); + + // expose the editor instance to the parent component via ref + React.useImperativeHandle( + ref, + () => ({ + editor: editorRef, + monaco: monacoRef, + }), + [editorRef, monacoRef], ); - const editorOptions = React.useMemo(() => { - return { - ...options, - minimap: { - enabled: showMiniMap, - }, - }; - }, [options, showMiniMap]); + // do not render toolbar if the component is null + const ToolbarLinks = React.useMemo(() => { + return showShortcuts || toolbarLinks?.length ? ( + + ) : undefined; + }, [toolbarLinks, showShortcuts]); + + // recalculate bounds when viewport is changed + const handleResize = React.useCallback(() => { + monacoRef?.editor?.getEditors()?.forEach((editor) => { + editor.layout({ width: 0, height: 0 }); + editor.layout(); + }); + }, [monacoRef]); + + React.useEffect(() => { + const observer = getResizeObserver(undefined, handleResize, true); + return () => observer(); + }, [handleResize]); + + React.useEffect(() => { + handleResize(); + }, [handleResize, minHeight, ToolbarLinks]); return ( - <> - - - {({ measureRef, contentRect }) => ( -
-
- -
-
- )} -
- +
+ +
); }); diff --git a/frontend/packages/console-shared/src/components/editor/CodeEditorSidebar.tsx b/frontend/packages/console-shared/src/components/editor/CodeEditorSidebar.tsx index 9f62a37d6ec..751dbabbb32 100644 --- a/frontend/packages/console-shared/src/components/editor/CodeEditorSidebar.tsx +++ b/frontend/packages/console-shared/src/components/editor/CodeEditorSidebar.tsx @@ -1,14 +1,14 @@ import * as React from 'react'; import { JSONSchema7 } from 'json-schema'; import { Range, Selection } from 'monaco-editor'; -import MonacoEditor from 'react-monaco-editor'; +import { CodeEditorRef } from '@console/dynamic-plugin-sdk'; import { ResourceSidebar } from '@console/internal/components/sidebars/resource-sidebar'; import { K8sKind } from '@console/internal/module/k8s'; import { Sample } from '../../utils'; import { downloadYaml } from './yaml-download-utils'; type CodeEditorSidebarProps = { - editorRef: React.MutableRefObject; + editorRef: React.MutableRefObject; model?: K8sKind; samples?: Sample[]; schema?: JSONSchema7; @@ -34,7 +34,7 @@ const CodeEditorSidebar: React.FC = ({ (id: string = 'default', yamlContent: string = '', kind) => { const yaml = sanitizeYamlContent ? sanitizeYamlContent(id, yamlContent, kind) : yamlContent; - const selection = editor.getSelection(); + const selection = editor?.getSelection(); const range = new Range( selection.startLineNumber, selection.startColumn, @@ -64,8 +64,8 @@ const CodeEditorSidebar: React.FC = ({ ); const op = { range, text: indentedText, forceMoveMarkers: true }; - editor.executeEdits(id, [op], [newContentSelection]); - editor.focus(); + editor?.executeEdits(id, [op], [newContentSelection]); + editor?.focus(); }, [editor, sanitizeYamlContent], ); @@ -73,7 +73,7 @@ const CodeEditorSidebar: React.FC = ({ const replaceYamlContent = React.useCallback( (id: string = 'default', yamlContent: string = '', kind: string) => { const yaml = sanitizeYamlContent ? sanitizeYamlContent(id, yamlContent, kind) : yamlContent; - editor.setValue(yaml); + editor?.setValue(yaml); }, [editor, sanitizeYamlContent], ); diff --git a/frontend/packages/console-shared/src/components/editor/CodeEditorToolbar.scss b/frontend/packages/console-shared/src/components/editor/CodeEditorToolbar.scss deleted file mode 100644 index 3e4ccd523e4..00000000000 --- a/frontend/packages/console-shared/src/components/editor/CodeEditorToolbar.scss +++ /dev/null @@ -1,16 +0,0 @@ -@import '../../../../../public/style/vars'; - -.ocs-yaml-editor-shortcut__text { - color: var(--pf-t--global--text--color--subtle); - margin-left: var(--pf-t--global--spacer--sm); -} - -.ocs-yaml-editor-toolbar { - align-items: center; -} - -@media (max-width: $screen-sm-max) { - .ocs-yaml-editor-toolbar__link { - display: none; - } -} diff --git a/frontend/packages/console-shared/src/components/editor/CodeEditorToolbar.tsx b/frontend/packages/console-shared/src/components/editor/CodeEditorToolbar.tsx index 5d2341e5ebe..3d91ef5a26f 100644 --- a/frontend/packages/console-shared/src/components/editor/CodeEditorToolbar.tsx +++ b/frontend/packages/console-shared/src/components/editor/CodeEditorToolbar.tsx @@ -1,86 +1,50 @@ import * as React from 'react'; -import { Button, Divider } from '@patternfly/react-core'; +import { Button, Flex, FlexItem } from '@patternfly/react-core'; import { MagicIcon } from '@patternfly/react-icons'; import { useTranslation } from 'react-i18next'; import { useDispatch } from 'react-redux'; import { action } from 'typesafe-actions'; +import { CodeEditorToolbarProps } from '@console/dynamic-plugin-sdk'; import { ActionType } from '@console/internal/reducers/ols'; import { useOLSConfig } from '../../hooks/ols-hook'; -import { isMac, ShortcutCommand } from '../shortcuts/Shortcut'; -import ShortcutsLink from './ShortcutsLink'; -import './CodeEditorToolbar.scss'; - -interface CodeEditorToolbarProps { - showShortcuts?: boolean; - toolbarLinks?: React.ReactNodeArray; -} - -const CodeEditorToolbar: React.FC = ({ showShortcuts, toolbarLinks }) => { - const { t } = useTranslation(); +export const AskOpenShiftLightspeedButton: React.FC = () => { + const { t } = useTranslation('console-shared'); const openOLS = () => action(ActionType.OpenOLS); const showLightspeedButton = useOLSConfig(); const dispatch = useDispatch(); + + return showLightspeedButton ? ( + + ) : null; +}; + +export const CodeEditorToolbar: React.FC = ({ + showShortcuts, + toolbarLinks, +}) => { if (!showShortcuts && !toolbarLinks?.length) return null; return ( -
-
- {showLightspeedButton && ( -
- - -
- )} -
-
- - {isMac ? '⌥ Opt' : 'Alt'} - F1 - - - {t('console-shared~Accessibility help')} - -
-
- {showShortcuts && ( -
- - -
- )} + <> + + + {toolbarLinks && toolbarLinks.map((link, index) => ( // eslint-disable-next-line react/no-array-index-key -
- {(showShortcuts || index > 0) && link ? ( - - ) : null} -
{link}
-
+ {link} ))} -
-
+ + ); }; export default CodeEditorToolbar; diff --git a/frontend/packages/console-shared/src/components/editor/ShortcutsLink.tsx b/frontend/packages/console-shared/src/components/editor/ShortcutsLink.tsx deleted file mode 100644 index 526ead1e407..00000000000 --- a/frontend/packages/console-shared/src/components/editor/ShortcutsLink.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import * as React from 'react'; -import { Popover, Button } from '@patternfly/react-core'; -import { QuestionCircleIcon } from '@patternfly/react-icons/dist/esm/icons/question-circle-icon'; -import { useTranslation } from 'react-i18next'; -import { ShortcutTable, Shortcut } from '../shortcuts'; -import { isMac } from '../shortcuts/Shortcut'; - -interface ShortcutsLinkProps { - onHideShortcuts?: () => {}; -} - -const ShortcutsLink: React.FC = ({ onHideShortcuts }) => { - const { t } = useTranslation(); - return ( - - - {t('console-shared~Accessibility help')} - - {t('console-shared~View all editor shortcuts')} - - {t('console-shared~Activate auto complete')} - - - {t( - 'console-shared~Toggle Tab action between insert Tab character and move focus out of editor', - )} - - - {t('console-shared~View document outline')} - - {t('console-shared~View property descriptions')} - - {t('console-shared~Save')} - - - } - maxWidth="25rem" - distance={18} - onHide={onHideShortcuts} - > - - - ); -}; - -export default ShortcutsLink; diff --git a/frontend/packages/console-shared/src/components/editor/ShortcutsPopover.tsx b/frontend/packages/console-shared/src/components/editor/ShortcutsPopover.tsx new file mode 100644 index 00000000000..d0ef435181b --- /dev/null +++ b/frontend/packages/console-shared/src/components/editor/ShortcutsPopover.tsx @@ -0,0 +1,34 @@ +import * as React from 'react'; +import { PopoverProps } from '@patternfly/react-core'; +import { useTranslation } from 'react-i18next'; +import { ShortcutTable, Shortcut } from '../shortcuts'; +import { isMac } from '../shortcuts/Shortcut'; + +export const useShortcutPopover = (onHideShortcuts?: () => {}): PopoverProps => { + const { t } = useTranslation('console-shared'); + + return { + 'aria-label': t('Shortcuts'), + bodyContent: ( + + {t('View all editor shortcuts')} + + {t('Activate auto complete')} + + + {t('Toggle Tab action between insert Tab character and move focus out of editor')} + + + {t('View document outline')} + + {t('View property descriptions')} + + {t('Save')} + + + ), + maxWidth: '25rem', + distance: 18, + onHide: onHideShortcuts, + }; +}; diff --git a/frontend/packages/console-shared/src/components/editor/__tests__/CodeEditorToolbar.spec.tsx b/frontend/packages/console-shared/src/components/editor/__tests__/CodeEditorToolbar.spec.tsx index 64f3163f16d..0ff52b9ae7c 100644 --- a/frontend/packages/console-shared/src/components/editor/__tests__/CodeEditorToolbar.spec.tsx +++ b/frontend/packages/console-shared/src/components/editor/__tests__/CodeEditorToolbar.spec.tsx @@ -5,8 +5,7 @@ import { useTranslation } from 'react-i18next'; import { useDispatch } from 'react-redux'; import { ActionType } from '@console/internal/reducers/ols'; import { useOLSConfig } from '../../../hooks/ols-hook'; -import CodeEditorToolbar from '../CodeEditorToolbar'; -import ShortcutsLink from '../ShortcutsLink'; +import { AskOpenShiftLightspeedButton, CodeEditorToolbar } from '../CodeEditorToolbar'; jest.mock('react-i18next', () => ({ useTranslation: jest.fn(), @@ -35,11 +34,6 @@ describe('CodeEditorToolbar', () => { expect(wrapper.isEmptyRender()).toBe(true); }); - it('should render toolbar with shortcuts when showShortcuts is true', () => { - wrapper = shallow(); - expect(wrapper.find(ShortcutsLink).exists()).toBe(true); - }); - it('should render toolbar with custom links when toolbarLinks are provided', () => { const toolbarLinks = [
Custom Link
]; wrapper = shallow(); @@ -48,19 +42,19 @@ describe('CodeEditorToolbar', () => { it('should render "Ask OpenShift Lightspeed" button when showLightspeedButton is true', () => { (useOLSConfig as jest.Mock).mockReturnValue(true); - wrapper = shallow(); + wrapper = shallow(); expect(wrapper.find(Button).prop('children')).toBe('console-shared~Ask OpenShift Lightspeed'); }); it('should not render "Ask OpenShift Lightspeed" button when showLightspeedButton is false', () => { (useOLSConfig as jest.Mock).mockReturnValue(false); - wrapper = shallow(); + wrapper = shallow(); expect(wrapper.find(Button).exists()).toBe(false); }); it('should dispatch OpenOLS action when "Ask OpenShift Lightspeed" button is clicked', () => { (useOLSConfig as jest.Mock).mockReturnValue(true); - wrapper = shallow(); + wrapper = shallow(); wrapper.find(Button).simulate('click'); expect(mockDispatch).toHaveBeenCalledWith({ type: ActionType.OpenOLS }); }); diff --git a/frontend/packages/console-shared/src/components/editor/theme.ts b/frontend/packages/console-shared/src/components/editor/theme.ts index b0c41f490af..26743b8ffc9 100644 --- a/frontend/packages/console-shared/src/components/editor/theme.ts +++ b/frontend/packages/console-shared/src/components/editor/theme.ts @@ -1,33 +1,97 @@ -(window as any).monaco.editor.defineTheme('console-light', { - base: 'vs', - inherit: true, - colors: { - 'editor.background': '#fff', - 'editorGutter.background': '#f5f5f5', // black-150 - 'editorLineNumber.activeForeground': '#151515', - 'editorLineNumber.foreground': '#151515', - }, - rules: [ - { token: 'number', foreground: '486b00' }, // light-green-600 - { token: 'type', foreground: '795600' }, // gold-500 - { token: 'string', foreground: '004080' }, // blue-600 - { token: 'keyword', foreground: '40199a' }, // purple-600 - ], -}); - -(window as any).monaco.editor.defineTheme('console-dark', { - base: 'vs-dark', - inherit: true, - colors: { - 'editor.background': '#151515', - 'editorGutter.background': '#292e34', // no pf token defined - 'editorLineNumber.activeForeground': '#fff', - 'editorLineNumber.foreground': '#f0f0f0', - }, - rules: [ - { token: 'number', foreground: 'ace12e' }, // light-green-600 - { token: 'type', foreground: '73bcf7' }, // blue-200 - { token: 'string', foreground: 'f0ab00' }, // gold-400 - { token: 'keyword', foreground: 'cbc1ff' }, // purple-100 - ], -}); +import { useContext, useEffect, useState } from 'react'; +import { + t_color_green_70, + t_color_yellow_70, + t_color_blue_70, + t_color_purple_70, + t_color_green_30, + t_color_blue_30, + t_color_yellow_30, + t_color_purple_30, + t_color_white, + t_color_gray_20, + t_color_gray_60, + t_color_gray_90, + t_color_black, +} from '@patternfly/react-tokens'; +import type { editor as monacoEditor } from 'monaco-editor/esm/vs/editor/editor.api'; +import { ThemeContext } from '@console/internal/components/ThemeProvider'; + +/** + * Define the themes `console-light` and `console-dark` for an instance of Monaco editor. + */ +const defineThemes = (editor: typeof monacoEditor) => { + editor.defineTheme('console-light', { + base: 'vs', + inherit: true, + colors: { + 'editor.background': t_color_white.value, + 'editorLineNumber.activeForeground': t_color_black.value, + 'editorLineNumber.foreground': t_color_gray_60.value, + }, + rules: [ + { token: 'number', foreground: t_color_green_70.value }, + { token: 'type', foreground: t_color_yellow_70.value }, + { token: 'string', foreground: t_color_blue_70.value }, + { token: 'keyword', foreground: t_color_purple_70.value }, + ], + }); + + editor.defineTheme('console-dark', { + base: 'vs-dark', + inherit: true, + colors: { + 'editor.background': t_color_gray_90.value, + 'editorLineNumber.activeForeground': t_color_white.value, + 'editorLineNumber.foreground': t_color_gray_20.value, + }, + rules: [ + { token: 'number', foreground: t_color_green_30.value }, + { token: 'type', foreground: t_color_blue_30.value }, + { token: 'string', foreground: t_color_yellow_30.value }, + { token: 'keyword', foreground: t_color_purple_30.value }, + ], + }); +}; + +const useSystemTheme = () => { + const [theme, setTheme] = useState('light'); + + useEffect(() => { + const query = window.matchMedia('(prefers-color-scheme: dark)'); + const updateTheme = () => setTheme(query.matches ? 'dark' : 'light'); + + query.addEventListener('change', updateTheme); + updateTheme(); + + return () => query.removeEventListener('change', updateTheme); + }, []); + + return theme; +}; + +/** + * Sets the theme of a provided Monaco editor instance based on the current theme. + */ +export const useConsoleMonacoTheme = (editor: typeof monacoEditor | null) => { + const systemTheme = useSystemTheme(); + const theme = useContext(ThemeContext); + const [themeLoaded, setThemeLoaded] = useState(false); + + useEffect(() => { + if (editor) { + if (!themeLoaded) { + defineThemes(editor); + setThemeLoaded(true); + } + + if (theme === 'light') { + editor.setTheme('console-light'); + } else if (theme === 'dark') { + editor.setTheme('console-dark'); + } else if (theme === 'systemDefault') { + editor.setTheme(`console-${systemTheme}`); + } + } + }, [theme, editor, themeLoaded, systemTheme]); +}; diff --git a/frontend/packages/console-shared/src/components/editor/yaml-editor-utils.ts b/frontend/packages/console-shared/src/components/editor/yaml-editor-utils.ts index fdc7645e917..8705b4f7a38 100644 --- a/frontend/packages/console-shared/src/components/editor/yaml-editor-utils.ts +++ b/frontend/packages/console-shared/src/components/editor/yaml-editor-utils.ts @@ -1,131 +1,17 @@ -import * as URL from 'url'; -import { Uri, Range } from 'monaco-editor'; -import { - MonacoToProtocolConverter, - ProtocolToMonacoConverter, -} from 'monaco-languageclient/lib/monaco-converter'; +import { Range } from 'monaco-editor'; +import type * as monaco from 'monaco-editor/esm/vs/editor/editor.api'; +import { configureMonacoYaml } from 'monaco-yaml'; import * as yaml from 'yaml-ast-parser'; -import { getLanguageService, TextDocument } from 'yaml-language-server'; import { openAPItoJSONSchema } from '@console/internal/module/k8s/openapi-to-json-schema'; import { getSwaggerDefinitions } from '@console/internal/module/k8s/swagger'; -export const defaultEditorOptions = { readOnly: false, scrollBeyondLastLine: false }; - -const MODEL_URI = 'inmemory://model.yaml'; -const MONACO_URI = Uri.parse(MODEL_URI); - -const createDocument = (model) => { - return TextDocument.create( - MODEL_URI, - model?.getModeId(), - model?.getVersionId(), - model?.getValue(), - ); -}; - -// Unfortunately, `editor.focus()` doesn't work when hiding the shortcuts -// popover. We need to find the actual DOM element. -export const hackyFocusEditor = () => - setTimeout(() => document.querySelector('.monaco-editor textarea')?.focus()); - -export const registerYAMLLanguage = (monaco) => { - // register the YAML language with Monaco - monaco.languages.register({ - id: 'yaml', - extensions: ['.yml', '.yaml'], - aliases: ['YAML', 'yaml'], - mimetypes: ['application/yaml'], - }); -}; - -export const createYAMLService = () => { - const resolveSchema = (url: string): Promise => { - const promise = new Promise((resolve, reject) => { - const xhr = new XMLHttpRequest(); - xhr.onload = () => resolve(xhr.responseText); - xhr.onerror = () => reject(xhr.statusText); - xhr.open('GET', url, true); - xhr.send(); - }); - return promise as Promise; - }; - - const workspaceContext = { - resolveRelativePath: (relativePath, resource) => URL.resolve(resource, relativePath), - }; - - const yamlService = getLanguageService(resolveSchema, workspaceContext); - - // Prepare the schema - const yamlOpenAPI = getSwaggerDefinitions(); - - // Convert the openAPI schema to something the language server understands - const kubernetesJSONSchema = openAPItoJSONSchema(yamlOpenAPI); - - const schemas = [ - { - uri: 'inmemory:yaml', - fileMatch: ['*'], - schema: kubernetesJSONSchema, - }, - ]; - yamlService.configure({ - validate: true, - schemas, - hover: true, - completion: true, - }); - return yamlService; -}; - -export const registerYAMLCompletion = (languageID, monaco, m2p, p2m, yamlService) => { - monaco.languages.registerCompletionItemProvider(languageID, { - provideCompletionItems(model, position) { - const document = createDocument(model); - return yamlService - .doComplete(document, m2p.asPosition(position.lineNumber, position.column), true) - .then((list) => { - return p2m.asCompletionResult(list); - }); - }, - }); -}; - -export const registerYAMLDocumentSymbols = (languageID, monaco, p2m, yamlService) => { - monaco.languages.registerDocumentSymbolProvider(languageID, { - provideDocumentSymbols(model) { - const document = createDocument(model); - return p2m.asSymbolInformations(yamlService.findDocumentSymbols(document)); - }, - }); -}; - -export const registerYAMLHover = (languageID, monaco, m2p, p2m, yamlService) => { - monaco.languages.registerHoverProvider(languageID, { - provideHover(model, position) { - const doc = createDocument(model); - return yamlService - .doHover(doc, m2p.asPosition(position.lineNumber, position.column), true) - .then((hover) => { - return p2m.asHover(hover); - }) - .then((e) => { - for (const el of document.getElementsByClassName('monaco-editor-hover')) { - el.onclick = (event) => event.preventDefault(); - el.onauxclick = (event) => { - window.open(event.target.getAttribute('data-href'), '_blank').opener = null; - event.preventDefault(); - }; - } - return e; - }); - }, - }); +export const defaultEditorOptions: monaco.editor.IEditorOptions = { + scrollBeyondLastLine: false, }; -const findManagedMetadata = (model) => { - const document = createDocument(model); - const doc = yaml.safeLoad(document.getText()); +const findManagedMetadata = (model: monaco.editor.ITextModel) => { + const modelValue = model.getValue(); + const doc = yaml.safeLoad(modelValue); const rootMappings = doc?.mappings || []; for (const rootElement of rootMappings) { const rootKey = rootElement.key; @@ -139,8 +25,8 @@ const findManagedMetadata = (model) => { // Search for managedFields if (childKey.value === 'managedFields') { - const startLine = document.positionAt(metadataChildren.startPosition).line + 1; - const endLine = document.positionAt(metadataChildren.endPosition).line; + const startLine = model.getPositionAt(metadataChildren.startPosition).lineNumber; + const endLine = model.getPositionAt(metadataChildren.endPosition).lineNumber; return { start: startLine, end: endLine, @@ -155,7 +41,11 @@ const findManagedMetadata = (model) => { }; }; -export const fold = (editor, model, resetMouseLocation: boolean): void => { +export const fold = ( + editor: monaco.editor.IStandaloneCodeEditor, + model: monaco.editor.ITextModel, + resetMouseLocation: boolean, +): void => { const managedLocation = findManagedMetadata(model); const { start } = managedLocation; const { end } = managedLocation; @@ -176,49 +66,19 @@ export const fold = (editor, model, resetMouseLocation: boolean): void => { } }; -// TODO: These functions are not part of React Component LifeCycle, will need refactoring -export const enableYAMLValidation = ( - editor, - monaco, - p2m, - monacoURI, - yamlService, +/** + * Register automatic for managedFields folding in the editor + */ +export const registerAutoFold = ( + editor: monaco.editor.IStandaloneCodeEditor, alreadyInUse: boolean = false, ) => { - const pendingValidationRequests = new Map(); - - const getModel = () => monaco.editor?.getModels()[0]; - - const cleanPendingValidation = (document) => { - const request = pendingValidationRequests.get(document.uri); - if (request !== undefined) { - clearTimeout(request); - pendingValidationRequests.delete(document.uri); - } - }; - - const cleanDiagnostics = () => - monaco.editor.setModelMarkers(monaco.editor.getModel(monacoURI), 'default', []); - - const doValidate = (document) => { - if (document.getText().length === 0) { - cleanDiagnostics(); - return; - } - yamlService - .doValidation(document, true) - .then((diagnostics) => { - const markers = p2m.asDiagnostics(diagnostics); - monaco.editor.setModelMarkers(getModel(), 'default', markers); - }) - .catch(() => {}); - }; - let initialFoldingTriggered = false; + const model = editor.getModel(); const tryFolding = () => { - const document = createDocument(getModel()); - if (!initialFoldingTriggered && document.getText() !== '') { - setTimeout(() => fold(editor, getModel(), true)); + const document = model.getValue(); + if (!initialFoldingTriggered && document !== '') { + setTimeout(() => fold(editor, model, true)); initialFoldingTriggered = true; } }; @@ -226,50 +86,44 @@ export const enableYAMLValidation = ( tryFolding(); } - getModel()?.onDidChangeContent(() => { + model.onDidChangeContent(() => { tryFolding(); - - const document = createDocument(getModel()); - cleanPendingValidation(document); - pendingValidationRequests.set( - document.uri, - setTimeout(() => { - pendingValidationRequests.delete(document.uri); - doValidate(document); - }), - ); }); }; -export const registerYAMLinMonaco = (editor, monaco, alreadyInUse: boolean = false) => { - const LANGUAGE_ID = 'yaml'; - - const m2p = new MonacoToProtocolConverter(); - const p2m = new ProtocolToMonacoConverter(); - - const yamlService = createYAMLService(); - - // validation is not a 'registered' feature like the others, it relies on calling the yamlService - // directly for validation results when content in the editor has changed - enableYAMLValidation(editor, monaco, p2m, MONACO_URI, yamlService, alreadyInUse); - +export const registerYAMLinMonaco = (monacoInstance: typeof monaco) => { /** - * This exists because react-monaco-editor passes the same monaco - * object each time. Without it you would be registering all the features again and - * getting duplicate results. + * This exists because we enabled globalAPI in the webpack config. This means that the + * the monaco instance may have already been setup with the YAML language features. + * Otherwise, we might register all the features again, getting duplicate results. * - * Monaco does not provide any apis for unregistering or checking if the features have already + * Monaco does not provide any APIs for unregistering or checking if the features have already * been registered for a language. * - * We check that > 1 YAML language exists because one is the default and one is the initial register - * that setups our features. + * We check that > 1 YAML language exists because one is the default and + * the other is the language server that we register. */ - if (monaco.languages.getLanguages().filter((x) => x.id === LANGUAGE_ID).length > 1) { - return; + if (monacoInstance.languages.getLanguages().filter((x) => x.id === 'yaml').length <= 1) { + // Prepare the schema + const yamlOpenAPI = getSwaggerDefinitions(); + + // Convert the openAPI schema to something the language server understands + const kubernetesJSONSchema = openAPItoJSONSchema(yamlOpenAPI); + + const schemas = [ + { + uri: 'inmemory:yaml', + fileMatch: ['*'], + schema: kubernetesJSONSchema, + }, + ]; + + configureMonacoYaml(monacoInstance, { + isKubernetes: true, + validate: true, + schemas, + hover: true, + completion: true, + }); } - - registerYAMLLanguage(monaco); // register the YAML language with monaco - registerYAMLCompletion(LANGUAGE_ID, monaco, m2p, p2m, yamlService); - registerYAMLDocumentSymbols(LANGUAGE_ID, monaco, p2m, yamlService); - registerYAMLHover(LANGUAGE_ID, monaco, m2p, p2m, yamlService); }; diff --git a/frontend/packages/console-shared/src/components/formik-fields/CodeEditorField.scss b/frontend/packages/console-shared/src/components/formik-fields/CodeEditorField.scss index 82558c0d0de..9a305149228 100644 --- a/frontend/packages/console-shared/src/components/formik-fields/CodeEditorField.scss +++ b/frontend/packages/console-shared/src/components/formik-fields/CodeEditorField.scss @@ -2,35 +2,36 @@ @import '../../../../../public/style/vars'; .osc-yaml-editor { - display: flex; - flex: 1 0 auto; - flex-direction: row; margin-right: -$pf-v6-global-gutter; + margin-top: -$pf-v6-global-gutter--md; + @media (max-width: $pf-v6-global--breakpoint--md) { margin-left: -$pf-v6-global-gutter; - margin-top: -$pf-v6-global-gutter--md; } @media (min-width: $pf-v6-global--breakpoint--xl) { margin-right: -$pf-v6-global-gutter--md; } + .co-p-has-sidebar__body { + flex-direction: column; + display: flex; + } + &__editor { + position: relative; display: flex; - flex: 1 0 auto; + height: 100%; + flex-grow: 1; flex-direction: column; - @media (min-width: $pf-v6-global--breakpoint--md) { - margin-right: $pf-v6-global-gutter; - } - @media (min-width: $pf-v6-global--breakpoint--xl) { - margin-right: $pf-v6-global-gutter--md; + padding-top: $pf-v6-global-gutter; + width: 100%; + max-width: calc(100% - $pf-v6-global-gutter--md); + + @media (max-width: $pf-v6-global--breakpoint--md) { + max-width: 100%; } } &__sidebar { - display: flex; - width: 34%; margin-top: -$pf-v6-global-gutter--md; - @media screen and (max-width: $pf-v6-global--breakpoint--lg) { - display: none; - } } } diff --git a/frontend/packages/console-shared/src/components/formik-fields/CodeEditorField.tsx b/frontend/packages/console-shared/src/components/formik-fields/CodeEditorField.tsx index 7384d711aa7..99999e10a56 100644 --- a/frontend/packages/console-shared/src/components/formik-fields/CodeEditorField.tsx +++ b/frontend/packages/console-shared/src/components/formik-fields/CodeEditorField.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { Button } from '@patternfly/react-core'; import { InfoCircleIcon } from '@patternfly/react-icons/dist/esm/icons/info-circle-icon'; +import classNames from 'classnames'; import { FormikValues, useField, useFormikContext } from 'formik'; import { isEmpty } from 'lodash'; import { useTranslation } from 'react-i18next'; @@ -32,7 +33,7 @@ const CodeEditorField: React.FC = ({ schema, showSamples, showShortcuts, - showMiniMap, + isMinimapVisible, minHeight, onSave, language, @@ -80,49 +81,52 @@ const CodeEditorField: React.FC = ({ ); return ( -
-
- import('../editor/CodeEditor').then((c) => c.default)} - forwardRef={editorRef} - value={field.value} - minHeight={minHeight ?? '200px'} - onChange={(yaml: string) => setFieldValue(name, yaml)} - onSave={onSave} - showShortcuts={showShortcuts} - showMiniMap={showMiniMap} - language={language} - toolbarLinks={ - !sidebarOpen && - hasSidebarContent && [ - , - ] - } - /> -
- {sidebarOpen && hasSidebarContent && ( -
+
+
+
import('../editor/CodeEditorSidebar').then((c) => c.default)} - editorRef={editorRef} - model={model} - schema={schema} - samples={showSamples ? samples : []} - snippets={snippets} - sanitizeYamlContent={sanitizeYamlContent} - sidebarLabel={label} - toggleSidebar={() => setSidebarOpen(!sidebarOpen)} + loader={() => import('../editor/CodeEditor').then((c) => c.default)} + forwardRef={editorRef} + value={field.value} + minHeight={minHeight ?? '200px'} + onChange={(yaml: string) => setFieldValue(name, yaml)} + onSave={onSave} + showShortcuts={showShortcuts} + isMinimapVisible={isMinimapVisible} + language={language} + toolbarLinks={ + !sidebarOpen && + hasSidebarContent && [ + , + ] + } />
+
+ {sidebarOpen && hasSidebarContent && ( + import('../editor/CodeEditorSidebar').then((c) => c.default)} + editorRef={editorRef} + model={model} + schema={schema} + samples={showSamples ? samples : []} + snippets={snippets} + sanitizeYamlContent={sanitizeYamlContent} + sidebarLabel={label} + toggleSidebar={() => setSidebarOpen(!sidebarOpen)} + /> )}
); diff --git a/frontend/packages/console-shared/src/components/formik-fields/field-types.ts b/frontend/packages/console-shared/src/components/formik-fields/field-types.ts index 0d88f62b0fa..533109ac305 100644 --- a/frontend/packages/console-shared/src/components/formik-fields/field-types.ts +++ b/frontend/packages/console-shared/src/components/formik-fields/field-types.ts @@ -115,7 +115,7 @@ export interface CodeEditorFieldProps extends FieldProps { schema?: JSONSchema7; showSamples: boolean; showShortcuts?: boolean; - showMiniMap?: boolean; + isMinimapVisible?: boolean; onSave?: () => void; } diff --git a/frontend/packages/dev-console/integration-tests/support/pageObjects/add-flow-po.ts b/frontend/packages/dev-console/integration-tests/support/pageObjects/add-flow-po.ts index bd290d32f7e..ba425ac23ba 100644 --- a/frontend/packages/dev-console/integration-tests/support/pageObjects/add-flow-po.ts +++ b/frontend/packages/dev-console/integration-tests/support/pageObjects/add-flow-po.ts @@ -390,7 +390,7 @@ export const channelPO = { }; export const yamlPO = { - yamlEditor: '.react-monaco-editor-container', + yamlEditor: '.ocs-yaml-editor', }; export const uploadJarFilePO = { diff --git a/frontend/packages/dev-console/integration-tests/support/pages/app.ts b/frontend/packages/dev-console/integration-tests/support/pages/app.ts index bedc03e60f4..260fa04b9ba 100644 --- a/frontend/packages/dev-console/integration-tests/support/pages/app.ts +++ b/frontend/packages/dev-console/integration-tests/support/pages/app.ts @@ -394,6 +394,7 @@ export const yamlEditor = { isLoaded: () => { app.waitForLoad(); cy.get(yamlPO.yamlEditor).should('be.visible'); + cy.window().its('monaco.editor.getModels').should('exist'); }, clearYAMLEditor: () => { diff --git a/frontend/packages/dev-console/src/components/buildconfig/sections/EditorField.tsx b/frontend/packages/dev-console/src/components/buildconfig/sections/EditorField.tsx index 0d9081aa9d6..237d8e6ec0b 100644 --- a/frontend/packages/dev-console/src/components/buildconfig/sections/EditorField.tsx +++ b/frontend/packages/dev-console/src/components/buildconfig/sections/EditorField.tsx @@ -1,18 +1,17 @@ import * as React from 'react'; import { FormGroup, FormHelperText, HelperText, HelperTextItem } from '@patternfly/react-core'; import { FormikValues, useFormikContext } from 'formik'; -import MonacoEditor, { ChangeHandler, MonacoEditorProps } from 'react-monaco-editor'; -import { ThemeContext } from '@console/internal/components/ThemeProvider'; +import { BasicCodeEditorProps } from '@console/dynamic-plugin-sdk'; import { RedExclamationCircleIcon, useDebounceCallback } from '@console/shared/src'; -import '@console/shared/src/components/editor/theme'; +import { BasicCodeEditor } from '@console/shared/src/components/editor/BasicCodeEditor'; -type EditorFieldProps = { +type EditorFieldProps = Partial & { name: string; label?: React.ReactNode; helpText?: React.ReactNode; required?: boolean; isDisabled?: boolean; -} & MonacoEditorProps; +}; const EditorField: React.FC = ({ name, @@ -23,11 +22,10 @@ const EditorField: React.FC = ({ onChange, ...otherProps }) => { - const theme = React.useContext(ThemeContext); const { getFieldMeta, setFieldValue, setFieldTouched } = useFormikContext(); const { error, value } = getFieldMeta(name); - const debouncedOnChange = useDebounceCallback((newValue, event) => { + const debouncedOnChange = useDebounceCallback((newValue, event) => { if (onChange) { onChange(newValue, event); } @@ -37,11 +35,13 @@ const EditorField: React.FC = ({ return ( - diff --git a/frontend/packages/dev-console/src/components/buildconfig/sections/HooksSection.tsx b/frontend/packages/dev-console/src/components/buildconfig/sections/HooksSection.tsx index a69737bbf27..193e223d388 100644 --- a/frontend/packages/dev-console/src/components/buildconfig/sections/HooksSection.tsx +++ b/frontend/packages/dev-console/src/components/buildconfig/sections/HooksSection.tsx @@ -55,12 +55,8 @@ const HooksSection: React.FC<{}> = () => { diff --git a/frontend/packages/dev-console/src/components/buildconfig/sections/SourceSection.tsx b/frontend/packages/dev-console/src/components/buildconfig/sections/SourceSection.tsx index cf18e5ef3d8..b382e2fbe2c 100644 --- a/frontend/packages/dev-console/src/components/buildconfig/sections/SourceSection.tsx +++ b/frontend/packages/dev-console/src/components/buildconfig/sections/SourceSection.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { Language } from '@patternfly/react-code-editor'; import { useField } from 'formik'; import { useTranslation } from 'react-i18next'; import { DropdownField } from '@console/shared'; @@ -33,8 +34,6 @@ const SourceSection: React.FC = () => { }; const lineHeight = 18; - const showLines = 10; // Math.max(3, Math.min(15, dockerfile?.split('/n')?.length)); - const height = lineHeight * showLines; return ( @@ -55,13 +54,9 @@ const SourceSection: React.FC = () => { diff --git a/frontend/packages/integration-tests-cypress/views/yaml-editor.ts b/frontend/packages/integration-tests-cypress/views/yaml-editor.ts index 7323760fc80..bec2f7fe900 100644 --- a/frontend/packages/integration-tests-cypress/views/yaml-editor.ts +++ b/frontend/packages/integration-tests-cypress/views/yaml-editor.ts @@ -1,13 +1,23 @@ +import type { editor } from 'monaco-editor/esm/vs/editor/editor.api'; + export const getEditorContent = () => { - return cy.window().then((win: any) => { - return win.monaco.editor.getModels()[0].getValue(); - }); + return cy + .window() + .its('monaco.editor.getModels') + .should('be.a', 'function') + .then((getModels: typeof editor.getModels) => { + return getModels()[0].getValue(); + }); }; export const setEditorContent = (text: string) => { - return cy.window().then((win: any) => { - win.monaco.editor.getModels()[0].setValue(text); - }); + return cy + .window() + .its('monaco.editor.getModels') + .should('be.a', 'function') + .then((getModels: typeof editor.getModels) => { + return getModels()[0].setValue(text); + }); }; // initially yamlEditor loads with all grey text, finished loading when editor is color coded diff --git a/frontend/packages/knative-plugin/integration-tests/support/step-definitions/serverless/create-knative-service-from-deployment-or-deployment-config.ts b/frontend/packages/knative-plugin/integration-tests/support/step-definitions/serverless/create-knative-service-from-deployment-or-deployment-config.ts index 29f4be684c6..04f2f1d47ad 100644 --- a/frontend/packages/knative-plugin/integration-tests/support/step-definitions/serverless/create-knative-service-from-deployment-or-deployment-config.ts +++ b/frontend/packages/knative-plugin/integration-tests/support/step-definitions/serverless/create-knative-service-from-deployment-or-deployment-config.ts @@ -213,18 +213,14 @@ When( ); Then('user is able to see value of {string} as {string}', (util: string, utilValue: string) => { - cy.get('.ocs-yaml-editor__wrapper').contains(`${util}: '${utilValue}'`).should('be.visible'); + cy.get('.ocs-yaml-editor').contains(`${util}: '${utilValue}'`).should('be.visible'); }); Then( 'user is able to see the value of {string} and {string} as {string} and {string} percent respectively', (maxScale: string, minScale: string, minScaleValue: string, maxScaleValue: string) => { - cy.get('.ocs-yaml-editor__wrapper') - .contains(`${maxScale}: '${maxScaleValue}'`) - .should('be.visible'); + cy.get('.ocs-yaml-editor').contains(`${maxScale}: '${maxScaleValue}'`).should('be.visible'); - cy.get('.ocs-yaml-editor__wrapper') - .contains(`${minScale}: '${minScaleValue}'`) - .should('be.visible'); + cy.get('.ocs-yaml-editor').contains(`${minScale}: '${minScaleValue}'`).should('be.visible'); }, ); diff --git a/frontend/packages/knative-plugin/src/components/test-function/RequestPane.tsx b/frontend/packages/knative-plugin/src/components/test-function/RequestPane.tsx index 99bfafcac06..38cf30b8dfe 100644 --- a/frontend/packages/knative-plugin/src/components/test-function/RequestPane.tsx +++ b/frontend/packages/knative-plugin/src/components/test-function/RequestPane.tsx @@ -144,7 +144,7 @@ const RequestPane: React.FC> = ({ setFieldValue, value minHeight="34vh" showSamples={false} showShortcuts={false} - showMiniMap={false} + isMinimapVisible={false} language={getcurrentLanguage(contentType)} />
diff --git a/frontend/packages/knative-plugin/src/components/test-function/ResponsePane.tsx b/frontend/packages/knative-plugin/src/components/test-function/ResponsePane.tsx index 688a7bd1e1d..0a0bc9c7169 100644 --- a/frontend/packages/knative-plugin/src/components/test-function/ResponsePane.tsx +++ b/frontend/packages/knative-plugin/src/components/test-function/ResponsePane.tsx @@ -92,7 +92,7 @@ const ResponsePane: React.FC ) : ( diff --git a/frontend/packages/pipelines-plugin/integration-tests/support/page-objects/pipelines-po.ts b/frontend/packages/pipelines-plugin/integration-tests/support/page-objects/pipelines-po.ts index fcc77cf9441..f1c336b01e3 100644 --- a/frontend/packages/pipelines-plugin/integration-tests/support/page-objects/pipelines-po.ts +++ b/frontend/packages/pipelines-plugin/integration-tests/support/page-objects/pipelines-po.ts @@ -57,7 +57,7 @@ export const pipelineBuilderPO = { }, yamlView: { switchToYAMLView: '[id="form-radiobutton-editorType-yaml-field"]', - editor: 'div.react-monaco-editor-container', + editor: 'div.ocs-yaml-editor', yamlEditor: 'div.monaco-scrollable-element.editor-scrollable.vs-dark', sideBar: '[data-test="resource-sidebar"]', createButton: '[data-test-id="submit-button"]', diff --git a/frontend/public/components/_edit-yaml.scss b/frontend/public/components/_edit-yaml.scss index 5ef25402d7c..a1a5e3d91ac 100644 --- a/frontend/public/components/_edit-yaml.scss +++ b/frontend/public/components/_edit-yaml.scss @@ -4,39 +4,20 @@ height: 100%; flex: 1; flex-direction: column; - @media (min-width: $pf-v6-global--breakpoint--md) { - margin-left: $pf-v6-global-gutter; - margin-right: $pf-v6-global-gutter; - padding-top: $pf-v6-global-gutter--md; - } - @media (min-width: $pf-v6-global--breakpoint--xl) { - margin-left: $pf-v6-global-gutter--md; - margin-right: $pf-v6-global-gutter--md; - } -} + align-items: center; -.yaml-editor__buttons { - padding: var(--pf-t--global--spacer--md) $pf-v6-global-gutter; - @media (min-width: $pf-v6-global--breakpoint--md) { - padding-left: 0; - padding-right: 0; - } -} + .ocs-yaml-editor, .yaml-editor__buttons { + width: calc(100% - $pf-v6-global-gutter * 2); + padding-top: $pf-v6-global-gutter--md; -// only used in packages and will be orphaned when packages move out -.yaml-editor__header { - border-bottom: var(--pf-t--global--border--width--divider--default) solid - var(--pf-t--global--border--color--default); - padding: 20px $pf-v6-global-gutter; - @media (min-width: $pf-v6-global--breakpoint--xl) { - padding-left: $pf-v6-global-gutter--md; - padding-right: $pf-v6-global-gutter--md; + @media (min-width: $pf-v6-global--breakpoint--xl) { + width: calc(100% - $pf-v6-global-gutter--md * 2); + } } } -// only used in packages and will be orphaned when packages move out -.yaml-editor__header-text { - margin: 0; +.yaml-editor__buttons { + padding-bottom: $pf-v6-global-gutter; } .yaml-editor__link { diff --git a/frontend/public/components/edit-yaml.jsx b/frontend/public/components/edit-yaml.jsx index 9be97ad5d70..fed0dffe830 100644 --- a/frontend/public/components/edit-yaml.jsx +++ b/frontend/public/components/edit-yaml.jsx @@ -6,9 +6,8 @@ import { useDispatch, useSelector, connect } from 'react-redux'; import { action } from 'typesafe-actions'; import { ActionType, getOLSCodeBlock } from '@console/internal/reducers/ols'; import { safeLoad, safeLoadAll, safeDump } from 'js-yaml'; -import { ActionGroup, Alert, Button, Checkbox } from '@patternfly/react-core'; +import { ActionGroup, Alert, Button, Switch } from '@patternfly/react-core'; import { DownloadIcon } from '@patternfly/react-icons/dist/esm/icons/download-icon'; -import { InfoCircleIcon } from '@patternfly/react-icons/dist/esm/icons/info-circle-icon'; import { Trans, useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom-v5-compat'; import { @@ -25,7 +24,6 @@ import { import CodeEditor from '@console/shared/src/components/editor/CodeEditor'; import CodeEditorSidebar from '@console/shared/src/components/editor/CodeEditorSidebar'; -import '@console/shared/src/components/editor/theme'; import { fold } from '@console/shared/src/components/editor/yaml-editor-utils'; import { downloadYaml } from '@console/shared/src/components/editor/yaml-download-utils'; import { isYAMLTemplate, getImpersonate } from '@console/dynamic-plugin-sdk'; @@ -123,6 +121,7 @@ const EditYAMLInner = (props) => { const [notAllowed, setNotAllowed] = React.useState(); const [displayResults, setDisplayResults] = React.useState(); const [resourceObjects, setResourceObjects] = React.useState(); + const [editorMounted, setEditorMounted] = React.useState(false); const [callbackCommand, setCallbackCommand] = React.useState(''); const [showReplaceCodeModal, setShowReplaceCodeModal] = React.useState(false); @@ -143,6 +142,7 @@ const EditYAMLInner = (props) => { const displayedVersion = React.useRef('0'); const onCancel = 'onCancel' in props ? props.onCancel : navigateBack; + /** @return {import('monaco-editor').editor.IStandaloneCodeEditor | null} */ const getEditor = () => { return monacoRef.current?.editor; }; @@ -207,16 +207,14 @@ const EditYAMLInner = (props) => { .then((resp) => { const notAll = !resp.status.allowed; setNotAllowed(notAll); - if (monacoRef.current) { - monacoRef.current.editor?.updateOptions({ readOnly: notAll }); - } + editorMounted && getEditor()?.updateOptions({ readOnly: notAll }); }) .catch((e) => { // eslint-disable-next-line no-console console.warn('Error while check edit access', e); }); }, - [props.readOnly, props.impersonate, create, getModel], + [props.readOnly, props.impersonate, create, getModel, editorMounted], ); const appendYAMLString = React.useCallback((yaml) => { @@ -267,11 +265,11 @@ const EditYAMLInner = (props) => { const yaml = convertObjToYAMLString(obj); displayedVersion.current = _.get(obj, 'metadata.resourceVersion'); - getEditor()?.setValue(yaml); + editorMounted && getEditor()?.setValue(yaml); setInitialized(true); setStale(false); }, - [convertObjToYAMLString, initialized, props.obj], + [convertObjToYAMLString, initialized, props.obj, editorMounted], ); const handleCodeReplace = (_event) => { @@ -304,7 +302,7 @@ const EditYAMLInner = (props) => { return; } - const currentYAML = getEditor()?.getValue(); + const currentYAML = editorMounted && getEditor()?.getValue(); if (_.isEmpty(currentYAML) || currentYAML === olsCode) { getEditor()?.setValue(olsCodeBlock?.value); @@ -318,7 +316,7 @@ const EditYAMLInner = (props) => { setOLSCode(olsCodeBlock?.value); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [olsCodeBlock, initialized, isCodeImportRedirect]); + }, [olsCodeBlock, initialized, isCodeImportRedirect, editorMounted]); const handleError = (err, value = null) => { setSuccess(value); @@ -360,9 +358,9 @@ const EditYAMLInner = (props) => { if (props.error) { handleError(props.error); } - loadYaml(); + editorMounted && loadYaml(); loadCSVs(); - }, [loadCSVs, loadYaml, props.error]); + }, [loadCSVs, loadYaml, props.error, editorMounted]); const prevProps = React.useRef(props); @@ -373,17 +371,18 @@ const EditYAMLInner = (props) => { } const newVersion = _.get(props.obj, 'metadata.resourceVersion'); - const s = displayedVersion.current !== newVersion; + const s = displayedVersion.current !== newVersion && editorMounted; setStale(s); handleError(props.error, success); if (props.sampleObj) { - loadYaml(!_.isEqual(sampleObj, props.sampleObj), props.sampleObj); + editorMounted && loadYaml(!_.isEqual(sampleObj, props.sampleObj), props.sampleObj); } else if (props.fileUpload) { - loadYaml(!_.isEqual(prevProps.current.fileUpload, props.fileUpload), props.fileUpload); + editorMounted && + loadYaml(!_.isEqual(prevProps.current.fileUpload, props.fileUpload), props.fileUpload); } else { - loadYaml(); + editorMounted && loadYaml(); } - }, [props, isOver, loadYaml, sampleObj, success]); + }, [props, isOver, loadYaml, sampleObj, success, editorMounted]); const reload = () => { loadYaml(true); @@ -506,12 +505,12 @@ const EditYAMLInner = (props) => { let obj; if (onSave) { - onSave(getEditor().getValue()); + onSave(editorMounted && getEditor()?.getValue()); return; } try { - obj = safeLoad(getEditor().getValue()); + obj = safeLoad(editorMounted && getEditor()?.getValue()); } catch (e) { handleError(t('public~Error parsing YAML: {{e}}', { e })); return; @@ -580,7 +579,7 @@ const EditYAMLInner = (props) => { } } updateYAML(obj); - }, [create, owner, t, updateYAML, validate, onSave, props.obj]); + }, [create, owner, t, updateYAML, validate, onSave, props.obj, editorMounted]); const save = () => { setErrors([]); @@ -593,7 +592,7 @@ const EditYAMLInner = (props) => { let hasErrors = false; try { - objs = safeLoadAll(getEditor().getValue()).filter((obj) => obj); + objs = safeLoadAll(editorMounted && getEditor()?.getValue()).filter((obj) => obj); } catch (e) { handleError(t('public~Error parsing YAML: {{e}}', { e })); return; @@ -645,7 +644,7 @@ const EditYAMLInner = (props) => { setResourceObjects(objs); setDisplay(true); } - }, [t, setDisplay, validate]); + }, [t, setDisplay, validate, editorMounted]); const saveAll = () => { setErrors([]); @@ -708,6 +707,10 @@ const EditYAMLInner = (props) => { return sanitizedYaml; }; + React.useEffect(() => { + editorMounted && getEditor()?.updateOptions({ hover: { enabled: showTooltips } }); + }, [showTooltips, editorMounted]); + if (!create && !props.obj) { return ; } @@ -716,8 +719,6 @@ const EditYAMLInner = (props) => { 'co-file-dropzone--drop-over': isOver, }); - monacoRef.current?.editor?.updateOptions({ hover: showTooltips }); - if (displayResults) { return ( { const definition = model ? definitionFor(model) : { properties: [] }; const showSchema = definition && !_.isEmpty(definition.properties); const hasSidebarContent = showSchema || (create && !_.isEmpty(samples)) || !_.isEmpty(snippets); - const sidebarLink = - !showSidebar && hasSidebarContent ? ( - - ) : null; - const tooltipCheckBox = ( - + ); + + const tooltipSwitch = ( + ); @@ -791,17 +792,21 @@ const EditYAMLInner = (props) => {
-
+
{showReplaceCodeModal && } (allowMultiple ? saveAll() : save())} + onEditorDidMount={() => setEditorMounted(true)} />
{customAlerts} diff --git a/frontend/public/components/sidebars/resource-sidebar-samples.tsx b/frontend/public/components/sidebars/resource-sidebar-samples.tsx index 77aa398ae76..4acaa2b00de 100644 --- a/frontend/public/components/sidebars/resource-sidebar-samples.tsx +++ b/frontend/public/components/sidebars/resource-sidebar-samples.tsx @@ -1,8 +1,8 @@ import * as _ from 'lodash-es'; import * as React from 'react'; import { Button, Level, LevelItem, Title } from '@patternfly/react-core'; -import MonacoEditor from 'react-monaco-editor'; -import { ThemeContext } from '@console/internal/components/ThemeProvider'; +import { Language } from '@patternfly/react-code-editor'; +import { BasicCodeEditor } from '@console/shared/src/components/editor/BasicCodeEditor'; import { ChevronDownIcon } from '@patternfly/react-icons/dist/esm/icons/chevron-down-icon'; import { ChevronRightIcon } from '@patternfly/react-icons/dist/esm/icons/chevron-right-icon'; import { DownloadIcon } from '@patternfly/react-icons/dist/esm/icons/download-icon'; @@ -60,15 +60,12 @@ const ResourceSidebarSample: React.FC = ({ const lineHeight = 18; const PreviewYAML = ({ maxPreviewLines = 20, yaml }) => { - const theme = React.useContext(ThemeContext); - return (
- --- to separate each definition.": "Drag and drop YAML or JSON files into the editor, or manually enter files and use <2>--- to separate each definition.", "Create by manually entering YAML or JSON definitions, or by dragging and dropping a file into the editor.": "Create by manually entering YAML or JSON definitions, or by dragging and dropping a file into the editor.", diff --git a/frontend/public/style/_layout.scss b/frontend/public/style/_layout.scss index 868e0262a93..6e442c053d0 100644 --- a/frontend/public/style/_layout.scss +++ b/frontend/public/style/_layout.scss @@ -34,6 +34,13 @@ body, &__body { flex: 2; + max-width: 100%; + + @media (min-width: $screen-md-min) { + &--sidebar-open { + max-width: 66%; + } + } } &__close-button { @@ -47,6 +54,7 @@ body, @media (min-width: $screen-md-min) { flex: 1 0 auto; overflow-y: auto; + max-width: 34%; } &--bordered { diff --git a/frontend/scripts/check-patternfly-modules.sh b/frontend/scripts/check-patternfly-modules.sh index 07da7e420cf..ba6bf1b8090 100755 --- a/frontend/scripts/check-patternfly-modules.sh +++ b/frontend/scripts/check-patternfly-modules.sh @@ -50,6 +50,7 @@ PKGS_TO_CHECK=( '@patternfly/quickstarts:6' '@patternfly/react-catalog-view-extension:6' '@patternfly/react-charts:8' + '@patternfly/react-code-editor:6' '@patternfly/react-component-groups:6' '@patternfly/react-console:6' '@patternfly/react-core:6' diff --git a/frontend/webpack.config.ts b/frontend/webpack.config.ts index 5f22496e5b6..67c46935cbe 100644 --- a/frontend/webpack.config.ts +++ b/frontend/webpack.config.ts @@ -61,11 +61,7 @@ const sharedPluginModulesTest = getVendorModuleRegExp( const config: Configuration = { entry: { - main: [ - './public/components/app.jsx', - 'monaco-editor/esm/vs/editor/editor.worker.js', - '/node_modules/@patternfly-5/patternfly/patternfly.scss', - ], + main: ['./public/components/app.jsx', '/node_modules/@patternfly-5/patternfly/patternfly.scss'], }, cache: { type: 'filesystem', @@ -95,9 +91,6 @@ const config: Configuration = { prettier: false, 'prettier/parser-yaml': false, }, - fallback: { - net: false, // for YAML language server - }, }, node: { global: true, // see https://github.com/browserify/randombytes/issues/36 @@ -145,14 +138,6 @@ const config: Configuration = { }, ], }, - { - test: /node_modules[\\\\|/](yaml-language-server)/, - loader: 'umd-compat-loader', - }, - { - test: /node_modules[\\\\|/](vscode-json-languageservice)/, - loader: 'umd-compat-loader', - }, { test: /\.s?css$/, exclude: /node_modules\/(?!(@patternfly(-\S+)?|@console\/plugin-shared)\/).*/, @@ -264,6 +249,16 @@ const config: Configuration = { new MonacoWebpackPlugin({ languages: ['yaml', 'dockerfile', 'json', 'plaintext'], globalAPI: true, + customLanguages: [ + { + label: 'yaml', + entry: 'monaco-yaml', + worker: { + id: 'monaco-yaml/yamlWorker', + entry: 'monaco-yaml/yaml.worker', + }, + }, + ], }), new NodePolyfillPlugin({ additionalAliases: ['process'], diff --git a/frontend/yarn.lock b/frontend/yarn.lock index c0473927040..13d7435b70c 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -1747,6 +1747,20 @@ resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz#c3ec604a0b54b9a9b87e9735dfc59e1a5da6a5fb" integrity sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug== +"@monaco-editor/loader@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@monaco-editor/loader/-/loader-1.4.0.tgz#f08227057331ec890fa1e903912a5b711a2ad558" + integrity sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg== + dependencies: + state-local "^1.0.6" + +"@monaco-editor/react@^4.6.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@monaco-editor/react/-/react-4.6.0.tgz#bcc68671e358a21c3814566b865a54b191e24119" + integrity sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw== + dependencies: + "@monaco-editor/loader" "^1.4.0" + "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" @@ -1866,6 +1880,18 @@ lodash "^4.17.21" tslib "^2.8.1" +"@patternfly/react-code-editor@^6.2.0-prerelease.21": + version "6.2.0-prerelease.21" + resolved "https://registry.yarnpkg.com/@patternfly/react-code-editor/-/react-code-editor-6.2.0-prerelease.21.tgz#384905b036309480e216608f4ebdf4bbcb40652b" + integrity sha512-fWY7i7AMD8UnzOrOToUDR6cpxKmPR26LLhNFoHmOraSw/KvsF5f3NxAeta4ymJADEppPQwyBK126IR07OXk1+w== + dependencies: + "@monaco-editor/react" "^4.6.0" + "@patternfly/react-core" "^6.2.0-prerelease.19" + "@patternfly/react-icons" "^6.2.0-prerelease.3" + "@patternfly/react-styles" "^6.2.0-prerelease.3" + react-dropzone "14.3.5" + tslib "^2.8.1" + "@patternfly/react-component-groups@^6.2.0-prerelease.4": version "6.2.0-prerelease.4" resolved "https://registry.yarnpkg.com/@patternfly/react-component-groups/-/react-component-groups-6.2.0-prerelease.4.tgz#235fc34a40a05aba9b13007e18e523de5f0847ca" @@ -1891,7 +1917,7 @@ xterm "^5.1.0" xterm-addon-fit "^0.8.0" -"@patternfly/react-core@^6.0.0", "@patternfly/react-core@^6.0.0-prerelease.21", "@patternfly/react-core@^6.2.0-prerelease.15": +"@patternfly/react-core@^6.0.0", "@patternfly/react-core@^6.0.0-prerelease.21", "@patternfly/react-core@^6.2.0-prerelease.15", "@patternfly/react-core@^6.2.0-prerelease.19": version "6.2.0-prerelease.15" resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-6.2.0-prerelease.15.tgz#8f576605763e3410a411ca2681ddb7d66c47970d" integrity sha512-h8TdGxcX5Bkxb6c5cdP8Z0FEAeVcu4PO+dPncq2SXdMmFPvwUJfeklVGC8v81fclPPVtlijStFSM5aC5n1XjHQ== @@ -1903,7 +1929,7 @@ react-dropzone "^14.3.5" tslib "^2.8.1" -"@patternfly/react-icons@^6.0.0", "@patternfly/react-icons@^6.0.0-prerelease.7", "@patternfly/react-icons@^6.2.0-prerelease.2": +"@patternfly/react-icons@^6.0.0", "@patternfly/react-icons@^6.0.0-prerelease.7", "@patternfly/react-icons@^6.2.0-prerelease.2", "@patternfly/react-icons@^6.2.0-prerelease.3": version "6.2.0-prerelease.2" resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-6.2.0-prerelease.2.tgz#b695a12733d90004d243b37458bfe52947317d8e" integrity sha512-3ymG24ICMAvMqrDPzU8ycPcsHht4RfHjQil3ox43wwHI+nLrpywAgE9z6GtAzwtdm+DVZHBT1CWLWuAgdofX8w== @@ -1918,7 +1944,7 @@ "@patternfly/react-styles" "^6.0.0" memoize-one "^5.1.0" -"@patternfly/react-styles@^6.0.0", "@patternfly/react-styles@^6.0.0-prerelease.6", "@patternfly/react-styles@^6.2.0-prerelease.2": +"@patternfly/react-styles@^6.0.0", "@patternfly/react-styles@^6.0.0-prerelease.6", "@patternfly/react-styles@^6.2.0-prerelease.2", "@patternfly/react-styles@^6.2.0-prerelease.3": version "6.2.0-prerelease.2" resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-6.2.0-prerelease.2.tgz#32935b2e8d3bfb8aa4287e06a9aa3d4fbd550eea" integrity sha512-1YJH8Ozu05AHCBNGRZyNA5X1HxNGXuYTQvcR8FbVaNGuuWtvZxzb2EovN9xYVBu2joh+/LCLhiTAXI4eNKw3Ag== @@ -3950,16 +3976,6 @@ ast-types-flow@0.0.7, ast-types-flow@^0.0.7: resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= -ast-types@0.9.6: - version "0.9.6" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9" - integrity sha1-ECyenpAF0+fjgpvwxPok7oYu6bk= - -ast-types@^0.9.2: - version "0.9.14" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.14.tgz#d34ba5dffb9d15a44351fd2a9d82e4ab2838b5ba" - integrity sha512-Ebvx7/0lLboCdyEmAw/4GqwBeKIijPveXNiVGhCGCNxc7z26T5he7DC6ARxu8ByKuzUZZcLog+VP8GMyZrBzJw== - astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -7881,7 +7897,7 @@ espree@^6.1.2: acorn-jsx "^5.1.0" eslint-visitor-keys "^1.1.0" -esprima@^3.1.3, esprima@~3.1.0: +esprima@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= @@ -9000,11 +9016,6 @@ glob-stream@^8.0.0: normalize-path "^3.0.0" streamx "^2.12.5" -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" - integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= - glob-to-regexp@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" @@ -9634,7 +9645,7 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -https-proxy-agent@^2.2.1, https-proxy-agent@^2.2.3: +https-proxy-agent@^2.2.1: version "2.2.4" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== @@ -11135,11 +11146,16 @@ json5@^2.1.0, json5@^2.1.2, json5@^2.2.3: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jsonc-parser@^2.2.1, jsonc-parser@^2.3.1: +jsonc-parser@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.3.1.tgz#59549150b133f2efacca48fe9ce1ec0659af2342" integrity sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg== +jsonc-parser@^3.0.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.3.1.tgz#f2a524b4f7fd11e3d791e559977ad60b98b798b4" + integrity sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ== + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -11609,7 +11625,7 @@ loader-runner@^4.2.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== -loader-utils@^1.0.3, loader-utils@^1.1.0, loader-utils@^1.4.0: +loader-utils@^1.1.0, loader-utils@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== @@ -11627,7 +11643,7 @@ loader-utils@^2.0.0: emojis-list "^3.0.0" json5 "^2.1.2" -loader-utils@^2.0.4: +loader-utils@^2.0.2, loader-utils@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== @@ -12366,27 +12382,60 @@ module-deps@^6.0.0, module-deps@^6.2.3: through2 "^2.0.0" xtend "^4.0.0" -monaco-editor-webpack-plugin@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-4.2.0.tgz#2be76cde9cca7bd8c3418503625990f86886927b" - integrity sha512-/P3sFiEgBl+Y50he4mbknMhbLJVop5gBUZiPS86SuHUDOOnQiQ5rL1jU5lwt1XKAwMEkhwZbUwqaHxTPkb1Utw== +monaco-editor-webpack-plugin@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-7.1.0.tgz#16f265c2b5dbb5fe08681b6b3b7d00d3c5b2ee97" + integrity sha512-ZjnGINHN963JQkFqjjcBtn1XBtUATDZBMgNQhDQwd78w2ukRhFXAPNgWuacaQiDZsUr4h1rWv5Mv6eriKuOSzA== dependencies: - loader-utils "^2.0.0" + loader-utils "^2.0.2" -monaco-editor@^0.28.1: - version "0.28.1" - resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.28.1.tgz#732788ff2172d59e6d436b206da8cac715413940" - integrity sha512-P1vPqxB4B1ZFzTeR1ScggSp9/5NoQrLCq88fnlNUsuRAP1usEBN4TIpI2lw0AYIZNVIanHk0qwjze2uJwGOHUw== +monaco-editor@^0.51.0: + version "0.51.0" + resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.51.0.tgz#922a6103f6742b5a62fbb097276c5a6619d879db" + integrity sha512-xaGwVV1fq343cM7aOYB6lVE4Ugf0UyimdD/x5PWcWBMKENwectaEu77FAN7c5sFiyumqeJdX1RPTh1ocioyDjw== -monaco-languageclient@^0.13.0: - version "0.13.0" - resolved "https://registry.yarnpkg.com/monaco-languageclient/-/monaco-languageclient-0.13.0.tgz#59b68b42fb7633171502d6557f597c2752f6c266" - integrity sha512-aCwd33dTitwV5QwY56rpYHwzEGXei8TZ+yvZcvP3gEMd6Mizr8m3pOuoknDi2SUfLuNAHS6+ulvLgZlNQB5awg== +monaco-languageserver-types@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/monaco-languageserver-types/-/monaco-languageserver-types-0.4.0.tgz#8f3414c1ebba786b9c9db45857cc853e50e768e8" + integrity sha512-QQ3BZiU5LYkJElGncSNb5AKoJ/LCs6YBMCJMAz9EA7v+JaOdn3kx2cXpPTcZfKA5AEsR0vc97sAw+5mdNhVBmw== dependencies: - glob-to-regexp "^0.3.0" - vscode-jsonrpc "^5.0.0" - vscode-languageclient "^6.0.0" - vscode-uri "^2.1.1" + monaco-types "^0.1.0" + vscode-languageserver-protocol "^3.0.0" + vscode-uri "^3.0.0" + +monaco-marker-data-provider@^1.0.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/monaco-marker-data-provider/-/monaco-marker-data-provider-1.2.4.tgz#56fbeede5bd830ec2ee15b2aea9a7df62fa447a7" + integrity sha512-4DsPgsAqpTyUDs3humXRBPUJoihTv+L6v9aupQWD80X2YXaCXUd11mWYeSCYHuPgdUmjFaNWCEOjQ6ewf/QA1Q== + dependencies: + monaco-types "^0.1.0" + +monaco-types@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/monaco-types/-/monaco-types-0.1.0.tgz#3a3066aba499cb5923cd60efc736f3f14a169e10" + integrity sha512-aWK7SN9hAqNYi0WosPoMjenMeXJjwCxDibOqWffyQ/qXdzB/86xshGQobRferfmNz7BSNQ8GB0MD0oby9/5fTQ== + +monaco-worker-manager@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/monaco-worker-manager/-/monaco-worker-manager-2.0.1.tgz#f67c54dfca34ed4b225d5de84e77b24b4e36de8a" + integrity sha512-kdPL0yvg5qjhKPNVjJoym331PY/5JC11aPJXtCZNwWRvBr6jhkIamvYAyiY5P1AWFmNOy0aRDRoMdZfa71h8kg== + +monaco-yaml@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/monaco-yaml/-/monaco-yaml-5.3.1.tgz#e37749ff8491924a7cabf9f597e746036cc6a9ea" + integrity sha512-1MN8i1Tnc8d8RugQGqv5jp+Ce2xtNhrnbm0ZZbe5ceExj9C2PkKZfHJhY9kbdUS4G7xSVwKlVdMTmLlStepOtw== + dependencies: + jsonc-parser "^3.0.0" + monaco-languageserver-types "^0.4.0" + monaco-marker-data-provider "^1.0.0" + monaco-types "^0.1.0" + monaco-worker-manager "^2.0.0" + path-browserify "^1.0.0" + prettier "^3.0.0" + vscode-languageserver-textdocument "^1.0.0" + vscode-languageserver-types "^3.0.0" + vscode-uri "^3.0.0" + yaml "^2.0.0" moo@^0.5.0: version "0.5.2" @@ -13277,7 +13326,7 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -path-browserify@^1.0.1: +path-browserify@^1.0.0, path-browserify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== @@ -13591,6 +13640,11 @@ prettier@^2.6.2: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +prettier@^3.0.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.5.0.tgz#50325a28887c6dfdf2ca3f8eaba02b66a8429ca7" + integrity sha512-quyMrVt6svPS7CjQ9gKb3GLEX/rl3BCL2oa/QkNcXv4YNVBC9olt3s+H7ukto06q7B1Qz46PbrKLO34PR6vXcA== + pretty-bytes@^5.6.0: version "5.6.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" @@ -13660,7 +13714,7 @@ prisma-yml@1.34.10: scuid "^1.0.2" yaml-ast-parser "^0.0.40" -private@^0.1.7, private@~0.1.5: +private@^0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -14014,7 +14068,7 @@ react-draggable@4.x: classnames "^2.2.5" prop-types "^15.6.0" -react-dropzone@^14.3.5: +react-dropzone@14.3.5, react-dropzone@^14.3.5: version "14.3.5" resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-14.3.5.tgz#1a8bd312c8a353ec78ef402842ccb3589c225add" integrity sha512-9nDUaEEpqZLOz5v5SUcFA0CjM4vq8YbqO0WRls+EYT7+DvxUdzDPKNCPLqGfj3YL9MsniCLCD4RFA6M95V6KMQ== @@ -14121,13 +14175,6 @@ react-modal@^3.12.1: react-lifecycles-compat "^3.0.0" warning "^4.0.3" -react-monaco-editor@0.46.x: - version "0.46.0" - resolved "https://registry.yarnpkg.com/react-monaco-editor/-/react-monaco-editor-0.46.0.tgz#ac97d5429cd8821d466f0e8e0536ea2a90bbc6d0" - integrity sha512-/GyQ0tQLbjHAuMUNRfKecBYN68o8TwA4fnwH9P+lHbF80ayMAo0PQ60joTQH6R6j839kMn6o9Kk/cbzOxK5DzA== - dependencies: - prop-types "^15.7.2" - react-redux@7.2.9: version "7.2.9" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.9.tgz#09488fbb9416a4efe3735b7235055442b042481d" @@ -14389,16 +14436,6 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -recast@^0.11.17: - version "0.11.23" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3" - integrity sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM= - dependencies: - ast-types "0.9.6" - esprima "~3.1.0" - private "~0.1.5" - source-map "~0.5.0" - rechoir@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" @@ -14631,15 +14668,6 @@ replaceall@^0.1.6: resolved "https://registry.yarnpkg.com/replaceall/-/replaceall-0.1.6.tgz#81d81ac7aeb72d7f5c4942adf2697a3220688d8e" integrity sha1-gdgax663LX9cSUKt8ml6MiBojY4= -request-light@^0.2.4: - version "0.2.5" - resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.5.tgz#38a3da7b2e56f7af8cbba57e8a94930ee2380746" - integrity sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw== - dependencies: - http-proxy-agent "^2.1.0" - https-proxy-agent "^2.2.3" - vscode-nls "^4.1.1" - request-progress@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe" @@ -15515,7 +15543,7 @@ source-map@^0.4.4: dependencies: amdefine ">=0.0.4" -source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.0, source-map@~0.5.1, source-map@~0.5.3: +source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1, source-map@~0.5.3: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= @@ -15655,6 +15683,11 @@ stacktrace-js@^2.0.0: stack-generator "^2.0.5" stacktrace-gps "^3.0.4" +state-local@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/state-local/-/state-local-1.0.7.tgz#da50211d07f05748d53009bee46307a37db386d5" + integrity sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w== + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -16612,15 +16645,6 @@ uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" -umd-compat-loader@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/umd-compat-loader/-/umd-compat-loader-2.1.2.tgz#abf89be1591940a236cf8fa87f88d6d6f5a8da35" - integrity sha512-RkTlsfrCxUISWqiTtYFFJank7b2Hhl4V2pc29nl0xOEGvvuVkpy1xnufhXfTituxgpW0HSrDk0JHlvPYZxEXKQ== - dependencies: - ast-types "^0.9.2" - loader-utils "^1.0.3" - recast "^0.11.17" - umd@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/umd/-/umd-3.0.3.tgz#aa9fe653c42b9097678489c01000acb69f0b26cf" @@ -17356,7 +17380,7 @@ void-elements@3.1.0: resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w== -vscode-json-languageservice@^3.10.0, vscode-json-languageservice@^3.3.5: +vscode-json-languageservice@^3.3.5: version "3.10.0" resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.10.0.tgz#19eed884fd0f234f8ed2fa0a96e772f293ccc5c4" integrity sha512-8IvuRSQnjznu+obqy6Dy4S4H68Ke7a3Kb+A0FcdctyAMAWEnrORpCpMOMqEYiPLm/OTYLVWJ7ql3qToDTozu4w== @@ -17367,88 +17391,54 @@ vscode-json-languageservice@^3.10.0, vscode-json-languageservice@^3.3.5: vscode-nls "^5.0.0" vscode-uri "^2.1.2" -vscode-jsonrpc@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz#a7bf74ef3254d0a0c272fab15c82128e378b3be9" - integrity sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg== - -vscode-jsonrpc@^5.0.0, vscode-jsonrpc@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz#9bab9c330d89f43fc8c1e8702b5c36e058a01794" - integrity sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A== - -vscode-languageclient@^6.0.0: - version "6.1.3" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-6.1.3.tgz#c979c5bb5855714a0307e998c18ca827c1b3953a" - integrity sha512-YciJxk08iU5LmWu7j5dUt9/1OLjokKET6rME3cI4BRpiF6HZlusm2ZwPt0MYJ0lV5y43sZsQHhyon2xBg4ZJVA== - dependencies: - semver "^6.3.0" - vscode-languageserver-protocol "^3.15.3" +vscode-jsonrpc@8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz#f43dfa35fb51e763d17cd94dcca0c9458f35abf9" + integrity sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA== -vscode-languageserver-protocol@3.14.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz#b8aab6afae2849c84a8983d39a1cf742417afe2f" - integrity sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g== +vscode-languageserver-protocol@^3.0.0: + version "3.17.5" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz#864a8b8f390835572f4e13bd9f8313d0e3ac4bea" + integrity sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg== dependencies: - vscode-jsonrpc "^4.0.0" - vscode-languageserver-types "3.14.0" + vscode-jsonrpc "8.2.0" + vscode-languageserver-types "3.17.5" -vscode-languageserver-protocol@^3.15.3: - version "3.15.3" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.3.tgz#3fa9a0702d742cf7883cb6182a6212fcd0a1d8bb" - integrity sha512-zrMuwHOAQRhjDSnflWdJG+O2ztMWss8GqUUB8dXLR/FPenwkiBNkMIJJYfSN6sgskvsF0rHAoBowNQfbyZnnvw== - dependencies: - vscode-jsonrpc "^5.0.1" - vscode-languageserver-types "3.15.1" +vscode-languageserver-textdocument@^1.0.0: + version "1.0.12" + resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz#457ee04271ab38998a093c68c2342f53f6e4a631" + integrity sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA== vscode-languageserver-textdocument@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz#178168e87efad6171b372add1dea34f53e5d330f" integrity sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA== -vscode-languageserver-types@3.14.0: - version "3.14.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743" - integrity sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A== - -vscode-languageserver-types@3.15.1, vscode-languageserver-types@^3.10.0, vscode-languageserver-types@^3.15.1: - version "3.15.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz#17be71d78d2f6236d414f0001ce1ef4d23e6b6de" - integrity sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ== - vscode-languageserver-types@3.16.0-next.2: version "3.16.0-next.2" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0-next.2.tgz#940bd15c992295a65eae8ab6b8568a1e8daa3083" integrity sha512-QjXB7CKIfFzKbiCJC4OWC8xUncLsxo19FzGVp/ADFvvi87PlmBSCAtZI5xwGjF5qE0xkLf0jjKUn3DzmpDP52Q== -vscode-languageserver@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz#0d2feddd33f92aadf5da32450df498d52f6f14eb" - integrity sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A== - dependencies: - vscode-languageserver-protocol "3.14.1" - vscode-uri "^1.0.6" - -vscode-nls@^4.1.1, vscode-nls@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.2.tgz#ca8bf8bb82a0987b32801f9fddfdd2fb9fd3c167" - integrity sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw== +vscode-languageserver-types@3.17.5, vscode-languageserver-types@^3.0.0: + version "3.17.5" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz#3273676f0cf2eab40b3f44d085acbb7f08a39d8a" + integrity sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg== vscode-nls@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.0.tgz#99f0da0bd9ea7cda44e565a74c54b1f2bc257840" integrity sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA== -vscode-uri@^1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.8.tgz#9769aaececae4026fb6e22359cb38946580ded59" - integrity sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ== - -vscode-uri@^2.1.1, vscode-uri@^2.1.2: +vscode-uri@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.2.tgz#c8d40de93eb57af31f3c715dd650e2ca2c096f1c" integrity sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A== +vscode-uri@^3.0.0: + version "3.0.8" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.8.tgz#1770938d3e72588659a172d0fd4642780083ff9f" + integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw== + vue-template-compiler@^2.6.11: version "2.6.11" resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz#c04704ef8f498b153130018993e56309d4698080" @@ -18021,33 +18011,16 @@ yaml-ast-parser@^0.0.40: resolved "https://registry.yarnpkg.com/yaml-ast-parser/-/yaml-ast-parser-0.0.40.tgz#08536d4e73d322b1c9ce207ab8dd70e04d20ae6e" integrity sha1-CFNtTnPTIrHJziB6uN1w4E0grm4= -yaml-language-server-parser@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/yaml-language-server-parser/-/yaml-language-server-parser-0.1.1.tgz#02cc9c022a8b10ffa7ba92096ffee86433a50b07" - integrity sha512-2PememGb1SrPqXAxXTpBD39rwYZap6CJVSvkfULNv9uwV3VHp1TfkgpsylBb+mpuuivH0JZ52lChXPvNa6yVxw== - -yaml-language-server@0.13.0: - version "0.13.0" - resolved "https://registry.yarnpkg.com/yaml-language-server/-/yaml-language-server-0.13.0.tgz#ea18facf59618589b51675ee63e14e00c71c7906" - integrity sha512-5FHW7dUAyIjEM3mRzIplE0pZut2K30cA+K7coaOxFxi82LTk/oiVLS4/AQFnOtGicSyoi4YOiRqpMZ04vgtuew== - dependencies: - js-yaml "^3.13.1" - jsonc-parser "^2.2.1" - request-light "^0.2.4" - vscode-json-languageservice "^3.10.0" - vscode-languageserver "^5.2.1" - vscode-languageserver-types "^3.15.1" - vscode-nls "^4.1.2" - vscode-uri "^2.1.1" - yaml-language-server-parser "0.1.1" - optionalDependencies: - prettier "2.0.5" - yaml@^1.10.0, yaml@^1.7.2: version "1.10.0" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== +yaml@^2.0.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.6.1.tgz#42f2b1ba89203f374609572d5349fb8686500773" + integrity sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg== + yargs-parser@^13.1.2: version "13.1.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38"