UNPKG

@cainiaofe/cn-ui-lowcode

Version:
418 lines (401 loc) 10.9 kB
import React from 'react'; import { CnDialog as UICnDialog, CnButton, CnDrawer as UICnDrawer, formilyReact, } from '@cainiaofe/cn-ui'; import { executeFunction, executeObjectExpr, getRealizeValue, isArrayNotEmpty, isDesignMode, renderIcon, transProxyToObject, getRunTimeItem as getCommonRunTimeItem, } from '@/common/util/util'; import './view.scss'; import { getButtonAction, getItem as getButtonItem, getRunTimeItem, } from '@/common/manager/button'; import CnForm from '../cn-form-alc'; import { ButtonPosition } from '@/common/manager/position/button-position'; import { _getFormValues, _state, } from '@/common/util/biz-component-prop-name'; import { __dataSource__, __extraParam__, __filterValue__, __formValue__, __stateValueOfSplit__, } from '@/common/util/expr-const'; import set from 'lodash/set'; import get from 'lodash/get'; const { Observer } = formilyReact || {}; class CnFormDialog extends React.Component { constructor(props) { super(props); this.state = { visible: false, }; this.formInstance = null; this.formStepInstance = null; this.formRef = null; } getFormInstance = () => { return this.formInstance; }; // componentWillReceiveProps(nextProps, nextContext) { // const newFormValue = this.getFormValue(nextProps); // const originValue = this.formInstance?.values; // if(!isEqual(newFormValue, originValue)) { // this.formInstance.setValues(newFormValue); // } // } emptyContent = () => { return ( <div style={{ padding: '20px 0 60px 0', display: 'flex', justifyContent: 'center', fontSize: '24px', }} > 请在右侧表单配置面板添加表单项 </div> ); }; close = () => { const { _context, _dataSourceName } = this.props; this.formInstance && this.formInstance.setValues({}, 'overwrite'); this.formInstance = null; if (_dataSourceName) { const path = `${_dataSourceName}${__stateValueOfSplit__}openDialogMode`; if (_context) { set(_context.state.valueOf, path, undefined); } } this.setState({ visible: false, }); }; open = (data, config) => { const { _context, _dataSourceName } = this.props; const { selectedRowKeys, selectedRowRecords, buttonConfig } = config || {}; const { options } = buttonConfig || {}; const { openDialogMode } = options || {}; // FIXME 临时方案,表格选中项托管到当前弹窗上 this.selectedRowKeys = selectedRowKeys; this.selectedRowRecords = selectedRowRecords; if (data !== undefined && data !== null) { if (_context && _dataSourceName) { _context?.setState({ [_dataSourceName]: data, }); } } if (openDialogMode && _context?.state?.valueOf) { set( _context.state.valueOf, `${_dataSourceName}$$$openDialogMode`, openDialogMode, ); set( _context.state.valueOf, `${_dataSourceName}${__stateValueOfSplit__}openDialogMode`, openDialogMode, ); } return new Promise((resolve) => { setTimeout(() => { this.setState( { visible: true, }, () => { // 给formInstance创建留出时间 setTimeout(() => { resolve(true); }, 50); }, ); }); }); }; getUrlParams = () => { const { _context } = this.props; return _context?.state?.urlParams || {}; }; load = () => { this.formRef?.load?.(); }; reRender = () => { this.formRef?.reRender?.(); }; getExtraParam = () => { const { _context, _dataSourceName } = this.props; return { openDialogMode: get( _context?.state?.valueOf, `${_dataSourceName}${__stateValueOfSplit__}openDialogMode`, ), }; }; getButtons = () => { const { buttons = [], _context, dialogMode } = this.props; if (!(buttons?.length > 0)) { return false; } const result = buttons.map((item, index) => { const { iconType, primaryKey, optType, options = {}, children, type, hidden, disabled, ...rest } = item; const position = ButtonPosition.formDialog; const action = getButtonAction({ ...item, position: ButtonPosition.formDialog, }); const getRenderDom = getButtonItem(position, optType, 'getRenderDom'); const componentDefine = getRunTimeItem(optType); const btnProps = { type, }; let needShowLoading; if (optType === 'submit') { needShowLoading = true; } else if (optType === 'flowAction') { const hasSubmitAction = options?.flowList?.find?.( (item) => item?.optType === 'submit', ); if (hasSubmitAction) { needShowLoading = true; } } if (dialogMode === 'drawer') { btnProps.size = 'large'; } const formValue = this.formInstance?.values; const isHidden = executeObjectExpr( hidden, { [__filterValue__]: formValue || {}, [__formValue__]: formValue || {}, [__dataSource__]: _context?.state, [__extraParam__]: { currentFormStep: this.formStepInstance?.current, }, }, formValue || {}, _context?.state, ); if (isHidden) { return null; } if ( optType === 'previousStep' && this.formStepInstance?.allowBack !== true ) { return null; } if (optType === 'nextStep' && this.formStepInstance?.allowNext !== true) { return null; } if (needShowLoading) { btnProps.loading = this.formInstance?.submitting; } const isDisabled = executeObjectExpr( disabled, { [__filterValue__]: formValue || {}, [__formValue__]: formValue || {}, [__dataSource__]: _context?.state, }, formValue || {}, _context?.state, ); if (isDisabled === true) { btnProps.disabled = true; } if (componentDefine?.component) { const component = getRealizeValue(componentDefine.component); if (component) { return React.createElement(component, { ...btnProps, buttonConfig: item, dialogRef: this, _context, }); } } else if (typeof getRenderDom === 'function') { return executeFunction(getRenderDom, { _context, buttonConfig: item, state: _context?.state, urlParamsDataSource: this.getUrlParams(), recordDataSource: { realize: () => { return this?.formInstance?.values; }, }, }); } if (action) { btnProps.onClick = action.bind(this, { componentProps: this.props, buttonConfig: item, open: this.open, close: this.close, dialogRef: this, formInstance: { realize: () => { return this?.formInstance; }, }, position: ButtonPosition.formDialog, state: _context?.state, urlParamsDataSource: this.getUrlParams(), recordDataSource: { realize: () => { return this?.formInstance?.values; }, }, _context, formStepInstance: this.formStepInstance, getExtraParam: this.getExtraParam, }); } return ( <CnButton key={index} mobileProps={{ fullWidth: true, size: 'large' }} {...btnProps} > {renderIcon(iconType)} {children} </CnButton> ); }); if (Array.isArray(result) && result.length > 0) { return <>{result}</>; } }; getForm = () => { const { config, dynamicFormConfig = {} } = this.props; const { active: dynamicFormConfigActive } = dynamicFormConfig; if (dynamicFormConfigActive || (config && config.length > 0)) { return ( <CnForm {...this.props} onCreateForm={(formInstance, formStepInstance) => { this.formInstance = formInstance; this.formStepInstance = formStepInstance; }} dialogRef={this} ref={(c) => (this.formRef = c)} /> ); } else { return this.emptyContent(); } }; render() { let { visible } = this.state; const { config, children, dialogMode, title, _context, canCloseByOutSideClick, ...otherProps } = this.props; const { _dataSourceName } = otherProps || {}; const isDesign = isDesignMode(this.props); if (isDesign) { visible = true; } let drawerEmbeddable = false; let Component = UICnDialog; if (dialogMode === 'drawer') { if (config && config[0] && config[0].componentName === 'CnCard') { drawerEmbeddable = true; } Component = UICnDrawer; } let realTitle = title; if (typeof title === 'function') { realTitle = executeFunction( title, get( _context?.state?.valueOf, `${_dataSourceName}${__stateValueOfSplit__}openDialogMode`, ), _context?.state, ); } else { const componentDefine = getCommonRunTimeItem({}, title); if (componentDefine?.component) { const component = getRealizeValue(componentDefine.component); if (component) { realTitle = React.createElement(component, { _context, [_state]: _context?.state, [_getFormValues]: () => { return this?.formInstance?.values; }, }); } } } const componentProps = { className: 'cn-dialog-alc', ...otherProps, title: realTitle, visible, onClose: this.close, okProps: { visible: false }, cancelProps: { visible: false }, }; if (dialogMode === 'drawer') { // componentProps.canCloseByOutSideClick = canCloseByOutSideClick; } if (isArrayNotEmpty(this.props?.buttons)) { componentProps.footer = ( <Observer> {() => { return this.getButtons(); }} </Observer> ); } else { componentProps.footer = false; } if (drawerEmbeddable) { componentProps.embeddable = drawerEmbeddable; } return ( <Observer> {() => { return <Component {...componentProps}>{this.getForm()}</Component>; }} </Observer> ); } } CnFormDialog.displayName = 'CnFormDialog'; export default CnFormDialog; export { CnFormDialog };