feat: add monaco editor for custom monitor provider

This commit is contained in:
moonrailgun 2024-01-01 16:33:01 +08:00
parent 8dfa679127
commit 96e2e008eb
6 changed files with 123 additions and 2 deletions

View File

@ -24,6 +24,7 @@
"dependencies": { "dependencies": {
"@ant-design/charts": "^1.4.2", "@ant-design/charts": "^1.4.2",
"@ant-design/icons": "^5.2.5", "@ant-design/icons": "^5.2.5",
"@monaco-editor/react": "^4.6.0",
"@paralleldrive/cuid2": "^2.2.2", "@paralleldrive/cuid2": "^2.2.2",
"@prisma/client": "^5.4.2", "@prisma/client": "^5.4.2",
"@tanstack/react-query": "^4.33.0", "@tanstack/react-query": "^4.33.0",

View File

@ -7,6 +7,9 @@ dependencies:
'@ant-design/icons': '@ant-design/icons':
specifier: ^5.2.5 specifier: ^5.2.5
version: 5.2.5(react-dom@18.2.0)(react@18.2.0) version: 5.2.5(react-dom@18.2.0)(react@18.2.0)
'@monaco-editor/react':
specifier: ^4.6.0
version: 4.6.0(monaco-editor@0.45.0)(react-dom@18.2.0)(react@18.2.0)
'@paralleldrive/cuid2': '@paralleldrive/cuid2':
specifier: ^2.2.2 specifier: ^2.2.2
version: 2.2.2 version: 2.2.2
@ -1760,6 +1763,28 @@ packages:
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
dev: false dev: false
/@monaco-editor/loader@1.4.0(monaco-editor@0.45.0):
resolution: {integrity: sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==}
peerDependencies:
monaco-editor: '>= 0.21.0 < 1'
dependencies:
monaco-editor: 0.45.0
state-local: 1.0.7
dev: false
/@monaco-editor/react@4.6.0(monaco-editor@0.45.0)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==}
peerDependencies:
monaco-editor: '>= 0.25.0 < 1'
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
'@monaco-editor/loader': 1.4.0(monaco-editor@0.45.0)
monaco-editor: 0.45.0
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: false
/@noble/hashes@1.3.2: /@noble/hashes@1.3.2:
resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==}
engines: {node: '>= 16'} engines: {node: '>= 16'}
@ -6513,6 +6538,10 @@ packages:
resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==} resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==}
dev: false dev: false
/monaco-editor@0.45.0:
resolution: {integrity: sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==}
dev: false
/morgan@1.10.0: /morgan@1.10.0:
resolution: {integrity: sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==} resolution: {integrity: sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
@ -9063,6 +9092,10 @@ packages:
stacktrace-gps: 3.1.2 stacktrace-gps: 3.1.2
dev: false dev: false
/state-local@1.0.7:
resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==}
dev: false
/statuses@2.0.1: /statuses@2.0.1:
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}

View File

@ -0,0 +1,5 @@
import { lazy } from 'react';
export const CodeEditor = lazy(() =>
import('./main').then((m) => ({ default: m.CodeEditor }))
);

View File

@ -0,0 +1,48 @@
export const sandboxGlobal = `
interface AxiosConfig {
url?: string;
method?:
| 'get' | 'GET'
| 'delete' | 'DELETE'
| 'head' | 'HEAD'
| 'options' | 'OPTIONS'
| 'post' | 'POST'
| 'put' | 'PUT'
| 'patch' | 'PATCH'
| 'purge' | 'PURGE'
| 'link' | 'LINK'
| 'unlink' | 'UNLINK';
baseURL?: string;
headers?: Record<string, string>;
params?: any;
data?: any;
timeout?: number;
withCredentials?: boolean;
auth?: {
username: string;
password: string;
};
responseType?:
| 'arraybuffer'
| 'blob'
| 'document'
| 'json'
| 'text'
| 'stream';
responseEncoding?: string;
xsrfCookieName?: string;
xsrfHeaderName?: string;
maxContentLength?: number;
proxy?: {
host: string;
port: number;
auth?: {
username: string;
password: string;
};
protocol?: string;
} | false;
}
const request = async (config: AxiosConfig) => {}
`;

View File

@ -0,0 +1,33 @@
import Editor, { Monaco } from '@monaco-editor/react';
import React from 'react';
import { useSettingsStore } from '../../store/settings';
import { useEvent } from '../../hooks/useEvent';
import { sandboxGlobal } from './lib/sandbox';
interface CodeEditorProps {
height?: string | number;
value?: string;
onChange?: (code: string) => void;
}
export const CodeEditor: React.FC<CodeEditorProps> = React.memo((props) => {
const colorScheme = useSettingsStore((state) => state.colorScheme);
const theme = colorScheme === 'dark' ? 'vs-dark' : 'light';
const handleEditorWillMount = useEvent((monaco: Monaco) => {
monaco.languages.typescript.javascriptDefaults.addExtraLib(
sandboxGlobal,
'global.ts'
);
});
return (
<Editor
height={props.height}
theme={theme}
defaultLanguage="javascript"
value={props.value}
onChange={(val) => props.onChange?.(val ?? '')}
beforeMount={handleEditorWillMount}
/>
);
});

View File

@ -1,6 +1,7 @@
import { Form, Input } from 'antd'; import { Button, Form } from 'antd';
import React from 'react'; import React from 'react';
import { MonitorProvider } from './types'; import { MonitorProvider } from './types';
import { CodeEditor } from '../../CodeEditor';
export const MonitorCustom: React.FC = React.memo(() => { export const MonitorCustom: React.FC = React.memo(() => {
return ( return (
@ -10,7 +11,7 @@ export const MonitorCustom: React.FC = React.memo(() => {
name={['payload', 'code']} name={['payload', 'code']}
rules={[{ required: true }]} rules={[{ required: true }]}
> >
<Input.TextArea placeholder="return 1" rows={10} /> <CodeEditor height={320} />
</Form.Item> </Form.Item>
</> </>
); );