UNPKG

@cainiaofe/cn-ui-lowcode

Version:
429 lines (405 loc) 12.8 kB
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 };