UNPKG

@cainiaofe/cn-ui-lowcode

Version:
438 lines (416 loc) 11.8 kB
import React, { useCallback, useEffect, useState, forwardRef, useImperativeHandle, } from 'react'; import { CnStep as UICnStep, CnStepItem, Box, CnButton, } from '@cainiaofe/cn-ui'; import { calculateTextExprValue, executeFunction, executeObjectExpr, isArrayNotEmpty, isDesignMode, isEmptyButNotZero, isRequestConfig, setDataToDs, } from '@/common/util/util'; import { getButtonAction, getItem as getButtonItem, } from '@/common/manager/button'; import { ButtonPosition } from '@/common/manager/position/button-position'; import isPlainObject from 'lodash/isPlainObject'; import { __dataSource__, __step_activeKey__, __step_current__, __step_currentItem__, __step_list__, } from '@/common/util/expr-const'; import { dataOriginRequest } from '@/common/util/const'; import { getRealResponse, makeRequest } from '@/common/util/request'; const CnStep = forwardRef((props, ref) => { if (!UICnStep) { return null; } useImperativeHandle(ref, () => ({ changeStep(...arg) { changeStep(...arg); }, load(...arg) { load(arg); }, })); const { steps: propSteps, stepStyle, current: propsCurrent, leftButtons, rightButtons, _dataSource, _dataSourceName, _context, dataOrigin, requestConfig, events, } = props; const isDesign = isDesignMode(props); const findCurrent = (list, tempCurrent) => { let result = tempCurrent; if (typeof tempCurrent === 'number') { } else { const tempActiveKey = calculateTextExprValue(tempCurrent, { state: _context?.state, recordDataSource: {}, }); if (typeof tempActiveKey === 'number') { result = tempActiveKey; } else { if (typeof result === 'function') { result = undefined; } for (const index in list) { const item = list[index]; const { key } = item || {}; if (key === tempActiveKey) { result = +index; break; } } } } return result; }; const filterHiddenStep = (list) => { const result = []; if (Array.isArray(list)) { list.forEach((item) => { const { hidden } = item || {}; const isHidden = executeObjectExpr(hidden, {}, {}, _context?.state); if (isHidden !== true) { result.push(item); } }); } return result; }; let initialSteps = filterHiddenStep(propSteps); if (dataOrigin === dataOriginRequest) { initialSteps = []; } const [steps, setSteps] = useState(initialSteps); const [current, setCurrent] = useState(findCurrent(steps, propsCurrent)); useEffect(() => { if (dataOrigin !== dataOriginRequest) { setSteps(filterHiddenStep(propSteps)); } }, [propSteps]); useEffect(() => { if (dataOrigin !== dataOriginRequest) { setCurrent(findCurrent(steps, propsCurrent)); } }, [propsCurrent]); const executeEvent = (config) => { const { eventType } = config || {}; const { events } = props; if (isArrayNotEmpty(events)) { for (const item of events) { const { name: eventName } = item || {}; if (eventName === eventType) { const action = getButtonAction({ ...item, position: ButtonPosition.stepEvent, }); if (typeof action === 'function') { action({ buttonConfig: { ...item, position: ButtonPosition.stepEvent, options: { ...item, }, }, position: ButtonPosition.stepEvent, state: _context?.state, urlParamsDataSource: _context?.state?.urlParams || {}, _context, recordDataSource: {}, }); } } } } }; const getActiveKeyByIndex = (list, index) => { if (typeof index === 'number' && isArrayNotEmpty(list)) { const temp = list[index]; if (temp?.key) { return temp.key; } } }; const changeStep = (newIndex, config) => { const { needSetState } = config || {}; let realIndex; if (typeof newIndex === 'number') { realIndex = newIndex; } else { realIndex = findCurrent(steps, newIndex); } if (typeof realIndex === 'number') { if (needSetState) { setCurrent(realIndex); } setDataToDs({ _context, _dataSource, _dataSourceName, data: { [__step_current__]: realIndex, [__step_activeKey__]: getActiveKeyByIndex(steps, newIndex), [__step_currentItem__]: steps[newIndex] || {}, }, }); setTimeout(() => { executeEvent({ eventType: 'onStepItemClick', }); }); } }; const handleStep = (steps) => { if (isDesign && dataOrigin === dataOriginRequest) { return [ <CnStepItem key={'unique'} title={'动态Step请到预览页面查看'} />, ]; } const result = []; if (Array.isArray(steps) && steps.length > 0) { steps.forEach((item, index) => { const { title, content, key, ...rest } = item; if (key) { result.push( <CnStepItem {...rest} key={index} title={title} content={content} onClick={changeStep} />, ); } }); } return result; }; const handleButtons = useCallback((leftButtons, rightButtons) => { function handle(buttons) { if (Array.isArray(buttons) && buttons.length > 0) { const result = []; buttons.forEach((item) => { const { children, disabled, hidden, optType, type } = item || {}; const action = getButtonAction({ ...item, position: ButtonPosition.step, }); const getRenderDom = getButtonItem( ButtonPosition.step, optType, 'getRenderDom', ); const isDisabled = executeObjectExpr( disabled, { [__step_current__]: current, [__dataSource__]: _context?.state, }, current, _context?.state, ); const isHidden = executeObjectExpr( hidden, { [__step_current__]: current, [__dataSource__]: _context?.state, }, current, _context?.state, ); if (isHidden !== true) { if (typeof getRenderDom === 'function') { result.push( executeFunction(getRenderDom, { _context, buttonConfig: item, state: _context?.state, urlParamsDataSource: _context?.state?.urlParams || {}, }), ); } else { result.push( <CnButton type={type} disabled={isDisabled} onClick={() => { if (typeof action === 'function') { action({ buttonConfig: item, state: _context?.state, urlParamsDataSource: _context?.state?.urlParams || {}, _context, position: ButtonPosition.step, }); } }} size={'large'} > {children} </CnButton>, ); } } }); if (result.length > 0) { return ( <Box // className="cn-ui-form-footer-footer" style={{ alignItems: 'center' }} spacing={8} direction='row' > {result} </Box> ); } } } const leftSlot = handle(leftButtons); const rightSlot = handle(rightButtons); if (leftSlot || rightSlot) { return { hasCnPageFooter: true, cnPageFooterProps: { leftSlot, rightSlot, }, }; } }, []); const stepProps = { ...stepStyle, current, ...handleButtons(leftButtons, rightButtons), }; const getUrlParams = () => { return _context?.state?.urlParams || {}; }; const load = () => { if (dataOrigin === dataOriginRequest) { let realSteps; let realCurrent; if (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 (isPlainObject(data)) { const { list: originList, activeKey: originalActiveKey } = data; const list = filterHiddenStep(originList); if (isArrayNotEmpty(list)) { let tempCurrent; const newList = []; if (typeof originalActiveKey === 'number') { tempCurrent = originalActiveKey; } for (const index in list) { const { label, value, title, key } = list[index]; const realKey = key || value; if ( typeof originalActiveKey === 'string' && originalActiveKey === realKey ) { tempCurrent = +index; } const temp = { ...list[index], title: label || title, key: realKey, }; if (title) { temp.title = title; } newList.push(temp); } if (isEmptyButNotZero(tempCurrent)) { tempCurrent = 0; } realSteps = newList; realCurrent = tempCurrent; setDataToDs({ _context, _dataSource, _dataSourceName, data: { [__step_list__]: newList, [__step_current__]: tempCurrent, [__step_activeKey__]: getActiveKeyByIndex( newList, tempCurrent, ), [__step_currentItem__]: newList[tempCurrent] || {}, }, }); } } } }) .finally(() => { setSteps(realSteps); setCurrent(realCurrent); }); } } }; useEffect(() => { if (dataOrigin === dataOriginRequest) { load(); } else { setDataToDs({ _context, _dataSource, _dataSourceName, data: { [__step_list__]: steps, [__step_current__]: current, [__step_activeKey__]: getActiveKeyByIndex(steps, current), }, }); } }, []); return ( <div className=''> <UICnStep {...stepProps}>{handleStep(steps)}</UICnStep> </div> ); }); CnStep.displayName = 'CnStep'; export default CnStep;