Skip to content

Commit

Permalink
Merge pull request #1586 from redpanda-data/yaml-monaco-editor
Browse files Browse the repository at this point in the history
Yaml monaco editor
  • Loading branch information
andresaristizabal authored Jan 16, 2025
2 parents 19fe8d8 + d675089 commit 3199b46
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 95 deletions.
35 changes: 24 additions & 11 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"mobx-react": "^7.6",
"moment": "^2.29.4",
"monaco-editor": "^0.52.0",
"monaco-editor-webpack-plugin": "^7.1.0",
"monaco-yaml": "^5.2.2",
"node-polyfill-webpack-plugin": "^4.0.0",
"pretty-bytes": "^5.6.0",
Expand Down
15 changes: 15 additions & 0 deletions frontend/rsbuild.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { pluginReact } from '@rsbuild/plugin-react';
import { pluginSass } from '@rsbuild/plugin-sass';
import { pluginSvgr } from '@rsbuild/plugin-svgr';
import { RsdoctorRspackPlugin } from '@rsdoctor/rspack-plugin';
import MonacoWebpackPlugin from 'monaco-editor-webpack-plugin';
import NodePolyfillPlugin from 'node-polyfill-webpack-plugin';

import moduleFederationConfig from './module-federation';
Expand Down Expand Up @@ -73,6 +74,20 @@ export default defineConfig({
new NodePolyfillPlugin({
additionalAliases: ['process'],
}),
new MonacoWebpackPlugin({
languages: ['yaml', 'json', 'typescript', 'javascript', 'protobuf'],
customLanguages: [
{
label: 'yaml',
entry: 'monaco-yaml',
worker: {
id: 'monaco-yaml/yamlWorker',
entry: 'monaco-yaml/yaml.worker',
},
},
],
filename: 'static/js/[name].worker.js',
}),
];

if (process.env.RSDOCTOR) {
Expand Down
81 changes: 20 additions & 61 deletions frontend/src/components/misc/PipelinesYamlEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
import Editor, { type EditorProps, type Monaco } from '@monaco-editor/react';
import 'monaco-editor';
import type { editor } from 'monaco-editor';
import type { MonacoYamlOptions } from 'monaco-yaml';
import { type MonacoYaml, type MonacoYamlOptions, configureMonacoYaml } from 'monaco-yaml';
import { useCallback, useEffect, useState } from 'react';
import benthosSchema from '../../assets/rp-connect-schema.json';

type IStandaloneCodeEditor = editor.IStandaloneCodeEditor;
Expand Down Expand Up @@ -71,60 +72,29 @@ export const monacoYamlOptions = {
},

// And the URI will be linked to as the source.
uri: 'http://example.com/schema-name.json', // '../../benthos-schema.json',
uri: 'http://example.com/redpanda-connect-schema.json', // '../../benthos-schema.json',
},
],
} as MonacoYamlOptions;

// const linter = {
// editor: undefined as undefined | IStandaloneCodeEditor,
// monaco: undefined as undefined | Monaco,
//
// isLinting: false,
// text: '',
//
// async refreshLint() {
// if (!this.editor) return;
// const monaco = this.monaco;
// if (!monaco) return;
// if (this.isLinting) return;
//
// const model = this.editor.getModel();
// if (!model) return;
//
// // Save the text into a local variable, so we can compare/know if we need to lint again
// const lintedText = this.text;
//
// this.isLinting = true;
// const r = await pipelinesApi.lintConfig(lintedText).catch(() => null);
// this.isLinting = false;
// if (!r) return; // do nothing, don't care about fetching errors here
//
// // Update the results
// const markers = r.lints.map(l => {
// return {
// message: l.reason,
// startLineNumber: l.line,
// endLineNumber: l.line,
// startColumn: l.column,
// endColumn: l.column + 4,
// severity: MarkerSeverity.Error,
// } as editor.IMarkerData;
// });
//
// monaco.editor.setModelMarkers(model, 'owner', markers);
//
// // Maybe, while we were linting, the user has modified the text?
// // If so, this function didn't run (because of the isLinting check at the start)
// // So we need to lint the new config
// if (this.text != lintedText)
// this.refreshLint();
// }
// };

export default function PipelinesYamlEditor(props: PipelinesYamlEditorProps) {
const { options: givenOptions, ...rest } = props;
const options = Object.assign({}, defaultOptions, givenOptions ?? {});
const [yaml, setYaml] = useState<MonacoYaml | undefined>(undefined);

useEffect(() => {
return () => {
if (yaml) {
// avoid duplicate yaml option registration
yaml.dispose();
}
};
}, [yaml]);

const setMonacoOptions = useCallback(async (monaco: Monaco) => {
const yaml = configureMonacoYaml(monaco, monacoYamlOptions);
setYaml(yaml);
}, []);

return (
<Editor
Expand All @@ -134,22 +104,11 @@ export default function PipelinesYamlEditor(props: PipelinesYamlEditorProps) {
style: { minWidth: 0, width: '100px', display: 'flex', flexBasis: '100%' },
}}
defaultValue={''}
path={'new-connector.yaml'}
defaultLanguage="yaml"
options={options}
beforeMount={(monaco) => setMonacoOptions(monaco)}
{...rest}

// onChange={(v, ev) => {
// if (v) {
// linter.text = v;
// linter.refreshLint();
// }
// rest.onChange?.(v, ev);
// }}

// onMount={(editor, monaco) => {
// linter.editor = editor;
// linter.monaco = monaco;
// }}
/>
);
}
Expand Down
37 changes: 14 additions & 23 deletions frontend/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@ import memoizeOne from 'memoize-one';
*/
import { autorun, configure, observable, when } from 'mobx';
import * as monaco from 'monaco-editor';
import { configureMonacoYaml } from 'monaco-yaml';

import { DEFAULT_API_BASE } from './components/constants';
import { monacoYamlOptions } from './components/misc/PipelinesYamlEditor';
import { APP_ROUTES } from './components/routes';
import { ConsoleService } from './protogen/redpanda/api/console/v1alpha1/console_service_connect';
import { DebugBundleService } from './protogen/redpanda/api/console/v1alpha1/debug_bundle_connect';
Expand Down Expand Up @@ -268,36 +267,28 @@ export const embeddedAvailableRoutesObservable = observable({
});

export const setup = memoizeOne((setupArgs: SetConfigArguments) => {
const config = setConfig(setupArgs);
setConfig(setupArgs);

// Tell monaco editor where to load dependencies from
loader.config({
paths: {
vs: `${config.assetsPath}/static/js/vendor/monaco/package/min/vs`,
},
});
loader.config({ monaco });

// Ensure yaml workers are being loaded locally as well
loader.init().then(async (monaco) => {
loader.init().then(async () => {
window.MonacoEnvironment = {
baseUrl: `${config.assetsPath}/static/js/vendor/monaco/package/min`,

getWorker(moduleId, label) {
console.debug(`window.MonacoEnvironment.getWorker looking for moduleId ${moduleId} label ${label}`);
getWorkerUrl(_, label: string): string {
switch (label) {
case 'editorWorkerService':
return new Worker(new URL('monaco-editor/esm/vs/editor/editor.worker', import.meta.url));
case 'yaml':
// return new yamlWorker();
return new Worker(new URL('monaco-yaml/yaml.worker', import.meta.url));

default:
throw new Error(`Unknown label ${label}`);
case 'editorWorkerService': {
return `${window.location.origin}/static/js/editor.worker.js`;
}
case 'typescript': {
return `${window.location.origin}/static/js/ts.worker.js`;
}
default: {
return `${window.location.origin}/static/js/${label}.worker.js`;
}
}
},
};

configureMonacoYaml(monaco, monacoYamlOptions);
});

// Configure MobX
Expand Down

0 comments on commit 3199b46

Please sign in to comment.