king
2022-08-08 176c6e1da22e96a1110fa91f8fc8eb8ad2881e08
src/menu/components/tabs/antv-tabs/index.jsx
@@ -1,35 +1,40 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Tabs, Icon, Popover, Modal } from 'antd'
import { Tabs, Popover, Modal } from 'antd'
import { PlusOutlined, CloseOutlined, EditOutlined, DeleteOutlined, FontColorsOutlined, ToolOutlined } from '@ant-design/icons'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import MkIcon from '@/components/mk-icon'
import DraggableTabs from './dragabletabs'
import { resetStyle } from '@/utils/utils-custom.js'
import MenuUtils from '@/utils/utils-custom.js'
import Utils from '@/utils/utils.js'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import { getTabForm, getTabsSetForm } from './options'
import './index.scss'
const SettingComponent = asyncComponent(() => import('../tabsetting'))
const TabLabelComponent = asyncComponent(() => import('../tablabelform'))
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('../paste'))
const TabComponents = asyncComponent(() => import('../tabcomponents'))
const { TabPane } = Tabs
const { confirm } = Modal
class antvBarLineChart extends Component {
class antvTabs extends Component {
  static propTpyes = {
    menu: PropTypes.object,
    tabs: PropTypes.object,
    deletecomponent: PropTypes.func,
    updateConfig: PropTypes.func,
  }
  state = {
    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    appType: sessionStorage.getItem('appType'),
    tabs: null,
    editab: null,
    labelvisible: false
    defaultActiveKey: ''
  }
  UNSAFE_componentWillMount () {
@@ -39,21 +44,27 @@
      let _tabs = {
        uuid: tabs.uuid,
        type: tabs.type,
        floor: tabs.floor,
        tabId: tabs.tabId || '',
        parentId: tabs.parentId || '',
        subtype: tabs.subtype,
        setting: {span: 12, position: 'top', tabStyle: 'line', name: tabs.name},
        width: 24,
        name: tabs.name,
        setting: {width: 24, position: 'top', tabStyle: 'line', name: tabs.name},
        style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' },
        subtabs: [
          { uuid: Utils.getuuid(), label: 'Tab 1', icon: '', components: [] },
          { uuid: Utils.getuuid(), label: 'Tab 2', icon: '', components: [] },
          { uuid: Utils.getuuid(), label: 'Tab 3', icon: '', components: [] }
          { uuid: Utils.getuuid(), parentId: tabs.uuid, label: 'Tab 1', icon: '', components: [] },
          { uuid: Utils.getuuid(), parentId: tabs.uuid, label: 'Tab 2', icon: '', components: [] },
          { uuid: Utils.getuuid(), parentId: tabs.uuid, label: 'Tab 3', icon: '', components: [] }
        ]
      }
      this.setState({
        defaultActiveKey: _tabs.subtabs[0].uuid,
        tabs: _tabs
      })
      this.props.updateConfig(_tabs)
    } else {
      this.setState({
        defaultActiveKey: window.GLOB.TabsMap.get(tabs.uuid) || '',
        tabs: fromJS(tabs).toJS()
      })
    }
@@ -63,13 +74,97 @@
    return !is(fromJS(this.state), fromJS(nextState))
  }
  componentDidMount () {
    MKEmitter.addListener('submitStyle', this.getStyle)
    MKEmitter.addListener('submitSearch', this.getSearch)
    MKEmitter.addListener('tabsChange', this.handleTabsChange)
    MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle)
  }
  /**
   * @description 组件销毁,清除state更新,清除快捷键设置
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('submitStyle', this.getStyle)
    MKEmitter.removeListener('submitSearch', this.getSearch)
    MKEmitter.removeListener('tabsChange', this.handleTabsChange)
    MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle)
  }
  updateComponentStyle = (parentId, keys, style) => {
    const { tabs } = this.state
    if (tabs.subtabs.findIndex(tab => tab.uuid === parentId) === -1) return
    let _tabs = fromJS(tabs).toJS()
    let _tabs_ = fromJS(tabs).toJS()
    let components = []
    _tabs.subtabs.forEach(tab => {
      if (tab.uuid === parentId) {
        components = tab.components.map(item => {
          if (keys.includes(item.uuid)) {
            item.style = {...item.style, ...style}
          }
          return item
        })
        tab.components = []
      }
    })
    _tabs_.subtabs = _tabs_.subtabs.map(tab => {
      if (tab.uuid === parentId) {
        tab.components = components
      }
      return tab
    })
    this.setState({tabs: _tabs}, () => {
      this.updateComponent(_tabs_)
    })
  }
  changeStyle = () => {
    const { tabs } = this.state
    MKEmitter.emit('changeStyle', [tabs.uuid], ['background', 'border', 'padding', 'margin', 'shadow'], tabs.style)
  }
  getStyle = (comIds, style) => {
    const { tabs } = this.state
    if (comIds.length !== 1 || comIds[0] !== tabs.uuid) return
    let _card = {...tabs, style}
    this.setState({
      tabs: _card
    })
    this.props.updateConfig(_card)
  }
  handleTabsChange = (parentId) => {
    const { tabs } = this.state
    if (parentId === tabs.parentId) {
      MKEmitter.emit('tabsChange', tabs.uuid)
    }
  }
  updateComponent = (component) => {
    const { tabs } = this.state
    if (!is(fromJS(tabs.setting), fromJS(component.setting))) {
    if (!is(fromJS(tabs.setting), fromJS(component.setting)) || !is(fromJS(tabs.style), fromJS(component.style))) {
      // 注册事件-标签变化,通知标签内元素
      MKEmitter.emit('tabsChange', tabs.uuid)
    }
    component.width = component.setting.width
    component.name = component.setting.name
    this.setState({
      tabs: component
@@ -92,61 +187,13 @@
    this.props.updateConfig(tabs)
  }
  tabAdd = (e) => {
    e.stopPropagation()
    this.setState({
      editab: {
        uuid: '',
        label: '',
        icon: '',
        components: []
      },
      labelvisible: true
    })
  }
  editTab = (tab) => {
    this.setState({
      editab: tab,
      labelvisible: true
    })
  }
  tabLabelSubmit = () => {
    let tabs = fromJS(this.state.tabs).toJS()
    let editab = fromJS(this.state.editab).toJS()
    this.tabLabelRef.handleConfirm().then(res => {
      editab.label = res.label
      editab.icon = res.icon
      if (editab.uuid) {
        tabs.subtabs = tabs.subtabs.map(t => {
          if (t.uuid === editab.uuid) {
            return editab
          } else {
            return t
          }
        })
      } else {
        editab.uuid = Utils.getuuid()
        tabs.subtabs.push(editab)
      }
      this.setState({
        editab: null,
        labelvisible: false,
        tabs
      })
      this.props.updateConfig(tabs)
    })
  }
  delTab = (tab) => {
    let tabs = fromJS(this.state.tabs).toJS()
    const _this = this
    tabs.subtabs = tabs.subtabs.filter(t => t.uuid !== tab.uuid)
    let uuids = MenuUtils.getDelButtonIds({...tab, type: 'group'})
    confirm({
      title: '确定删除标签?',
@@ -154,65 +201,207 @@
      onOk() {
        _this.setState({tabs})
        _this.props.updateConfig(tabs)
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
      },
      onCancel() {}
    })
  }
  moveSwitch = (index, index1) => {
  moveSwitch = (order) => {
    let tabs = fromJS(this.state.tabs).toJS()
    tabs.subtabs[index] = tabs.subtabs.splice(index1, 1, tabs.subtabs[index])[0]
    let subtab = {}
    tabs.subtabs.forEach(item => {
      subtab[item.uuid] = item
    })
    tabs.subtabs = []
    order.forEach(item => {
      if (subtab[item]) {
        tabs.subtabs.push(subtab[item])
      }
    })
    this.setState({tabs})
    this.props.updateConfig(tabs)
  }
  insert = (item, tab) => {
    let tabs = fromJS(this.state.tabs).toJS()
    tabs.subtabs.forEach(stab => {
      if (stab.uuid === tab.uuid) {
        stab.components.push(item)
      }
    })
    this.setState({tabs})
    this.props.updateConfig(tabs)
  }
  getSearch = (config) => {
    const { tabs } = this.state
    if (tabs.uuid !== config.uuid) return
    let _tabs = fromJS(tabs).toJS()
    _tabs.subtabs = _tabs.subtabs.map(t => {
      if (t.uuid === config.tabId) {
        t.search = config.search
      }
      return t
    })
    this.setState({
      tabs: _tabs
    })
    this.props.updateConfig(_tabs)
  }
  setSearch = (tab) => {
    const { tabs } = this.state
    let card = {
      uuid: tabs.uuid,
      tabId: tab.uuid,
      search: tab.search
    }
    if (!card.search) {
      card.search = {
        floor: 1,
        setting: { type: 'title', field: '', title: '', focus: 'true', btn: 'hidden' },
        groups: [],
        fields: []
      }
    }
    MKEmitter.emit('changeSearch', card)
  }
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
      MKEmitter.emit('clickComponent', this.state.tabs)
    }
  }
  getTabForms = (tab) => {
    const { tabs } = this.state
    if (!tab) {
      tab = {
        uuid: '',
        parentId: tabs.uuid,
        label: '',
        icon: '',
        components: []
      }
    }
    this.setState({
      editab: tab
    })
    return getTabForm(tab, tabs.setting)
  }
  updateTab = (res) => {
    let tabs = fromJS(this.state.tabs).toJS()
    let editab = fromJS(this.state.editab).toJS()
    editab.label = res.label
    editab.icon = res.icon
    // editab.hasSearch = res.hasSearch || ''
    editab.hide = res.hide || 'false'
    editab.backgroundColor = res.backgroundColor
    editab.controlVal = res.controlVal || ''
    editab.selectVal = res.selectVal || ''
    editab.blacklist = res.blacklist
    if (editab.uuid) {
      tabs.subtabs = tabs.subtabs.map(t => {
        if (t.uuid === editab.uuid) {
          return editab
        } else {
          return t
        }
      })
    } else {
      editab.uuid = Utils.getuuid()
      tabs.subtabs.push(editab)
    }
    this.setState({
      editab: null,
      tabs
    })
    this.props.updateConfig(tabs)
  }
  getTabsForms = () => {
    const { tabs } = this.state
    return getTabsSetForm(tabs.setting, tabs.uuid)
  }
  updateTabs = (res) => {
    this.updateComponent({...this.state.tabs, setting: res})
  }
  onChange = (key) => {
    const { tabs } = this.state
    window.GLOB.TabsMap.set(tabs.uuid, key)
  }
  render() {
    const { menu } = this.props
    const { tabs, dict, labelvisible, editab } = this.state
    const { tabs, defaultActiveKey } = this.state
    let _style = resetStyle(tabs.style)
    return (
      <div className="menu-tabs-edit-box">
        <SettingComponent config={tabs} updateConfig={this.updateComponent} />
        <Tabs defaultActiveKey="1" tabPosition={tabs.setting.position} type={tabs.setting.tabStyle}>
          {tabs.subtabs.map((tab, index) => (
      <div className={'menu-tabs-edit-box ' + (tabs.setting.display || '')} style={_style} onClick={this.clickComponent} id={tabs.uuid}>
        <DraggableTabs defaultActiveKey={defaultActiveKey} tabBarStyle={{background: tabs.setting.backgroundColor || 'transparent'}} tabPosition={tabs.setting.position} type={tabs.setting.tabStyle} tabsMove={this.moveSwitch} onChange={this.onChange}>
          {tabs.subtabs.map(tab => (
            <TabPane tab={
              <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
                <div className="mk-popover-control">
                  <Icon className="edit" title="edit" type="edit" onClick={() => this.editTab(tab)} />
                  {index !== 0 ? <Icon className="edit" type="arrow-left" onClick={() => this.moveSwitch(index, index - 1)} /> : null}
                  {(index + 1) !== tabs.subtabs.length ? <Icon className="edit" type="arrow-right" onClick={() => this.moveSwitch(index, index + 1)} /> : null}
                  <Icon className="close" title="delete" type="close" onClick={() => this.delTab(tab)} />
                  <NormalForm title="标签编辑" width={800} update={this.updateTab} getForms={() => this.getTabForms(tab)}>
                    <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
                  </NormalForm>
                  <PasteComponent Tab={tab} insert={this.insert} />
                  <CloseOutlined className="close" onClick={() => this.delTab(tab)} />
                </div>
              } trigger="hover">
                <span>{tab.icon ? <Icon type={tab.icon} /> : null}{tab.label}</span>
                <span style={{textDecoration: tab.hide === 'true' ? 'line-through' : 'none'}}>{tab.icon ? <MkIcon type={tab.icon} /> : null}{tab.label}</span>
              </Popover>
            } key={tab.uuid}>
              <TabComponents menu={menu} parentId={tabs.uuid} config={tab} handleList={this.updateTabComponent} deleteCard={this.deleteCard} />
            } key={tab.uuid} style={{backgroundColor: tab.backgroundColor || 'transparent'}}>
              {/* {appType === 'mob' && tabs.setting.position === 'top' && tabs.setting.display === 'inline-block' && tab.hasSearch === 'icon' ?
                <SearchOutlined className="search-icon" onDoubleClick={() => this.setSearch(tab)}/> : null} */}
              <TabComponents config={tab} handleList={this.updateTabComponent} deleteCard={this.deleteCard} />
            </TabPane>
          ))}
          <TabPane className="tab-add" disabled tab={<Icon onClick={this.tabAdd} type="plus" />} key="add"></TabPane>
        </Tabs>
        <Modal
          wrapClassName="popview-modal"
          title={'标签编辑'}
          visible={labelvisible}
          width={600}
          maskClosable={false}
          okText={dict['model.submit']}
          onOk={this.tabLabelSubmit}
          onCancel={() => { this.setState({ labelvisible: false }) }}
          destroyOnClose
        >
          <TabLabelComponent
            dict={dict}
            tab={editab}
            wrappedComponentRef={(inst) => this.tabLabelRef = inst}
          />
        </Modal>
        </DraggableTabs>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <NormalForm title="添加标签" width={800} update={this.updateTab} getForms={() => this.getTabForms()}>
              <PlusOutlined className="plus" title="添加标签"/>
            </NormalForm>
            <NormalForm title="标签页设置" width={800} update={this.updateTabs} getForms={this.getTabsForms}>
              <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="tabs" card={tabs}/>
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <DeleteOutlined className="close" onClick={() => this.props.deletecomponent(tabs.uuid)} />
          </div>
        } trigger="hover">
          <ToolOutlined />
        </Popover>
      </div>
    )
  }
}
export default antvBarLineChart
export default antvTabs