@cainiaofe/cn-ui-lowcode
Version:
316 lines (298 loc) • 7.79 kB
JavaScript
import React from 'react';
import { CnDialog as UICnDialog, CnDrawer, CnButton } from '@cainiaofe/cn-ui';
import {
executeEventWithoutJS,
executeFunction,
executeObjectExpr,
getRealizeValue,
getRunTimeItem as getCommonRunTimeItem,
isArrayNotEmpty,
isDesignMode,
renderIcon,
} from '@/common/util/util';
import './view.scss';
import {
getButtonAction,
getItem as getButtonItem,
getRunTimeItem,
} from '@/common/manager/button';
import { ButtonPosition } from '@/common/manager/position/button-position';
import {
_buttonConfig,
_buttonPosition,
_context as _contextConst,
_dialogRef,
_getFormValues,
_state,
} from '@/common/util/biz-component-prop-name';
import {
__dataSource__,
__stateValueOfSplit__,
} from '@/common/util/expr-const';
import {
CnTableRequestFinish,
onEvent,
} from '@/common/util/event-name';
import get from 'lodash/get';
import set from 'lodash/set';
import merge from 'lodash/merge';
import isPlainObject from 'lodash/isPlainObject';
class CnDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: false,
};
}
componentDidMount() {
onEvent(CnTableRequestFinish, (tableInfo) => {
this.forceUpdate();
});
}
close = () => {
const { _context, _dataSourceName, events } = this.props;
if (_dataSourceName) {
const path = `${_dataSourceName}${__stateValueOfSplit__}openDialogMode`;
if (_context) {
set(_context.state.valueOf, path, undefined);
}
}
this.setState({
visible: false,
});
if (isArrayNotEmpty(events)) {
executeEventWithoutJS({
eventType: 'onDialogClose',
events,
_context,
position: ButtonPosition.dialogEvent,
recordDataSource: {},
});
}
};
open = (data, config) => {
const { buttonConfig, position } = config || {};
const { options } = buttonConfig || {};
const { openDialogMode } = options || {};
if (buttonConfig) {
this[_buttonConfig] = buttonConfig;
}
if (position) {
this[_buttonPosition] = position;
}
const { _context, _dataSourceName } = this.props;
if (data !== undefined && data !== null) {
if (_context && _dataSourceName) {
_context?.setState({
[_dataSourceName]: data,
});
}
}
if (openDialogMode && _context?.state?.valueOf) {
set(
_context.state.valueOf,
`${_dataSourceName}${__stateValueOfSplit__}openDialogMode`,
openDialogMode,
);
}
return new Promise((resolve) => {
setTimeout(() => {
this.setState({
visible: true,
});
resolve(true);
});
});
};
getUrlParams = () => {
const { _context } = this.props;
return _context?.state?.urlParams || {};
};
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.dialog;
const action = getButtonAction({
...item,
position: ButtonPosition.dialog,
});
const componentDefine = getRunTimeItem(optType);
const getRenderDom = getButtonItem(position, optType, 'getRenderDom');
const btnProps = {
type,
};
if (dialogMode === 'drawer') {
btnProps.size = 'large';
}
const isHidden = executeObjectExpr(
hidden,
{
[__dataSource__]: _context?.state,
},
{},
_context?.state,
);
if (isHidden) {
return null;
}
const isDisabled = executeObjectExpr(
disabled,
{
[__dataSource__]: _context?.state,
},
{},
_context?.state,
);
if (isDisabled === true) {
btnProps.disabled = true;
}
if (componentDefine?.component) {
const component = getRealizeValue(componentDefine.component);
if (component) {
return React.createElement(component, {
...options,
...btnProps,
buttonConfig: item,
dialogRef: this,
_context,
children,
});
}
} else if (typeof getRenderDom === 'function') {
return executeFunction(getRenderDom, {
_context,
buttonConfig: item,
state: _context?.state,
urlParamsDataSource: this.getUrlParams(),
});
}
if (action) {
btnProps.onClick = action.bind(this, {
componentProps: this.props,
buttonConfig: item,
open: this.open,
close: this.close,
dialogRef: this,
position: ButtonPosition.dialog,
state: _context?.state,
urlParamsDataSource: this.getUrlParams(),
_context,
});
}
return (
<CnButton
key={index}
mobileProps={{ fullWidth: true, size: 'large' }}
{...btnProps}
>
{renderIcon(iconType)}
{children}
</CnButton>
);
});
return <>{result}</>;
};
handleChildren = (children) => {
const { _context } = this.props;
return React.Children.map(children, (item) => {
return React.cloneElement(item, {
[_buttonConfig]: this[_buttonConfig],
[_buttonPosition]: this[_buttonPosition],
[_contextConst]: _context,
[_state]: _context?.state,
[_dialogRef]: this,
});
});
};
render() {
let { visible } = this.state;
const {
// 按钮
buttons = [],
children,
dialogMode,
title,
_context,
_dataSourceName,
canCloseByOutSideClick,
handleProps,
...otherProps
} = this.props;
const isDesign = isDesignMode(this.props);
if (isDesign) {
visible = true;
}
// const props = {
// ...otherProps,
// visible,
// footer:this.getButtons(),
// onClose:this.close,
// }
let Component = UICnDialog;
if (dialogMode === 'drawer') {
Component = CnDrawer;
}
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,
});
}
}
}
let componentProps = {
className: 'cn-dialog-alc',
...otherProps,
title: realTitle,
visible,
okProps: { visible: false },
cancelProps: { visible: false },
};
if (typeof handleProps === 'function') {
const tempProps = executeFunction(
handleProps,
{ ...componentProps },
_context?.state,
);
if (isPlainObject(tempProps)) {
componentProps = merge(tempProps, { ...componentProps });
}
}
componentProps.onClose = this.close;
componentProps.footer = this.getButtons();
return (
<Component {...componentProps}>{this.handleChildren(children)}</Component>
);
}
}
CnDialog.displayName = 'CnDialog';
export default CnDialog;
export { CnDialog };