Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 66x 66x | import React, { Suspense, useEffect, useRef } from "react";
import { Divider, FormInstance, Input, List, Tooltip } from "antd";
import { fetchFunctions, FunctionInfo } from "./FunctionEditorUtils";
import { SaveRecordProps, Store, TableMetaProps } from "@props/RecordProps";
import { useResizeDetector } from "react-resize-detector";
import { CodeEditorRef } from "../../form/fields/CodeEditor";
import "./FunctionEditor.css";
import { SearchOutlined } from "@ant-design/icons";
const CodeEditor = React.lazy(() => import('../../form/fields/CodeEditor'));
export interface FunctionEditorProps {
code: string;
record?: SaveRecordProps | undefined;
column: TableMetaProps;
form?: FormInstance;
onValuesChange?: (changedValues: Store, allValues: Store) => void;
zIndex: number;
}
export const FunctionEditor: React.FC<FunctionEditorProps> = (props) => {
const {
code, form, column, onValuesChange,
record, zIndex
} = props;
const { key, extInfo } = column;
const [functions, setFunctions] = React.useState<FunctionInfo[]>([]);
const [filteredFunctions, setFilteredFunctions] = React.useState<FunctionInfo[]>([]);
const { width, ref } = useResizeDetector();
const [pattern, setPattern] = React.useState<string>('tech.muyan.function.DynamicFunctionService.invoke("FUNCTION_NAME", params)');
const codeRef = useRef<CodeEditorRef>(null);
const parentWidth = (width ?? 440);
const listWidth = parentWidth / 5;
const codeWidth = parentWidth - listWidth - 10;
useEffect(() => {
fetchFunctions().then((res) => {
setFunctions(res.functions);
setPattern(res.pattern);
setFilteredFunctions(res.functions);
}
);
}, []);
return <div
ref={ref}
className='function-editor'
>
<div
style={{
width: listWidth,
}}
>
<div className='function-editor-candidate'>
<div style={{
paddingLeft: 5,
paddingRight: 5,
}}>
<Input
prefix={<SearchOutlined/>}
onChange={(e) => {
const keyword = e.target.value.toLowerCase();
setFilteredFunctions(functions.filter(f => f.name.toLowerCase().includes(keyword)));
}}
/>
</div>
<Divider/>
<List
className="function-editor-candidate-list"
dataSource={filteredFunctions}
renderItem={(item) =>
<List.Item>
<Tooltip title={item.description}>
<span
onClick={() => codeRef.current?.insertText(pattern.replace("FUNCTION_NAME", item.name))}
style={{
cursor: "pointer",
}}
>
{item.name}
</span>
</Tooltip>
</List.Item>
}
style={{
backgroundColor: '#ffffff',
paddingLeft: 10,
paddingRight: 10,
}}
/>
</div>
</div>
<Suspense fallback={<div/>}>
<div style={{
paddingLeft: 10,
}}>
<CodeEditor
value={code}
onChange={(val) => {
const changedValue = { [column.key]: val };
const newValue = { ...record, ...changedValue };
form?.setFieldsValue(changedValue);
onValuesChange?.(changedValue, newValue);
}}
name={key}
width="99%"
updatable={true}
style={{
width: codeWidth,
margin: "auto",
paddingLeft: 10,
}}
mode={extInfo?.codeLanguage}
zIndex={zIndex}
record={record}
ref={codeRef}
/>
</div>
</Suspense>
</div>;
}; |