UNPKG

@cainiaofe/cn-ui-lowcode

Version:
305 lines (291 loc) 7.87 kB
import React from 'react'; import { Box, CnAsyncTree } from '@cainiaofe/cn-ui'; import { handleSelectRequestConfig, isArrayNotEmpty, isDesignMode, makeButtons, mergeHandleProps, setDataToDs, } from '@/common/util/util'; import { getButtonAction } from '@/common/manager/button'; import { ButtonPosition } from '@/common/manager/position/button-position'; import { __left_tree_currentItem__, __left_tree_currentValue__, __stateValueOfSplit__, } from '@/common/util/expr-const'; import cloneDeep from 'lodash/cloneDeep'; import get from 'lodash/get'; import isPlainObject from 'lodash/isPlainObject'; class CnLeftTree extends React.Component { constructor(props) { super(props); this.remoteInstance = CnAsyncTree?.createRemoteInstance?.(); this.treeRef = null; } getUrlParams = () => { const { _context } = this.props; return _context?.state?.urlParams || {}; }; load = () => { const p = this.remoteInstance?.load?.(); if (typeof p?.then === 'function') { p.then((res) => { this.refreshCurrentItem(); }); } }; refreshCurrentItem = () => { const { _context, _dataSourceName } = this.props; const currentItem = _context?.state?.[_dataSourceName]?.[__left_tree_currentItem__]; if (currentItem && isArrayNotEmpty(this.treeRef?.dataSource)) { const { pos } = currentItem; if (typeof pos === 'string') { const path = pos?.slice(2)?.replaceAll('-', '-children-')?.split('-'); const newCurrent = get(this.treeRef?.dataSource, path); if (newCurrent && newCurrent?.value === currentItem?.value) { this.setDataSource({ [__left_tree_currentItem__]: newCurrent, }); } } } }; makeButtons = () => { const { treeNodeButtons, _context } = this.props; if (isArrayNotEmpty(treeNodeButtons)) { return makeButtons({ buttons: treeNodeButtons.map((item) => { return { ...item, position: ButtonPosition.treeNode, text: true, type: 'primary', style: { marginLeft: '5px', }, }; }), _context, state: _context?.state, urlParamsDataSource: this.getUrlParams(), recordDataSource: {}, }); } }; setDataSource = (data) => { if (data) { const { _context, _dataSource, _dataSourceName } = this.props; setDataToDs({ _context, _dataSource, _dataSourceName, data, }); } }; executeEvent = (config) => { const { eventType, afterDropDataSource } = config; const { events, _context } = this.props; if (isArrayNotEmpty(events)) { for (const item of events) { const { name: eventName } = item; if (eventName === eventType) { const action = getButtonAction({ ...item, position: ButtonPosition.treeEvent, }); if (typeof action === 'function') { action({ buttonConfig: { ...item, position: ButtonPosition.treeEvent, options: { ...item, }, }, position: ButtonPosition.treeEvent, state: _context?.state, urlParamsDataSource: this.getUrlParams(), _context, recordDataSource: {}, getExtraParam: () => { return { afterDropDataSource, }; }, }); } } } } }; onDrop = (info) => { const { dragNode } = info || {}; if (!dragNode) { return; } if (isArrayNotEmpty(this.treeRef?.dataSource)) { const dragKey = info.dragNode?.props?.eventKey; const dropKey = info.node?.props?.eventKey; const { dropPosition } = info; const loop = (data, key, callback) => { data.forEach((item, index, arr) => { if (item.key === key) { return callback(item, index, arr); } if (item.children) { return loop(item.children, key, callback); } }); }; const data = cloneDeep(this.treeRef?.dataSource); let dragObj; loop(data, dragKey, (item, index, arr) => { arr.splice(index, 1); dragObj = item; }); if (info.dropPosition === 0) { loop(data, dropKey, (item) => { item.children = item.children || []; item.children.push(dragObj); }); } else { let ar; let i; loop(data, dropKey, (item, index, arr) => { ar = arr; i = index; }); if (dropPosition === -1) { ar.splice(i, 0, dragObj); } else { ar.splice(i + 1, 0, dragObj); } } if (isArrayNotEmpty(data)) { this.executeEvent({ eventType: 'onDrop', afterDropDataSource: data, }); } } }; render() { const extraProps = {}; const isDesign = isDesignMode(this.props); const urlParamsDataSource = this.getUrlParams(); const { children, _context, title, _dataSource, _dataSourceName, dataOrigin, requestConfig, treeStyle, handleProps, defaultParams, ...rest } = this.props; const { draggable } = treeStyle || {}; if (draggable === true) { extraProps.onDrop = this.onDrop; } const tempConfig = { componentProps: { requestConfig, dataOrigin, }, urlParamsDataSource, recordDataSource: {}, state: _context?.state, handleDynamicUrl: true, }; handleSelectRequestConfig(tempConfig, { dynamicParams: true }); if (isDesign) { extraProps.defaultExpandAll = true; extraProps.dataSource = [ { label: '树节点示例', value: 'tree1', children: [ { label: '子节点示例', value: 'sub1', }, ], }, ]; } else { extraProps.instance = this.remoteInstance; extraProps.requestConfig = tempConfig?.componentProps?.requestConfig; } let realComponentProps = { ...treeStyle, selectable: true, ...rest, ...(defaultParams || {}), }; const temp = mergeHandleProps({ handleProps, componentProps: realComponentProps, _context, }); if (isPlainObject(temp)) { realComponentProps = temp; } let rightDom = ( <div style={{ flex: 3, height: '100%', overflow: 'auto', borderLeft: '1px solid #e5e5e5', }} className='' > {children} </div> ); if (!isDesign && !children) { rightDom = null; } return ( <div className=''> <Box spacing={12} direction='row'> <div style={{ flex: 1, maxWidth: '288px', }} > <CnAsyncTree ref={(c) => (this.treeRef = c)} {...extraProps} treeArea={() => { return this.makeButtons(); }} onChange={(key, item) => { this.setDataSource({ [__left_tree_currentValue__]: key, [__left_tree_currentItem__]: item, }); this.executeEvent({ eventType: 'onChange', }); }} {...realComponentProps} /> </div> {rightDom} </Box> </div> ); } } CnLeftTree.displayName = 'CnLeftTree'; export default CnLeftTree; export { CnLeftTree };