All files / src/components/functionEditor FunctionEditor.tsx

7.14% Statements 2/28
0% Branches 0/2
0% Functions 0/9
7.69% Lines 2/26

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>;
};