index.tsx 4.75 KB
import React, {useCallback, useEffect, useRef, useState} from 'react';
import { useSetState } from 'ahooks';
import { Button } from 'antd';
import cls from 'classnames';
import type { InputSelectProps } from '../qx-input-select';
import { QxInputSelect } from '../qx-input-select';
import {QxBaseIcon, QxAppSelector} from '@qx/common';

import {getAppFromList, getFunInfo} from './service';

import './styles.less';

const prefix = 'qx-form-select';

const FormSelectMain: React.FC<FormSelectProps>= (props)=> {
  const {
    className,
    options = [],
    onChange,
    value,
    loading,
    appId,
    disabled,
    placeholder,
    title
  } = props;

  const [state, setState] = useSetState<FormSelectState>({
    visible: false,
    modalVisible: false,
  });
  const inputSelectRef = useRef<any>();
  const [item, setItem] = useState<any>({});


  const handleChange = (val: any) => {
    if (!val?.code) return;
    function onOk() {
      if (val?.code) {
        onChange?.({
          appId: val?.appId || appId,
          formId: val.code,
          isTree: val.extract?.isTree,
        });
        setState({
          visible: false,
        });
      }
    }
    onOk();
  };

  const onOpenOther = useCallback(() => {
    inputSelectRef.current?.closeDropdown();
    setState({
      modalVisible: true,
    });
  }, []);

  useEffect(() => {
    if (!value || !Object.keys(value || {})?.length || !value?.formId) {
      setItem({
        flag: 'SINGLE',
        code: '',
        appId: appId || '',
        name: '',
        appName: ''
      });
      return;
    }

    let _item: any = {};
    options.map((it: any) => {
      if (it.code === value?.formId) {
        _item = {
          flag: 'SINGLE',
          appId: appId,
          code: it.code,
          name: it.name,
          appName: it.extract?.appName
        };
      }
    });

    setItem(_item);
    if (!_item?.code) {
      getFunInfo(value?.formId).then((res: any) => {
        if (!res) {
          return;
        }
        setItem({
          flag: 'SINGLE',
          code: res.code,
          appId: res?.extract?.appId,
          name: res.name,
          appName: res.extract?.appName
        });
      });
    }
  }, [JSON.stringify(value), JSON.stringify(options)]);


  return (
    <div className={cls(prefix, className)}>
      {props?.preview ? <>
        {item?.name}
      </> : <>
        <QxInputSelect
          ref={inputSelectRef}
          value={item?.name}
          defaultValue={item?.name}
          placeholder={placeholder || '请选择数据源'}
          prefix={<QxBaseIcon className={`${prefix}__input-prefix`} type={'icon-field-rel'} />}
          options={options}
          onChange={handleChange}
          dropdownProps={{
            showSearch: true,
            loading,
            renderBottom: (
              <Button
                className={`${prefix}__dropdown-bottom`}
                type="link"
                onClick={onOpenOther}
              >
                其他应用
              </Button>
            ),
          }}
          disabled={disabled}
          popupOnBody={props?.popupOnBody}
          from={'FORM'}
          appName={item.appName}
        />

        {state.modalVisible ? (
          <QxAppSelector
            title={title || placeholder || '选择数据源'}
            item={{
              ...item,
              currentId: appId,
            }}
            onChange={handleChange}
            flag="join"
            showTableTypeTab={false}
            modalProps={{
              width: 480,
              destroyOnClose: true,
              open: state.modalVisible,
              onOk: () => setState({ modalVisible: false }),
              onCancel: () => setState({ modalVisible: false }),
            }}
          />
        ) : null}
      </>}
    </div>
  );
}

/**
 * 选择数据源
 * TODO 当前只支持表单选择 聚合表选择待开发
 */
export const QxFormSelect: React.FC<FormSelectProps> = (props) => {
  const {
    options = [] as any,
    appId,
    value,
  } = props;

  const [selectOptions, setSelectOptions] = useState([])

  useEffect(() => {
    if(appId && !options?.length) {
      getAppFromList(appId).then((res: any)=> {
        if(res?.length){
          setSelectOptions(res)
        } else {
          setSelectOptions([])
        }
      }).catch(()=> {
        setSelectOptions([])
      })
    } else {
      setSelectOptions(options)
    }
  }, [JSON.stringify(options), appId]);


  return <FormSelectMain {...props} options={selectOptions}/>
};

interface FormSelectProps extends InputSelectProps {
  value?: any;
  loading?: boolean;
  appId?: string; // 当前应用ID
  request?: any;
  disabled?: boolean;
  popupOnBody?: boolean;
  preview?: boolean;
}
interface FormSelectState {
  visible: boolean;
  modalVisible: boolean;
}