configComponent.tsx 6.22 KB
import React, { memo, useState, useEffect, useImperativeHandle } from 'react';
import { Checkbox, Form, Radio, Space, Tooltip } from 'antd';
import type { RadioChangeEvent } from 'antd';
import type { CheckboxChangeEvent } from 'antd/es/checkbox';
import type { IConfigComponent } from '@qx/flow';
import { QxParameterSetting } from '@qx/common';
import { QxIcon } from '@/components';
import { isEmpty, isEqual, cloneDeep } from 'lodash-es';

const propagationList: {
  value: string;
  label: string;
  tips: string;
}[] = [
  {
    value: 'REQUIRED',
    label: '需要事务',
    tips: '如果当前存在事务,则加入该事务;如果不存在事务,则创建一个新的事务',
  },
  {
    value: 'SUPPORTS',
    label: '支持当前事务',
    tips: '如果当前存在事务,则加入该事务;如果不存在事务,则直接执行',
  },
  {
    value: 'REQUIRES_NEW',
    label: '新建事务',
    tips: '不管当前是否存在事务,必定创建一个新事务,如果当前存在事务这个事务会被挂起。新事务在层级上与之前的事务是平级的,两者互不干扰',
  },
];

const isolationList: {
  value: string;
  label: string;
  tips: string;
}[] = [
  {
    value: 'READ_UNCOMMITTED',
    label: '读未提交',
    tips: '可以读到其它事务未提交的数据',
  },
  {
    value: 'READ_COMMITTED',
    label: '已提交读取',
    tips: '可以读到其它事务已提交的数据',
  },
  {
    value: 'REPEATABLE_READ',
    label: '可重复读取',
    tips: '不会读到其它事务已提交的数据',
  },
  {
    value: 'SERIALIZABLE',
    label: '可串行化的',
    tips: '串行化读',
  },
];

interface PropagationSettingProps {
  value: string;
  onChange: (val: string) => void;
  optionsList: {
    value: string;
    label: string;
    tips: string;
  }[];
}
const PropagationSetting: React.FC<PropagationSettingProps> = (props) => {
  const { value, onChange, optionsList } = props;

  return (
    <Radio.Group
      onChange={(e: RadioChangeEvent) => {
        onChange(e.target.value);
      }}
      value={value}
    >
      <Space direction="vertical">
        {(optionsList || []).map(
          (_options: { value: string; label: string; tips: string }) => {
            return (
              <Radio value={_options.value}>
                <span>{_options.label}</span>
                <Tooltip placement="right" title={_options.tips}>
                  <QxIcon
                    className={'qx-data-flow-tooltip-opt'}
                    type={'icon-frame-help'}
                  />
                </Tooltip>
              </Radio>
            );
          },
        )}
      </Space>
    </Radio.Group>
  );
};

const StartConfigComponent: React.FC<StartConfigComponentProps> =
  React.forwardRef((props, ref) => {
    const [form] = Form.useForm();

    useImperativeHandle(ref, () => ({
      validateFields: form.validateFields,
    }));

    const [values, setValues] = useState<{
      params?: any[];
      enablePropagation?: boolean;
      propagation?: string;
      isolation?: string;
    }>();
    useEffect(() => {
      if (isEmpty(props?.node?.data)) {
        return;
      }
      if (isEqual(props?.node?.data, values)) {
        return;
      }
      setValues({ ...props?.node?.data });
      form.setFieldsValue({ ...props?.node?.data });
    }, [JSON.stringify(props?.node?.data)]);

    const onCheckedChange = (e: CheckboxChangeEvent) => {
      const _cloneVal = !!values ? cloneDeep(values) : {};
      setValues({
        ..._cloneVal,
        enablePropagation: e.target.checked,
      });
    };

    useEffect(() => {
      if (!values || isEqual(props?.node?.data, values)) {
        return;
      }
      props.onChange(values);
    }, [JSON.stringify(values)]);

    return (
      <Form
        form={form}
        layout="vertical"
        initialValues={{
          enablePropagation: false,
          propagation: 'REQUIRED',
          isolation: 'REPEATABLE_READ',
        }}
      >
        <Form.Item
          style={{
            marginBottom: '24px',
          }}
          name="params"
        >
          <h3 className={'qx-flow-form__label-title'}>入参设置</h3>
          <p className={'qx-flow-form__label-tips'}>
            参数可以被后面的所有数据流节点使用
          </p>
          <QxParameterSetting
            // @ts-ignore
            value={values?.params || []}
            onChange={(_v: any) => {
              const _cloneVal = cloneDeep(values);
              setValues({
                ..._cloneVal,
                params: _v,
              });
            }}
          />
        </Form.Item>
        <Form.Item
          style={{
            marginBottom: '16px',
          }}
          name="enablePropagation"
        >
          <h3 className={'qx-flow-form__label-title'}>事务控制</h3>
          <Checkbox
            checked={values?.enablePropagation}
            onChange={onCheckedChange}
          >
            设置事务的传播行为和隔离级别
          </Checkbox>
        </Form.Item>
        <Form.Item
          hidden={!values?.enablePropagation}
          label="事务传播行为"
          name="propagation"
          style={{
            marginBottom: '16px',
          }}
        >
          <PropagationSetting
            optionsList={propagationList}
            value={values?.propagation || 'REQUIRED'}
            onChange={(_v: string) => {
              const _cloneVal = cloneDeep(values);
              setValues({
                ..._cloneVal,
                propagation: _v,
              });
            }}
          />
        </Form.Item>
        <Form.Item
          hidden={!values?.enablePropagation}
          label="事务隔离级别"
          name="isolation"
        >
          <PropagationSetting
            optionsList={isolationList}
            value={values?.isolation || 'REPEATABLE_READ'}
            onChange={(_v: string) => {
              const _cloneVal = cloneDeep(values);
              setValues({
                ..._cloneVal,
                isolation: _v,
              });
            }}
          />
        </Form.Item>
      </Form>
    );
  });

interface StartConfigComponentProps extends IConfigComponent {
  onChange: (values: any) => void;
}

export default memo(StartConfigComponent);