You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Hydro/packages/ui-default/components/problemconfig/ProblemConfigEditor.tsx

90 lines
2.2 KiB
TypeScript

import React from 'react';
import type { editor } from 'monaco-editor';
import { connect } from 'react-redux';
import { load } from 'vj/components/monaco/loader';
import Editor from 'vj/components/editor';
import yaml from 'js-yaml';
const mapStateToProps = (state) => ({
config: state.config,
});
const mapDispatchToProps = (dispatch) => ({
handleUpdateCode: (code) => {
dispatch({
type: 'CONFIG_CODE_UPDATE',
payload: code,
});
},
});
interface Props {
config: object;
handleUpdateCode: Function;
}
export default connect(mapStateToProps, mapDispatchToProps)(class MonacoEditor extends React.PureComponent<Props> {
disposable = [];
containerElement: HTMLElement;
private __preventUpdate = false;
editor: editor.IStandaloneCodeEditor;
model: editor.ITextModel;
vjEditor: Editor;
async componentDidMount() {
const { monaco } = await load(['yaml']);
const uri = monaco.Uri.parse('hydro://problem/file/config.yaml');
this.model = monaco.editor.createModel(yaml.dump(this.props.config), 'yaml', uri);
this.vjEditor = Editor.getOrConstruct($(this.containerElement), {
language: 'yaml',
model: this.model,
onChange: (value: string) => {
this.__preventUpdate = true;
this.props.handleUpdateCode(value);
this.__preventUpdate = false;
},
}) as Editor;
this.editor = this.vjEditor.editor;
}
componentDidUpdate(prevProps) {
if (this.__preventUpdate) return;
if (yaml.dump(prevProps.config) !== yaml.dump(this.props.config)) {
this.model?.pushEditOperations(
[],
[{
range: this.model.getFullModelRange(),
text: yaml.dump(this.props.config),
}],
undefined,
);
}
}
componentWillUnmount() {
if (this.vjEditor) this.vjEditor.destory();
if (this.model) this.model.dispose();
if (this.editor) this.editor.dispose();
this.disposable.map((i) => i.dispose());
}
assignRef = (component) => {
this.containerElement = component;
};
render() {
return (
<div
ref={this.assignRef}
style={{
minHeight: '500px',
height: '100%',
width: '100%',
}}
className="ConfigMonacoEditor"
>
</div>
);
}
});