File: //opt/agentcloud/webapp/src/components/Editor.tsx
// Courtesy of AlbinoGeek: https://github.com/react-monaco-editor/react-monaco-editor/issues/271#issuecomment-986612363
import Editor from '@monaco-editor/react';
import {
Dispatch,
MutableRefObject,
SetStateAction,
useEffect,
useRef
} from 'react';
//
// So... typings weren't working when I implemented Monaco, and we had to ship,
// so these placeholder types were put in place so tests passed... please fix
// these before going production. imo Monaco provides typings, they just didn't
// work when we tried them (VSCode wouldn't recognize them, tslint complained.)
//
export type MonacoEditorOptions = {
stopRenderingLineAfter: number;
}
export type MonacoEditorA = MutableRefObject<any>;
export type MonacoEditorB = MutableRefObject<any>;
export type MonacoTextModal = any;
export type MonacoOnInitializePane = (
monacoEditorRef: MonacoEditorA,
editorRef: MonacoEditorB,
model: MonacoTextModal
) => void;
export type ScriptEditorProps = {
// usage: const [code, setCode] = useState<string>('default value')
code: string
setCode: Dispatch<SetStateAction<string>>
// see: https://microsoft.github.io/monaco-editor/api/modules/monaco.editor.html
editorOptions: MonacoEditorOptions
onInitializePane: MonacoOnInitializePane
};
//
// End of placeholder typings
//
const ScriptEditor = (props: ScriptEditorProps): JSX.Element => {
const { code, setCode, editorOptions, onInitializePane } = props;
const monacoEditorRef = useRef<any | null>(null);
const editorRef = useRef<any | null>(null);
// monaco takes years to mount, so this may fire repeatedly without refs set
useEffect(() => {
if (monacoEditorRef?.current) {
// again, monaco takes years to mount and load, so this may load as null
const model: any = monacoEditorRef.current.getModels();
if (model?.length > 0) {
// finally, do editor's document initialization here
onInitializePane(monacoEditorRef, editorRef, model);
}
}
});
return <Editor
height='42.9em' // preference
language='python' // preference
onChange={(value, _event) => {
setCode(value);
}}
onMount={(editor, monaco) => {
monacoEditorRef.current = monaco.editor;
editorRef.current = editor;
}}
options={editorOptions}
theme='vs-dark' // preference
value={code}
width='100%' // preference
/>;
};
export default ScriptEditor;