UNPKG

@cainiaofe/cn-ui-lowcode

Version:
550 lines (517 loc) 14.3 kB
import React from 'react'; import { CnTab as UICnTab, CnTabItem as UICnTabItem, CnIcon, } from '@cainiaofe/cn-ui'; import './view.scss'; import isFunction from 'lodash/isFunction'; import { calculateTextExprValue, executeFunction, executeObjectExpr, isDesignMode, isEmptyButNotZero, isRequestConfig, setDataToDs, } from '@/common/util/util'; import { componentMap } from '@/common/manager/event'; import { getRealResponse, makeRequest } from '@/common/util/request'; import isPlainObject from 'lodash/isPlainObject'; import { __dataSource__, __tab_activeKey__, __tab_removeKey__, __tab_addKey__, } from '@/common/util/expr-const'; import { getButtonAction } from '@/common/manager/button'; import { ButtonPosition } from '@/common/manager/position/button-position'; import { CnFilterDefaultValueFinished, CnFilterOnChange, CnFilterOnSearch, emitEvent, onEvent, } from '@/common/util/event-name'; import { dataOriginRequest, dataOriginStatic, } from '@/common/util/const'; import merge from 'lodash/merge'; class CnTab extends React.Component { constructor(props) { super(props); // const activeKey = props.defaultActiveKey; // // const activeItem = this.findItem(activeKey); // this.state = { // activeKey: activeItem?.primaryKey, // }; const defaultActiveKey = this.getDefaultActiveKey(); this.state = { activeKey: defaultActiveKey, itemList: [], }; this.setDataSource({ [__tab_activeKey__]: defaultActiveKey, }); // this.indexesCache = []; } setDataSource = (data) => { if (data) { const { _context, _dataSource, _dataSourceName } = this.props; setDataToDs({ _context, _dataSource, _dataSourceName, data, }); } }; getDefaultActiveKey = () => { const { dataOrigin, items, _context, activeKey } = this.props; if (dataOrigin !== 'request') { let first; if (activeKey) { first = calculateTextExprValue(activeKey, { state: _context?.state, recordDataSource: {}, }); } else { if (Array.isArray(items)) { for (const item of items) { const { primaryKey, hidden } = item; if (primaryKey) { const isHidden = executeObjectExpr( hidden, {}, {}, _context?.state, ); if (isHidden !== true) { first = primaryKey; break; } } } } if (first === undefined) { first = items[0]?.primaryKey; } } return first; } }; getItems = () => { const { items = [] } = this.props; const { itemList = [] } = this.state; const { dataOrigin } = this.props; if (dataOrigin === 'request') { return itemList; } return items; }; getUrlParams = () => { const { _context } = this.props; return _context?.state?.urlParams || {}; }; getData = () => { const isDesign = isDesignMode(this.props); const { dataOrigin, requestConfig, _context } = this.props; if (dataOrigin === 'request' && isRequestConfig(requestConfig)) { return makeRequest({ buttonConfig: { options: { requestConfig, }, }, urlParamsDataSource: this.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, activeKey: originalActiveKey } = data; const state = { itemList: [], }; if (Array.isArray(list) && list.length > 0) { const newList = list.map((item) => { if (isPlainObject(item)) { const { label, value, title, primaryKey, key } = item; if (isEmptyButNotZero(title) && label) { item.title = label; } if (isEmptyButNotZero(primaryKey) && value) { item.primaryKey = value; } if (isEmptyButNotZero(item.primaryKey) && key) { item.primaryKey = key; } } return { ...item }; }); let activeKey = originalActiveKey; if (isEmptyButNotZero(activeKey)) { activeKey = newList[0]?.primaryKey; } state.itemList = newList; if (activeKey !== undefined) { state.activeKey = activeKey; this.setDataSource({ [__tab_activeKey__]: activeKey, }); } } else if (originalActiveKey !== undefined) { state.activeKey = originalActiveKey; this.setDataSource({ [__tab_activeKey__]: originalActiveKey, }); } this.setState(state); this.executeEvent({ eventType: 'onTabRequestFinish', activeKey: state.activeKey, }); } } }); } }; componentDidMount() { const p = this.getData(); const { dataOrigin, requestConfig, _context } = this.props; if (dataOrigin === dataOriginStatic) { setTimeout(() => { emitEvent(CnFilterDefaultValueFinished, { componentProps: this.props, formValues: {}, }); }); } else if (dataOrigin === dataOriginRequest) { if (typeof p?.finally === 'function') { p.finally((res) => { emitEvent(CnFilterDefaultValueFinished, { componentProps: this.props, formValues: {}, }); }); } } onEvent(CnFilterOnChange, (tableInfo) => { this.forceUpdate(); }); } renderTitle(title, props) { const { _customRenderTabItem = () => null, _context } = this.props; if (isFunction(_customRenderTabItem)) { const customTitle = executeFunction( _customRenderTabItem, props, _context?.state, ); if (customTitle) { return customTitle; } } return title; } clickClose(removeKey) { this.setDataSource({ [__tab_removeKey__]: removeKey, }); this.executeEvent({ eventType: 'onTabDeleteItemClick', activeKey: removeKey, }); } clickTab = (tabKey) => { const items = this.getItems(); const current = items.find((item) => { if (item) { return item.primaryKey === tabKey; } }); if (current) { const { optType, url, redirectType } = current; if (optType === 'link' && url && redirectType) { if (redirectType === 'current') { location.href = url; } else if (redirectType === 'open') { window.open(url); } } } }; renderTabItems() { const items = this.getItems(); const { children, _context, dataOrigin, _customRenderTabItem } = this.props; let tabItems; if (dataOrigin === 'request') { if (items.length > 0) { tabItems = items.map((item) => { const { title, primaryKey, disabled, closeable } = item; let realTitle = title; if (typeof _customRenderTabItem === 'function') { const tempTitle = executeFunction( _customRenderTabItem, item, _context?.state, ); if (tempTitle) { realTitle = tempTitle; } } return ( <UICnTabItem title={realTitle} key={primaryKey} disabled={disabled} closeable={closeable} /> ); }); } } else { const isDesign = isDesignMode(this.props); const safeChildren = Array.isArray(children) ? children : [children]; tabItems = safeChildren.map((child, index) => { if (!child) { return null; } let childProps; if (Array.isArray(items) && items[index]) { childProps = items[index]; } else if (child.props.componentSchema) { childProps = child.props.componentSchema.props; } else { childProps = child.props; } const hidden = executeObjectExpr( childProps?.hidden, {}, {}, _context?.state, ); if (hidden === true) { return null; } // const tabContentChildren = child?.props?.children; const title = this.renderTitle(childProps.title, childProps); // let paddingClassName = 'cn-tab-page-content'; // if(isDesign) { // if(tabContentChildren?.[0]?.props?.isCnTab === true) { // paddingClassName = '' // } // }else{ // if(tabContentChildren?.props?.isCnTab === true) { // paddingClassName = '' // } // } return ( <UICnTabItem title={title} key={childProps.primaryKey} disabled={childProps.disabled} closeable={childProps.closeable} > {child} </UICnTabItem> ); }); } return tabItems; } findItem(activeKey) { const items = this.getItems(); let ret; for (let i = 0; i < items.length; i++) { const item = items[i]; if ( activeKey === item.primaryKey || (item.customKey && item.customKey === activeKey) ) { ret = item; break; } } return ret ? { ...ret, customKey: ret.customKey || ret.primaryKey } : null; } setTabActiveKey = (activeKey) => { this.setDataSource({ [__tab_activeKey__]: activeKey, }); this.setState({ activeKey, }); this.executeEvent({ eventType: 'onChange', activeKey, }); emitEvent(CnFilterOnSearch, { componentProps: this.props, payload: {}, }); // const { onTabChange, onChange, fieldId, traceable } = this.props; // const activeItem = this.findItem(activeKey); // const key = activeItem?.customKey; // const changeHandle = onTabChange || onChange; // this.setState( // { // activeKey: activeItem.primaryKey, // }, // () => { // if (isFunction(changeHandle)) { // const activeIndex = this.indexesCache.indexOf(key) + 1; // changeHandle(activeIndex, key, activeItem); // } // }, // ); }; executeEvent = (config) => { const { eventType, activeKey } = config; const { events, _context } = this.props; if (Array.isArray(events) && events.length > 0) { for (const item of events) { const { name: eventName, optType, flowList } = item; if (eventName === eventType) { const action = getButtonAction({ ...item, position: ButtonPosition.tabEvent, }); if (typeof action === 'function') { action({ buttonConfig: { ...item, position: ButtonPosition.tabEvent, options: { ...item, }, }, position: ButtonPosition.tabEvent, state: _context?.state, urlParamsDataSource: this.getUrlParams(), _context, recordDataSource: activeKey, }); } } } } }; addTab() { this.executeEvent({ eventType: componentMap?.onTabAddItemClick?.value, }); } renderTabAdd() { const { addTabOpen, dataOrigin, _context } = this.props; const realIsOpen = dataOrigin === 'request' && (isFunction(addTabOpen) ? executeFunction(addTabOpen, {}, _context?.state) : addTabOpen); return ( realIsOpen && ( <CnTabItem onClick={this.addTab.bind(this)} key='operation' icon={<CnIcon type='add' />} /> ) ); } render() { const { shape, size, excessMode, tabPosition, contentPadding, unmountInactiveTabs, extraRender, tabRender, onClose, // items, children, lazyLoad = true, dataOrigin, className, handleProps, _context, } = this.props; const { activeKey } = this.state; const isDesign = isDesignMode(this.props); const tabProps = { animation: false, shape, size, activeKey, excessMode, tabPosition, unmountInactiveTabs, onClose, lazyLoad, className, }; // if (contentPadding) { // tabProps.contentStyle = { // padding: contentPadding, // }; // } if (isFunction(extraRender)) { tabProps.extra = extraRender(); } if (isFunction(tabRender)) { tabProps.tabRender = tabRender; } if (isDesign && dataOrigin === 'request') { return ( <UICnTab {...tabProps} smartPadding> <UICnTabItem title={'动态Tab,请到预览页面查看'} key={'dynamic_tab'} /> </UICnTab> ); } let realProps = { smartPadding: true, }; if (typeof handleProps === 'function') { const tempProps = executeFunction( handleProps, { ...realProps }, _context?.state, ); if (isPlainObject(tempProps)) { realProps = merge(realProps, tempProps); } } return ( <UICnTab onChange={this.setTabActiveKey} {...tabProps} onClick={this.clickTab} onClose={this.clickClose.bind(this)} {...realProps} > {this.renderTabItems()} {this.renderTabAdd()} </UICnTab> ); } } CnTab.displayName = 'CnTab'; class CnTabItem extends React.Component { static displayName = 'CnTabItem'; render() { return <>{this.props.children}</>; } } export default [CnTab, CnTabItem]; export { CnTab, CnTabItem };