king
2019-11-12 b68697ccdce3f7de67c3a918701c814497b6b41a
2019-11-12
2 文件已重命名
8个文件已修改
4个文件已添加
979 ■■■■ 已修改文件
src/components/sidemenu/comtableconfig/actionform/index.jsx 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/comtableconfig/actionform/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/comtableconfig/columnform/index.jsx 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/comtableconfig/columnform/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/comtableconfig/dragelement/card.jsx 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/comtableconfig/dragelement/index.jsx 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/comtableconfig/dragelement/itemtypes.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/comtableconfig/index.jsx 326 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/comtableconfig/index.scss 127 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/comtableconfig/searchform/index.jsx 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/comtableconfig/searchform/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/editthdmenu/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/header.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/header.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/comtableconfig/actionform/index.jsx
New file
@@ -0,0 +1,212 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, Select, Icon } from 'antd'
import './index.scss'
const btnIcons = [{
  MenuID: 'plus',
  text: 'plus'
}, {
  MenuID: 'plus-circle',
  text: 'plus-circle'
}, {
  MenuID: 'edit',
  text: 'edit'
}, {
  MenuID: 'form',
  text: 'form'
}, {
  MenuID: 'close',
  text: 'close'
}, {
  MenuID: 'close-circle',
  text: 'close-circle'
}, {
  MenuID: 'delete',
  text: 'delete'
}]
const btnClasses = [{
  MenuID: 'default',
  text: '默认(黑边白底)'
}, {
  MenuID: 'primary',
  text: '蓝色'
}, {
  MenuID: 'yellow',
  text: '黄色'
}, {
  MenuID: 'danger',
  text: '红色'
}, {
  MenuID: 'green',
  text: '绿色'
}, {
  MenuID: 'dgreen',
  text: '深绿色'
}, {
  MenuID: 'purple',
  text: '紫色'
}, {
  MenuID: 'gray',
  text: '灰色'
}]
class MainSearch extends Component {
  static propTpyes = {
    dict: PropTypes.object, // 字典项
    formlist: PropTypes.any,
    card: PropTypes.any
  }
  state = {
  }
  getFields() {
    const { getFieldDecorator } = this.props.form
    const fields = []
    this.props.formlist.forEach((item, index) => {
      if (item.type === 'text') { // 文本搜索
        fields.push(
          <Col span={24} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} />)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'select' && item.key === 'icon') { // 下拉搜索
        fields.push(
          <Col span={24} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Select
                  showSearch
                  filterOption={(input, option) => option.props.children[2].toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  getPopupContainer={() => document.getElementById('winter')}
                >
                  {btnIcons.map(option =>
                    <Select.Option id={option.MenuID} title={option.text} key={option.MenuID} value={option.MenuID}>
                      <Icon type={option.MenuID} /> {option.text}
                    </Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'select' && item.key === 'class') { // 下拉搜索
        fields.push(
          <Col span={24} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Select
                  showSearch
                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  getPopupContainer={() => document.getElementById('winter')}
                >
                  {btnClasses.map(option =>
                    <Select.Option id={option.MenuID} title={option.text} key={option.MenuID} value={option.MenuID}>
                      {option.text}
                    </Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'select') { // 下拉搜索
        fields.push(
          <Col span={24} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Select
                  showSearch
                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  getPopupContainer={() => document.getElementById('winter')}
                >
                  {item.options.map(option =>
                    <Select.Option id={option.MenuID} title={option.text} key={option.MenuID} value={option.MenuID}>
                      {option.text}
                    </Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        )
      }
    })
    return fields
  }
  handleConfirm = () => {
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          values.id = this.props.card.id
          values.uuid = this.props.card.uuid
          resolve({
            type: 'action',
            values
          })
        } else {
          reject(err)
        }
      })
    })
  }
  render() {
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 6 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 18 }
      }
    }
    return (
      <Form {...formItemLayout} className="ant-advanced-search-form commontable-action-form" id="winter">
        <Row gutter={24}>{this.getFields()}</Row>
      </Form>
    )
  }
}
export default Form.create()(MainSearch)
src/components/sidemenu/comtableconfig/actionform/index.scss
New file
@@ -0,0 +1,5 @@
.ant-advanced-search-form.commontable-action-form {
  .ant-form-item {
    margin-bottom: 15px;
  }
}
src/components/sidemenu/comtableconfig/columnform/index.jsx
New file
@@ -0,0 +1,123 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, Select, InputNumber } from 'antd'
import './index.scss'
class MainSearch extends Component {
  static propTpyes = {
    dict: PropTypes.object, // 字典项
    formlist: PropTypes.any,
    card: PropTypes.any
  }
  state = {
  }
  getFields() {
    const { getFieldDecorator } = this.props.form
    const fields = []
    this.props.formlist.forEach((item, index) => {
      if (item.type === 'text') { // 文本搜索
        fields.push(
          <Col span={24} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} />)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'spinner') { // 文本搜索
        fields.push(
          <Col span={24} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  }
                ]
              })(<InputNumber min={1} max={1000} />)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'select') { // 下拉搜索
        fields.push(
          <Col span={24} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Select
                  showSearch
                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  getPopupContainer={() => document.getElementById('columnwinter')}
                >
                  {item.options.map(option =>
                    <Select.Option id={option.MenuID} title={option.text} key={option.MenuID} value={option.MenuID}>
                      {option.text}
                    </Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        )
      }
    })
    return fields
  }
  handleConfirm = () => {
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          values.id = this.props.card.id
          values.uuid = this.props.card.uuid
          resolve({
            type: 'columns',
            values
          })
        } else {
          reject(err)
        }
      })
    })
  }
  render() {
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 6 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 18 }
      }
    }
    return (
      <Form {...formItemLayout} className="ant-advanced-search-form commontable-column-form" id="columnwinter">
        <Row gutter={24}>{this.getFields()}</Row>
      </Form>
    )
  }
}
export default Form.create()(MainSearch)
src/components/sidemenu/comtableconfig/columnform/index.scss
New file
@@ -0,0 +1,5 @@
.ant-advanced-search-form.commontable-column-form {
  .ant-form-item {
    margin-bottom: 15px;
  }
}
src/components/sidemenu/comtableconfig/dragelement/card.jsx
@@ -1,19 +1,20 @@
import React from 'react'
import { useDrag, useDrop } from 'react-dnd'
import { Icon, Button } from 'antd'
import { Icon, Button, Select, DatePicker } from 'antd'
import moment from 'moment'
import ItemTypes from './itemtypes'
import './index.scss'
const Card = ({ id, type, card, moveCard, findCard, editCard }) => {
  const originalIndex = findCard(id).index
  const [{ isDragging }, drag] = useDrag({
    item: { type: ItemTypes.CARD, id, originalIndex },
    item: { type: ItemTypes[type], id, originalIndex },
    collect: monitor => ({
      isDragging: monitor.isDragging(),
    }),
  })
  const [, drop] = useDrop({
    accept: ItemTypes.CARD,
    accept: ItemTypes[type],
    canDrop: () => false,
    hover({ id: draggedId }) {
      if (draggedId !== id) {
@@ -29,18 +30,30 @@
  }
  return (
    <div className="page-card" style={{ opacity }}>
    <div className="page-card" style={type === 'columns' ? { flex: card.Width, opacity: opacity} : { opacity: opacity}}>
      <div ref={node => drag(drop(node))}>
        {type === 'search' && <div className="ant-row ant-form-item">
          <div className="ant-col ant-form-item-label">
            <label title={card.label}>{card.label}</label>
          </div>
          <div className="ant-col ant-form-item-control-wrapper">
            <div className="ant-form-item-control">
              <span className="ant-form-item-children">
                <input placeholder="" autoComplete="off" type="text" readOnly={true}  className="ant-input" />
              </span>
            </div>
            {card.type === 'text' &&
              <div className="ant-form-item-control">
                <span className="ant-form-item-children">
                  <input placeholder="" autoComplete="off" type="text" readOnly={true}  className="ant-input" />
                </span>
              </div>
            }
            {card.type === 'select' &&
              <Select defaultValue="lucy"></Select>
            }
            {card.type === 'dateday' &&
              <DatePicker defaultValue={card.initval ? moment(card.initval, 'YYYY-MM-DD') : null} />
            }
            {card.type === 'datetime' &&
              <DatePicker showTime defaultValue={card.initval ? moment(card.initval, 'YYYY-MM-DD HH:mm:ss') : null} />
            }
            <div className="input-mask"></div>
          </div>
        </div>}
        {type === 'action' &&
@@ -50,6 +63,17 @@
            key={card.uuid}
          >{card.label}</Button>
        }
        {type === 'columns' &&
          <span className="ant-table-header-column">
            <div className="ant-table-column-sorters" style={{textAlign: card.Align}}>
              <span className="ant-table-column-title">{card.label}</span>
              {card.IsSort === 'true' && <span className="ant-table-column-sorter">
                <Icon type="caret-up" />
                <Icon type="caret-down" />
              </span>}
            </div>
          </span>
        }
      </div>
      <Icon className="edit" type="edit" onClick={edit} />
    </div>
src/components/sidemenu/comtableconfig/dragelement/index.jsx
@@ -12,7 +12,7 @@
    const { card, index } = findCard(id)
    const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] })
    setCards(_cards)
    handleList(_cards)
    handleList({[type]: _cards})
  }
  const findCard = id => {
@@ -27,27 +27,22 @@
    const { card } = findCard(id)
    handleMenu(card)
  }
  const [, drop] = useDrop({ accept: ItemTypes.CARD })
  const [, drop] = useDrop({ accept: ItemTypes[type] })
  return (
    <div ref={drop} className="ant-row">
        {type === 'search' && cards.map(card => (
          <Col key={card.uuid} span={6}>
            <Card
              key={card.uuid}
              id={`${card.id}`}
              type={type}
              card={card}
              moveCard={moveCard}
              editCard={editCard}
              findCard={findCard}
            />
          </Col>
        ))}
        {/* {type === 'search' && <Col key="add" span={6}>
          <Icon className="element-add" type="plus"/>
        </Col>} */}
        {type === 'action' && cards.map(card => (
    <div ref={drop} className="ant-row" style={type === 'columns' ? {display: 'flex'} : {}}>
      {type === 'action' && cards.map(card => (
        <Card
          key={card.uuid}
          id={`${card.id}`}
          type={type}
          card={card}
          moveCard={moveCard}
          editCard={editCard}
          findCard={findCard}
        />
      ))}
      {type === 'search' && cards.map(card => (
        <Col key={card.uuid} span={6}>
          <Card
            key={card.uuid}
            id={`${card.id}`}
@@ -57,7 +52,23 @@
            editCard={editCard}
            findCard={findCard}
          />
        ))}
        </Col>
      ))}
      {type === 'columns' && cards.length > 0 &&
      <div className="page-card" style={{flex: 60}}>
        <span className="ant-checkbox-inner"></span>
      </div>}
      {type === 'columns' && cards.map(card => (
        <Card
          key={card.uuid}
          id={`${card.id}`}
          type={type}
          card={card}
          moveCard={moveCard}
          editCard={editCard}
          findCard={findCard}
        />
      ))}
    </div>
  )
}
src/components/sidemenu/comtableconfig/dragelement/itemtypes.js
@@ -1,3 +1,6 @@
export default {
  CARD: 'card',
  search: 'search',
  action: 'action',
  columns: 'columns'
}
src/components/sidemenu/comtableconfig/index.jsx
@@ -1,15 +1,19 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
// import { is, fromJS } from 'immutable'
import { DndProvider } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'
import { Button, Card, Modal } from 'antd'
import { Button, Card, Modal, Tabs } from 'antd'
import DragElement from './dragelement'
import MenuForm from './menuform'
import SearchForm from './searchform'
import ActionForm from './actionform'
import ColumnForm from './columnform'
import zhCN from '@/locales/zh-CN/header.js'
import enUS from '@/locales/en-US/header.js'
import Utils from '@/utils/utils.js'
import './index.scss'
const {TabPane} = Tabs
class ComTableConfig extends Component {
  static propTpyes = {
@@ -21,6 +25,12 @@
    config: null,
    visible: false,
    formlist: null,
    formtemp: '',
    madalwidth: 520,
    card: null,
    searchloading: false,
    actionloading: false,
    columnsloading: false,
    baseconfig: {
      type: 'system',
      search: [{
@@ -83,46 +93,49 @@
        uuid: Utils.getuuid(),
        Align: 'left',
        label: 'fieldName1',
        Hide: false,
        IsSort: true,
        Hide: 'false',
        IsSort: 'true',
        Width: 120
      }, {
        id: 1,
        uuid: Utils.getuuid(),
        Align: 'left',
        label: 'fieldName2',
        Hide: false,
        IsSort: true,
        Hide: 'false',
        IsSort: 'true',
        Width: 120
      }, {
        id: 2,
        uuid: Utils.getuuid(),
        Align: 'left',
        label: 'fieldName3',
        Hide: false,
        IsSort: true,
        Hide: 'false',
        IsSort: 'true',
        Width: 120
      }, {
        id: 3,
        uuid: Utils.getuuid(),
        Align: 'left',
        label: 'fieldName4',
        Hide: false,
        IsSort: true,
        Hide: 'false',
        IsSort: 'true',
        Width: 120
      }]
    }
  }
  handlesearchList = (searchlist) => {
  handleList = (list) => {
    console.log(list)
    let config = this.state.config
    config.search = searchlist
    this.setState({config})
    this.setState({config: {...config, ...list}})
  }
  handleSearch = (card) => {
    this.setState({
      visible: true,
      formtemp: 'search',
      madalwidth: 650,
      card: card,
      formlist: [
        {
          type: 'text',
@@ -164,20 +177,191 @@
    })
  }
  handleactionList = (actionlist) => {
    let config = this.state.config
    config.action = actionlist
    this.setState({config})
  handleAction = (card) => {
    this.setState({
      visible: true,
      formtemp: 'action',
      madalwidth: 520,
      card: card,
      formlist: [
        {
          type: 'text',
          key: 'label',
          label: this.state.dict['header.form.name'],
          initVal: card.label,
          required: true,
          readonly: false
        },
        {
          type: 'select',
          key: 'Ot',
          label: this.state.dict['header.form.isRequired'],
          initVal: card.Ot,
          required: true,
          options: [{
            MenuID: 'notRequired',
            text: this.state.dict['header.form.notRequired']
          }, {
            MenuID: 'requiredSgl',
            text: this.state.dict['header.form.requiredSgl']
          }, {
            MenuID: 'required',
            text: this.state.dict['header.form.required']
          }, {
            MenuID: 'requiredOnce',
            text: this.state.dict['header.form.requiredOnce']
          }]
        },
        {
          type: 'select',
          key: 'OpenType',
          label: this.state.dict['header.form.openType'],
          initVal: card.OpenType,
          required: true,
          options: [{
            MenuID: 'pop',
            text: this.state.dict['header.form.pop']
          }, {
            MenuID: 'prompt',
            text: this.state.dict['header.form.prompt']
          }, {
            MenuID: 'exec',
            text: this.state.dict['header.form.exec']
          }, {
            MenuID: 'tab',
            text: this.state.dict['header.form.tab']
          }, {
            MenuID: 'newpage',
            text: this.state.dict['header.form.newpage']
          }, {
            MenuID: 'blank',
            text: this.state.dict['header.form.blank']
          }]
        },
        {
          type: 'select',
          key: 'icon',
          label: this.state.dict['header.form.icon'],
          initVal: card.icon,
          required: false,
          options: []
        },
        {
          type: 'select',
          key: 'class',
          label: this.state.dict['header.form.class'],
          initVal: card.class,
          required: true,
          options: []
        }
      ]
    })
  }
  handleAction = (card) => {
    console.log(card)
  handleColumn = (card) => {
    this.setState({
      visible: true,
      formtemp: 'columns',
      madalwidth: 520,
      card: card,
      formlist: [
        {
          type: 'text',
          key: 'label',
          label: this.state.dict['header.form.name'],
          initVal: card.label,
          required: true
        },
        {
          type: 'select',
          key: 'Align',
          label: this.state.dict['header.form.align'],
          initVal: card.Align,
          required: true,
          options: [{
            MenuID: 'left',
            text: this.state.dict['header.form.alignLeft']
          }, {
            MenuID: 'right',
            text: this.state.dict['header.form.alignRight']
          }, {
            MenuID: 'center',
            text: this.state.dict['header.form.alignCenter']
          }]
        },
        {
          type: 'select',
          key: 'Hide',
          label: this.state.dict['header.form.Hide'],
          initVal: card.Hide,
          required: true,
          options: [{
            MenuID: 'true',
            text: this.state.dict['header.form.true']
          }, {
            MenuID: 'false',
            text: this.state.dict['header.form.false']
          }]
        },
        {
          type: 'select',
          key: 'IsSort',
          label: this.state.dict['header.form.IsSort'],
          initVal: card.IsSort,
          required: true,
          options: [{
            MenuID: 'true',
            text: this.state.dict['header.form.true']
          }, {
            MenuID: 'false',
            text: this.state.dict['header.form.false']
          }]
        },
        {
          type: 'spinner',
          key: 'Width',
          label: this.state.dict['header.form.columnWidth'],
          initVal: card.Width,
          required: true
        }
      ]
    })
  }
  handleSubmit = () => {
    this.formRef.handleConfirm().then(values => {
      console.log(values)
    this.formRef.handleConfirm().then(res => {
      let _config = this.state.config
      _config[res.type] = _config[res.type].map(item => {
        if (item.uuid === res.values.uuid) {
          return res.values
        } else {
          return item
        }
      })
      this.setState({
        config: _config,
        [res.type + 'loading']: true,
        visible: false
      })
      this.resetFrom()
    })
  }
  deleteElement = () => {
    let _config = this.state.config
    _config[this.state.formtemp] = _config[this.state.formtemp].filter(item => {
      if (item.uuid === this.state.card.uuid) {
        return false
      } else {
        return true
      }
    })
    this.setState({
      config: _config,
      [this.state.formtemp + 'loading']: true,
      visible: false
    })
    this.resetFrom()
  }
  handleCancel = () => {
@@ -190,9 +374,26 @@
  resetFrom = () => {
    setTimeout(() => {
      this.setState({
        formtemp: '',
        searchloading: false,
        actionloading: false,
        columnsloading: false,
        formlist: null
      })
    }, 300)
  }
  dragstart = (e) => {
    console.log(e.target.id)
  }
  dragover = (e) => {
    e.preventDefault()
  }
  drop = (e) => {
    e.preventDefault()
    console.log(13)
  }
  UNSAFE_componentWillMount () {
@@ -207,16 +408,35 @@
    }
  }
  UNSAFE_componentWillReceiveProps (nextProps) {
    if (!is(fromJS(this.props.menulist), fromJS(nextProps.menulist))) {
    }
  }
  render () {
    return (
      <div className="common-table-board">
        <div className="tools"></div>
        <div className="tools">
          <Tabs defaultActiveKey="1">
            <TabPane tab="搜索" key="1">
              <ul className="search-element">
                <li>
                  <div draggable="true" id="search-text" onDragStart={(e) => {this.dragstart(e)}}>文本框</div>
                </li>
                <li>
                  <div draggable="true" id="search-select" onDragStart={this.dragstart}>下拉框</div>
                </li>
                <li>
                  <div draggable="true" id="search-dateday" onDragStart={this.dragstart}>时间框(天)</div>
                </li>
                <li>
                  <div draggable="true" id="search-datetime" onDragStart={this.dragstart}>时间框(秒)</div>
                </li>
              </ul>
            </TabPane>
            <TabPane tab="按钮" key="2">
              按钮
            </TabPane>
            <TabPane tab="显示列" key="3">
              列
            </TabPane>
          </Tabs>
        </div>
        <div className="setting">
          <Card title="页面配置" bordered={false} extra={
            <div>
@@ -224,23 +444,33 @@
              <Button>{this.state.dict['header.cancel']}</Button>
            </div>
          } style={{ width: '100%' }}>
            <div className="search-list">
              {this.state.config.search && <DndProvider backend={HTML5Backend}>
            <div className="search-list" onDragOver={this.dragover} onDrop={this.drop}>
              {this.state.config.search && !this.state.searchloading && <DndProvider backend={HTML5Backend}>
                <DragElement
                  list={this.state.config.search}
                  type="search"
                  handleList={this.handlesearchList}
                  handleList={this.handleList}
                  handleMenu={this.handleSearch}
                />
              </DndProvider>}
            </div>
            <div className="action-list">
              {this.state.config.action && <DndProvider backend={HTML5Backend}>
              {this.state.config.action && !this.state.actionloading && <DndProvider backend={HTML5Backend}>
                <DragElement
                  list={this.state.config.action}
                  type="action"
                  handleList={this.handleactionList}
                  handleList={this.handleList}
                  handleMenu={this.handleAction}
                />
              </DndProvider>}
            </div>
            <div className="column-list">
              {this.state.config.columns && !this.state.columnsloading && <DndProvider backend={HTML5Backend}>
                <DragElement
                  list={this.state.config.columns}
                  type="columns"
                  handleList={this.handleList}
                  handleMenu={this.handleColumn}
                />
              </DndProvider>}
            </div>
@@ -248,22 +478,36 @@
        </div>
        <Modal
          title={this.state.dict['header.edit']}
          okText={this.state.dict['header.confirm']}
          cancelText={this.state.dict['header.cancel']}
          visible={this.state.visible}
          onOk={this.handleSubmit}
          confirmLoading={this.state.confirmLoading}
          width={this.state.madalwidth}
          onCancel={this.handleCancel}
          className="commontable-edit-modal"
          footer={null}
          destroyOnClose
        >
          {this.state.formlist && <MenuForm
          {this.state.formlist && this.state.formtemp === 'search' && <SearchForm
            dict={this.state.dict}
            formlist={this.state.formlist}
            wrappedComponentRef={(inst) => this.formRef = inst}
          />}
          {this.state.formlist && this.state.formtemp === 'action' && <ActionForm
            dict={this.state.dict}
            card={this.state.card}
            formlist={this.state.formlist}
            wrappedComponentRef={(inst) => this.formRef = inst}
          />}
          {this.state.formlist && this.state.formtemp === 'columns' && <ColumnForm
            dict={this.state.dict}
            card={this.state.card}
            formlist={this.state.formlist}
            wrappedComponentRef={(inst) => this.formRef = inst}
          />}
          <div className="edit-modal-footer">
            <Button type="danger" onClick={this.deleteElement}>{this.state.dict['header.delete']}</Button>
            <Button onClick={this.handleCancel}>{this.state.dict['header.cancel']}</Button>
            <Button type="primary" onClick={this.handleSubmit}>{this.state.dict['header.confirm']}</Button>
          </div>
        </Modal>
      </div>
    )
  }
}
src/components/sidemenu/comtableconfig/index.scss
@@ -12,6 +12,24 @@
    flex: 1;
    background: #ffffff;
    border-right: 1px solid #d9d9d9;
    .ant-tabs-nav {
      .ant-tabs-tab {
        padding: 12px 0px;
        width: 60px;
        text-align: center;
      }
      .ant-tabs-tab:not(:last-child) {
        margin: 0 20px 0 0;
      }
    }
    .search-element {
      li {
        padding: 0px 16px 10px;
        div {
          cursor: move;
        }
      }
    }
  }
  .setting {
    position: relative;
@@ -19,13 +37,15 @@
    height: 100%;
    overflow-y: auto;
    background: #ffffff;
    .ant-card-head {
      min-height: 44px;
    }
    .ant-card-head-title {
      padding: 10px 0;
      padding: 5px 0;
      color: #1890ff;
    }
    .ant-card-extra {
      padding: 10px 0;
      padding: 5px 0;
      button {
        margin-left: 20px;
      }
@@ -35,7 +55,7 @@
      .search-list {
        padding: 1px 24px 20px;
        min-height: 50px;
        min-height: 87px;
        border-bottom: 1px solid #d9d9d9;
        .ant-row .ant-col-6 {
          padding: 0 12px!important;
@@ -54,24 +74,32 @@
            margin-bottom: 10px;
            .ant-form-item-label {
              width: 100px;
              height: 40px;
              label {
                width: 100%;
                cursor: move;
                overflow: hidden;
                display: inline-block;
                text-overflow: ellipsis;
                white-space: nowrap;
              }
            }
            .ant-form-item-control-wrapper {
              flex: 1 1;
              input {
                cursor: move;
              .ant-select {
                width: 100%;
                margin-top: 4px;
              }
              input:hover {
                border-color: #d9d9d9;
              .ant-calendar-picker {
                margin-top: 4px;
              }
              input:active {
                border-color: #d9d9d9;
              }
              input:focus {
                border-color: #d9d9d9;
                box-shadow: none;
              .input-mask {
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                opacity: 0;
              }
            }
          }
@@ -99,14 +127,16 @@
        }
      }
      .action-list {
        padding: 0px 20px 5px;
        min-height: 50px;
        padding: 0px 20px 15px;
        min-height: 72px;
        .page-card {
          display: inline-block;
          margin: 0px 15px 20px 0px;
          padding-top: 15px;
          cursor: move;
          margin: 0px 0px 20px 0px;
          padding: 15px 10px 0 0;
          position: relative;
          div {
            cursor: move;
          }
          .edit {
            position: absolute;
            left: 0;
@@ -129,9 +159,62 @@
        padding: 10px 20px;
        cursor: pointer;
      }
      .column-list {
        padding: 0px 20px;
        .ant-row {
          background: #fafafa;
          border-radius: 4px;
          border: 1px solid #e8e8e8;
          .page-card {
            position: relative;
            padding: 0px;
            min-height: 45px;
            > div {
              padding: 12px 8px;
              cursor: move;
            }
            .ant-table-column-sorter {
              position: relative;
              display: inline-block;
              width: 24px;
              font-size: 12px;
              color: #bfbfbf;
              .anticon-caret-up {
                position: relative;
                left: 10px;
                top: -3px;
              }
              .anticon-caret-down {
                position: relative;
                left: -2px;
                top: 3px;
              }
            }
            .edit {
              position: absolute;
              left: 0;
              top: 0px;
              cursor: pointer;
              display: none;
            }
            .ant-checkbox-inner {
              margin-top: 14px;
              margin-left: calc(50% - 8px);
            }
          }
          .page-card:hover {
            .edit {
              display: inline-block;
            }
          }
          .page-card:not(:last-child) {
            border-right: 1px solid #e8e8e8;
          }
        }
      }
    }
  }
}
.commontable-edit-modal {
  width: 650px!important;
}
// .commontable-edit-modal {
//   width: 650px!important;
// }
src/components/sidemenu/comtableconfig/searchform/index.jsx
File was renamed from src/components/sidemenu/comtableconfig/menuform/index.jsx
@@ -1,5 +1,6 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
// import { is, fromJS } from 'immutable'
import { Form, Row, Col, Input, Select, Icon, Radio } from 'antd'
import moment from 'moment'
import EditTable from '../editable'
@@ -10,14 +11,15 @@
class MainSearch extends Component {
  static propTpyes = {
    dict: PropTypes.object, // 字典项
    formlist: PropTypes.array
    formlist: PropTypes.any
  }
  state = {
    card: null,
    inputType: 'text',
    selectType: 0,
    options: null
    options: null,
    formlist: null
  }
  openTypeChange = (key, value) => {
@@ -78,7 +80,7 @@
                  showSearch
                  filterOption={(input, option) => option.props.children[2].toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  onChange={(value) => {this.openTypeChange(item.key, value)}}
                  getPopupContainer={() => document.getElementById('form-box')}
                  getPopupContainer={() => document.getElementById('commontable-search-form-box')}
                >
                  {item.options.map(option =>
                    <Select.Option id={option.MenuID} title={option.text} key={option.MenuID} value={option.MenuID}>
@@ -112,13 +114,7 @@
              <Col span={18} offset={6} key={'table' + index}>
                <Form.Item className="text-area">
                  {getFieldDecorator('datasource', {
                    initialValue: '',
                    rules: [
                      {
                        required: true,
                        message: this.props.dict['form.required.input'] + 'datasource !'
                      }
                    ]
                    initialValue: ''
                  })(<TextArea rows={4} />)}
                </Form.Item>
              </Col>
@@ -145,7 +141,10 @@
          }
          values.id = this.state.card.id
          values.uuid = this.state.card.uuid
          resolve(values)
          resolve({
            type: 'search',
            values
          })
        } else {
          reject(err)
        }
@@ -153,8 +152,9 @@
    })
  }
  UNSAFE_componentWillMount () {
    let _item = this.props.formlist.filter(cell => cell.key === 'type')[0]
  resetForm = (formlist) => {
    if (!formlist) return
    let _item = formlist.filter(cell => cell.key === 'type')[0]
    if (_item.initVal === 'select') {
      this.setState({
        inputType: 'select',
@@ -169,6 +169,10 @@
    }
  }
  UNSAFE_componentWillMount () {
    this.resetForm(this.props.formlist)
  }
  render() {
    const formItemLayout = {
      labelCol: {
@@ -181,7 +185,7 @@
      }
    }
    return (
      <Form {...formItemLayout} className="ant-advanced-search-form commontable-form" id="form-box">
      <Form {...formItemLayout} className="ant-advanced-search-form commontable-search-form" id="commontable-search-form-box">
        <Row gutter={24}>{this.getFields()}</Row>
      </Form>
    )
src/components/sidemenu/comtableconfig/searchform/index.scss
File was renamed from src/components/sidemenu/comtableconfig/menuform/index.scss
@@ -1,4 +1,4 @@
.ant-advanced-search-form.commontable-form {
.ant-advanced-search-form.commontable-search-form {
  .ant-col-offset-6 {
    padding-left: 6px!important;
    padding-bottom: 20px;
src/components/sidemenu/editthdmenu/index.jsx
@@ -389,7 +389,6 @@
  }
  useTemplate = (template) => {
    console.log(template)
    // 选择模板:添加菜单时
    if (this.state.type === 'add') {
      this.setState({
src/locales/en-US/header.js
@@ -47,5 +47,28 @@
  'header.form.dateday': 'Date(Day)',
  'header.form.datetime': 'Date(Second)',
  'header.form.initval': 'Initial Value',
  'header.form.isRequired': '是否选择行',
  'header.form.notRequired': '不选择行',
  'header.form.requiredSgl': '选择单行',
  'header.form.required': '选择多行',
  'header.form.requiredOnce': '多行拼接',
  'header.form.openType': '打开方式',
  'header.form.pop': '弹窗',
  'header.form.tab': '新标签页',
  'header.form.newpage': '新页面',
  'header.form.blank': '当前页跳转',
  'header.form.prompt': '提示框',
  'header.form.exec': '直接执行',
  'header.form.icon': '图标',
  'header.form.class': '颜色',
  'header.form.align': '对齐方式',
  'header.form.alignLeft': '左对齐',
  'header.form.alignRight': '右对齐',
  'header.form.alignCenter': '居中',
  'header.form.Hide': '是否隐藏',
  'header.form.IsSort': '是否排序',
  'header.form.columnWidth': '列宽',
  'header.form.true': '是',
  'header.form.false': '否',
  'form.required.input': 'Please enter the '
}
src/locales/zh-CN/header.js
@@ -47,6 +47,29 @@
  'header.form.dateday': '日期(天)',
  'header.form.datetime': '日期(秒)',
  'header.form.initval': '初始值',
  'header.form.isRequired': '是否选择行',
  'header.form.notRequired': '不选择行',
  'header.form.requiredSgl': '选择单行',
  'header.form.required': '选择多行',
  'header.form.requiredOnce': '多行拼接',
  'header.form.openType': '打开方式',
  'header.form.pop': '弹窗',
  'header.form.tab': '新标签页',
  'header.form.newpage': '新页面',
  'header.form.blank': '当前页跳转',
  'header.form.prompt': '提示框',
  'header.form.exec': '直接执行',
  'header.form.icon': '图标',
  'header.form.class': '颜色',
  'header.form.align': '对齐方式',
  'header.form.alignLeft': '左对齐',
  'header.form.alignRight': '右对齐',
  'header.form.alignCenter': '居中',
  'header.form.Hide': '是否隐藏',
  'header.form.IsSort': '是否排序',
  'header.form.columnWidth': '列宽',
  'header.form.true': '是',
  'header.form.false': '否',
  'form.required.input': '请输入'
}