@cainiaofe/cn-ui-lowcode
Version:
429 lines (405 loc) • 12.8 kB
JavaScript
import React, { useEffect, useState, useCallback, useImperativeHandle, forwardRef } from 'react';
import { CnPage as UICnPage, CnBox } from '@cainiaofe/cn-ui';
import { getButtonAction } from '@/common/manager/button';
import { ButtonPosition } from '@/common/manager/position/button-position';
import {
getRealResponse,
handleResultProcessFunc,
makeRequest,
} from '@/common/util/request';
import {
calculateTextExprValue,
calculateUrl,
clearState,
executeFlowList,
isArrayNotEmpty,
isDesignMode,
isRequestConfig,
makeButtons,
getPermissionGranted,
handleSelectDataSource,
handlePageDataSource,
executeFunction,
} from '@/common/util/util';
import {
CnPageForceUpdate,
CnPageRequestFinish,
emitEvent,
onEvent,
} from '@/common/util/event-name';
import { __permissionGranted__ } from '@/common/util/expr-const';
import set from 'lodash/set';
import isPlainObject from 'lodash/isPlainObject';
import merge from 'lodash/merge';
import { dataOriginStatic } from '@/common/util/const';
const CnPage = forwardRef((props, ref) => {
const {
children,
componentDidMount,
_context,
cnBreadcrumbDataSource,
breadcrumb = {},
action: originalAction,
title,
handleProps,
...otherProps
} = props;
useImperativeHandle(ref, () => ({
doMakeAction
}))
if (!_context?.state.valueOf.__permissionGranted__) {
set(_context?.state.valueOf, __permissionGranted__, getPermissionGranted());
}
const getUrlParams = () => {
return _context?.state?.urlParams || {};
};
const isDesign = isDesignMode(props);
const { dataOrigin, requestConfig } = breadcrumb;
const [action, setAction] = useState();
const getBreadcrumbData = useCallback((originalBreadcrumb) => {
let result;
if (originalBreadcrumb) {
const { dataSource, dataOrigin: bDataOrigin } = originalBreadcrumb;
if (bDataOrigin === 'static') {
if (Array.isArray(dataSource) && dataSource?.length > 0) {
const urlParams = getUrlParams();
result = dataSource.map((item) => {
const { children, link } = item || {};
const url = calculateUrl(link, {
urlParamsDataSource: urlParams,
recordDataSource: {},
state: _context?.state,
});
const temp = {
children,
};
if (url) {
temp.link = url;
}
return temp;
});
} else if (typeof dataSource === 'function') {
try {
const temp = dataSource();
if (Array.isArray(temp)) {
result = temp;
}
} catch (e) {}
}
}
}
if (!result) {
result = cnBreadcrumbDataSource;
}
return result;
}, []);
const [breadcrumbResult, setBreadcrumbResult] = useState(
getBreadcrumbData(breadcrumb) || [],
);
const [forceUpdate, setForceUpdate] = useState(false);
// 最后一个阻塞页面渲染的请求名称
let lastDeferRequest;
if (componentDidMount && componentDidMount.requestList?.length > 0) {
for (const req of componentDidMount.requestList) {
if (req?.name && req?.deferPageRender && req?.isAsync !== true) {
lastDeferRequest = req.name;
}
}
}
const needDefer = !!lastDeferRequest && !isDesign;
const [deferRender, setDeferRender] = useState(needDefer);
const executeActionList = () => {
if (!isDesign) {
const { actionList } = componentDidMount || {};
executeFlowList({
list: actionList,
_context,
position: ButtonPosition.pageDidMount,
}).finally((res) => {
clearState({ _context });
doMakeAction()
});
}
};
function doMakeAction() {
const tempAction = makeAction();
if (tempAction) {
setAction(tempAction);
}
}
const executeActionListAfterAsyncRequest = (actionList) => {
if (!isDesign && actionList?.length > 0) {
executeFlowList({
list: actionList,
_context,
position: ButtonPosition.pageAsyncRequestComplete,
}).finally((res) => {
clearState({ _context });
});
}
};
useEffect(() => {
if (isDesign) {
document.addEventListener(
'click',
(e) => {
setTimeout(() => {
const target = e?.target;
const clsName = e?.target?.className;
const sel =
window?.AliLowCodeEngine?.project?.currentDocument?.selection;
if (
['CnForm', 'CnFilter', 'CnFormDialog'].includes(
sel?.node?.componentName,
)
) {
const allFormItem = document.querySelectorAll(`.l2-cn-form-item`);
for (let item of allFormItem) {
item.style.border = 'none';
}
}
if (clsName?.includes?.('l2-cn-form-item')) {
const index = clsName.slice(
clsName.indexOf('l2-cn-form-item-') + 16,
);
const ele = window?.parent?.document.querySelector(
`div.lc-setter-list-card[data-id="${index}"]`,
);
const button =
ele?.children?.[0]?.children?.[0]?.children?.[0]?.children?.[0]
?.children?.[0]?.children?.[0];
if (button) {
target.style.border = '1px solid #006cff';
button?.click();
}
}
}, 50);
},
true,
);
}
}, []);
useEffect(() => {
onEvent(CnPageForceUpdate, () => {
setForceUpdate(Date.now());
setBreadcrumbResult(getBreadcrumbData(breadcrumb));
});
(async () => {
if (componentDidMount) {
const { requestList = [] } = componentDidMount;
if (requestList?.length > 0) {
let needForceUpdate = false;
for (const item of requestList) {
const {
name,
requestConfig,
dataOrigin,
dataSource,
isAsync,
asyncCompleteActionList,
} = item;
if (name) {
if (dataOrigin === dataOriginStatic) {
const tempP = {
dataOrigin,
dataSource,
};
handlePageDataSource({
componentProps: tempP,
state: _context?.state,
});
if (
tempP.dataSource !== undefined &&
tempP.dataSource !== null
) {
needForceUpdate = true;
_context?.setState({
[name]: tempP.dataSource,
});
}
} else if (requestConfig) {
try {
const buttonConfig = {
optType: 'request',
position: ButtonPosition.pageDidMount,
options: {
requestConfig,
},
};
const action = getButtonAction(buttonConfig);
if (isAsync) {
action?.({
position: ButtonPosition.pageDidMount,
urlParamsDataSource: getUrlParams(),
// recordDataSource: newFormValue,
state: _context?.state,
buttonConfig,
_context,
needSuccessToast: false,
noNeedHandleResult: true,
isDesign,
}).then((result) => {
const resultProcessFunc =
handleResultProcessFunc(requestConfig);
if (typeof resultProcessFunc === 'function') {
result = resultProcessFunc(result, _context?.state);
}
if (result !== null && result !== undefined) {
needForceUpdate = true;
_context?.setState({
[name]: result,
});
emitEvent(CnPageRequestFinish, {});
executeActionListAfterAsyncRequest(
asyncCompleteActionList,
);
}
});
} else {
let result = await action?.({
position: ButtonPosition.pageDidMount,
urlParamsDataSource: getUrlParams(),
// recordDataSource: newFormValue,
state: _context?.state,
buttonConfig,
_context,
needSuccessToast: false,
noNeedHandleResult: true,
isDesign,
});
const resultProcessFunc =
handleResultProcessFunc(requestConfig);
if (typeof resultProcessFunc === 'function') {
result = resultProcessFunc(result, _context?.state);
}
if (result !== null && result !== undefined) {
needForceUpdate = true;
_context?.setState({
[name]: result,
});
}
}
} catch (e) {
console.log(`${name} 的请求执行异常`, e);
}
if (deferRender && name === lastDeferRequest) {
setDeferRender(false);
}
}
}
}
if (needForceUpdate) {
setForceUpdate(true);
}
emitEvent(CnPageRequestFinish, {});
setTimeout(() => {
executeActionList();
});
} else {
executeActionList();
}
} else {
doMakeAction()
}
})();
if (breadcrumb) {
if (dataOrigin === 'request' && isRequestConfig(requestConfig)) {
makeRequest({
buttonConfig: {
options: {
requestConfig,
},
},
urlParamsDataSource: getUrlParams(),
recordDataSource: {},
state: _context?.state || {},
needSuccessToast: false,
isDesign,
}).then((res) => {
const res2 = getRealResponse(res);
const { success, data } = res2;
if (success) {
if (Array.isArray(data) && data?.length > 0) {
setBreadcrumbResult(data);
}
}
});
}
}
}, []);
const makeAction = useCallback(() => {
if (isArrayNotEmpty(originalAction)) {
return (
<CnBox spacing={8} direction='row' align={'center'}>
{makeButtons({
buttons: originalAction?.map((item) => {
return {
...item,
// style: { marginLeft: '8px' },
position: ButtonPosition.pageRightButton,
};
}),
_context,
state: _context?.state,
urlParamsDataSource: getUrlParams(),
recordDataSource: {},
})}
</CnBox>
);
}
}, [originalAction]);
useEffect(() => {
if (isDesign) {
const result = getBreadcrumbData(breadcrumb);
setBreadcrumbResult(result);
}
}, [breadcrumb]);
useEffect(() => {
if (isDesign) {
const tempAction = makeAction();
if (tempAction) {
setAction(tempAction);
}
}
}, [originalAction]);
let realBreadcrumbResult;
if (isArrayNotEmpty(breadcrumbResult)) {
realBreadcrumbResult = breadcrumbResult;
}
let realTitle = calculateTextExprValue(title, {
state: _context?.state,
recordDataSource: {},
});
if (isDesign) {
if (title === undefined) {
realTitle = 'js表达式标题';
}
}
const extraProps = {};
if (dataOrigin === 'useStandard') {
extraProps.cnBreadcrumbProps = {
useStandard: true,
};
}
let componentProps = {
title: realTitle,
action,
...otherProps,
cnBreadcrumbDataSource: realBreadcrumbResult,
...extraProps,
};
if (typeof handleProps === 'function') {
const tempProps = executeFunction(
handleProps,
{ ...componentProps },
_context?.state,
);
if (isPlainObject(tempProps)) {
componentProps = merge(tempProps, { ...componentProps });
}
}
return <UICnPage {...componentProps}>{!deferRender && children}</UICnPage>;
});
CnPage.displayName = 'CnPage';
export default CnPage;
export { CnPage };