@cainiaofe/cn-ui-lowcode
Version:
418 lines (401 loc) • 10.9 kB
JavaScript
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 };