| | |
| | | 'model.window': 'Window', |
| | | 'model.empty': 'Empty', |
| | | 'model.pay': 'Pay', |
| | | 'model.operation': 'Action', |
| | | 'model.switch.open': 'Open', |
| | | 'model.switch.close': 'Close', |
| | | 'model.menu.level1': 'Level 1 menu', |
| | |
| | | 'model.window': '窗口', |
| | | 'model.empty': '空', |
| | | 'model.pay': '支付', |
| | | 'model.operation': '操作', |
| | | 'model.switch.open': '开', |
| | | 'model.switch.close': '关', |
| | | 'model.menu.level1': '一级菜单', |
| | |
| | | format: 'object', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | |
| | | format: 'array', // 组件属性 - 数据格式 |
| | | pageable: true, // 组件属性 - 是否可分页 |
| | | switchable: true, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | |
| | | format: 'object', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: true, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | |
| | | format: 'array', // 组件属性 - 数据格式 |
| | | pageable: true, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 12, |
| | | search: [], |
| | | name: card.name, |
| | |
| | | format: 'array', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | |
| | | format: 'object', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | |
| | | format: 'array', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: card.type === 'bar' ? true : false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: _plot.width, |
| | | name: _plot.name, |
| | | subtype: card.subtype, |
| | |
| | | format: card.subtype === 'ratioboard' ? 'array' : 'object', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: _plot.width, |
| | | name: _plot.name, |
| | | subtype: card.subtype, |
| | |
| | | format: 'array', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: _plot.width, |
| | | name: _plot.name, |
| | | subtype: card.subtype, |
| | |
| | | format: 'array', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: _plot.width, |
| | | name: _plot.name, |
| | | subtype: card.subtype, |
| | |
| | | format: 'array', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: _plot.width, |
| | | name: _plot.name, |
| | | subtype: card.subtype, |
| | |
| | | type: card.type, |
| | | tabId: card.tabId || '', |
| | | parentId: card.parentId || '', |
| | | dataName: card.dataName || '', |
| | | format: 'object', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | |
| | | type: card.type, |
| | | tabId: card.tabId || '', |
| | | parentId: card.parentId || '', |
| | | dataName: card.dataName || '', |
| | | format: 'object', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | |
| | | format: 'object', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | |
| | | format: 'object', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | |
| | | format: 'object', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | |
| | | subtype: item.subtype, |
| | | config: item.config, |
| | | width: item.width || 24, |
| | | dataName: Utils.getdataName(), |
| | | name: name, |
| | | isNew: true // 新添加标志,用于初始化 |
| | | } |
| | |
| | | type: card.type, |
| | | tabId: card.tabId || '', |
| | | parentId: card.parentId || '', |
| | | dataName: card.dataName || '', |
| | | format: 'array', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | |
| | | import { is, fromJS } from 'immutable' |
| | | import { DndProvider, DragSource, DropTarget } from 'react-dnd' |
| | | import { Table, Popover, Modal, message } from 'antd' |
| | | import { PlusOutlined, FileSyncOutlined, EditOutlined, CopyOutlined, DeleteOutlined, FontColorsOutlined, CloseCircleOutlined, AntDesignOutlined } from '@ant-design/icons' |
| | | import { PlusOutlined, EditOutlined, CopyOutlined, DeleteOutlined, FontColorsOutlined, CloseCircleOutlined, AntDesignOutlined } from '@ant-design/icons' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import asyncIconComponent from '@/utils/asyncIconComponent' |
| | |
| | | }) |
| | | } |
| | | |
| | | syncfield = () => { |
| | | const { fields } = this.state |
| | | let columns = fromJS(this.state.columns).toJS() |
| | | |
| | | columns = columns.filter(c => !c.origin) |
| | | |
| | | let keys = columns.map(col => col.field) |
| | | |
| | | fields.forEach(item => { |
| | | if (keys.includes(item.field)) return |
| | | |
| | | let cell = { uuid: Utils.getuuid(), label: item.label, field: item.field, Align: 'left', Hide: 'false', IsSort: 'true', Width: 120, blacklist: [], postfix: '', prefix: '', linkmenu: [], marks: [], perspective: 'linkmenu' } |
| | | |
| | | if (/Nvarchar|date/ig.test(item.datatype)) { |
| | | cell.type = 'text' |
| | | cell.rowspan = 'false' |
| | | cell.textFormat = 'none' |
| | | } else { |
| | | cell.type = 'number' |
| | | cell.format = 'none' |
| | | cell.sum = 'false' |
| | | cell.decimal = item.decimal || 0 |
| | | cell.Width = 80 |
| | | } |
| | | |
| | | columns.push(cell) |
| | | }) |
| | | |
| | | const _this = this |
| | | |
| | | confirm({ |
| | | content: '确定同步字段集吗?', |
| | | onOk() { |
| | | _this.setState({columns}, () => { |
| | | _this.props.updatecolumn({..._this.props.config, cols: columns}) |
| | | }) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | clear = () => { |
| | | const _this = this |
| | | |
| | | confirm({ |
| | | content: '确定清空显示列吗?', |
| | | onOk() { |
| | | _this.setState({columns: []}, () => { |
| | | _this.props.updatecolumn({..._this.props.config, cols: []}) |
| | | }) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新,清除快捷键设置 |
| | | */ |
| | |
| | | <div className="col-control"> |
| | | <CopyOutlined title="复制显示列" onClick={this.copycolumn} /> |
| | | <MarkColumn columns={fields} type="line" marks={lineMarks} onSubmit={this.updateLineMarks} /> |
| | | <FileSyncOutlined title="同步字段集" onClick={this.syncfield} /> |
| | | <DeleteOutlined title="清空显示列" onClick={this.clear}/> |
| | | </div> |
| | | <DndProvider> |
| | | <Table |
| | |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Popover } from 'antd' |
| | | import { PlusOutlined, PlusCircleOutlined, PlusSquareOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons' |
| | | import { EditOutlined, ToolOutlined, FontColorsOutlined } from '@ant-design/icons' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import asyncIconComponent from '@/utils/asyncIconComponent' |
| | | import { resetStyle } from '@/utils/utils-custom.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import getWrapForm from './options' |
| | | import Utils from '@/utils/utils.js' |
| | |
| | | const NormalForm = asyncIconComponent(() => import('@/components/normalform')) |
| | | const SearchComponent = asyncComponent(() => import('@/templates/sharecomponent/searchcomponent')) |
| | | const ActionComponent = asyncComponent(() => import('@/menu/components/share/actioncomponent')) |
| | | const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader')) |
| | | const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent')) |
| | | const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent')) |
| | | const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent')) |
| | | const ColumnComponent = asyncComponent(() => import('./columns')) |
| | | |
| | | class TableCardEditComponent extends Component { |
| | | static propTpyes = { |
| | | card: PropTypes.object, |
| | | deletecomponent: PropTypes.func, |
| | | updateConfig: PropTypes.func, |
| | | } |
| | | |
| | |
| | | format: 'array', // 组件属性 - 数据格式 |
| | | pageable: true, // 组件属性 - 是否可分页 |
| | | switchable: true, // 组件属性 - 数据是否可切换 |
| | | dataName: Utils.getdataName(), |
| | | width: 24, |
| | | search: [ |
| | | { origin: true, uuid: Utils.getuuid(), label: 'label', field: '', type: 'text', match: 'like' }, |
| | | { origin: true, uuid: Utils.getuuid(), label: 'label', field: '', type: 'select', match: 'equal' } |
| | | { origin: true, uuid: Utils.getuuid(), label: 'label', field: '', type: 'select', match: '=' } |
| | | ], |
| | | action: [ |
| | | { origin: true, uuid: Utils.getuuid(), label: '添加', intertype: 'system', OpenType: 'pop', execSuccess: 'grid', icon: 'plus', class: 'green', style: {color: 'rgb(255, 255, 255)', background: 'rgb(38, 194, 129)', marginRight: '15px'} }, |
| | | { origin: true, uuid: Utils.getuuid(), label: '修改', intertype: 'system', OpenType: 'pop', execSuccess: 'grid', icon: 'form', class: 'purple', style: {color: 'rgb(255, 255, 255)', background: 'rgb(142, 68, 173)', marginRight: '15px'} }, |
| | | { origin: true, uuid: Utils.getuuid(), label: '删除', intertype: 'system', OpenType: 'prompt', execSuccess: 'grid', Ot: 'required', icon: 'delete', class: 'danger', style: {color: 'rgb(255, 255, 255)', background: 'rgb(255, 77, 79)', marginRight: '15px'} } |
| | | ], |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | | setting: { interType: 'system' }, |
| | | wrap: { name: card.name, width: 24, bordered: 'true', tableType: 'checkbox', show: 'true' }, |
| | | wrap: { bordered: 'true', tableType: 'checkbox', show: 'true' }, |
| | | style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' }, |
| | | headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' }, |
| | | columns: [], |
| | |
| | | ], |
| | | scripts: [], |
| | | isNew: true |
| | | } |
| | | |
| | | if (card.config) { |
| | | let config = fromJS(card.config).toJS() |
| | | |
| | | _card.wrap = config.wrap |
| | | _card.wrap.name = card.name |
| | | _card.style = config.style |
| | | _card.headerStyle = config.headerStyle |
| | | |
| | | _card.setting = config.setting |
| | | _card.columns = config.columns |
| | | _card.scripts = config.scripts |
| | | |
| | | let oriUids = {} |
| | | _card.action = config.action.map(item => { |
| | | let _uuid = Utils.getuuid() |
| | | oriUids[item.uuid] = _uuid |
| | | item.uuid = _uuid |
| | | return item |
| | | }) |
| | | _card.search = config.search.map(item => { |
| | | item.uuid = Utils.getuuid() |
| | | return item |
| | | }) |
| | | _card.cols = config.cols.map(col => { |
| | | col.uuid = Utils.getuuid() |
| | | if (col.type === 'colspan' && col.subcols) { |
| | | col = this.loopCol(col) |
| | | } else if (col.type === 'custom' && col.elements) { |
| | | col.elements = col.elements.map(cell => { |
| | | cell.uuid = Utils.getuuid() |
| | | return cell |
| | | }) |
| | | } else if (col.type === 'action' && col.elements) { |
| | | col.elements = col.elements.map(cell => { |
| | | cell.uuid = Utils.getuuid() |
| | | return cell |
| | | }) |
| | | } |
| | | return col |
| | | }) |
| | | |
| | | if (_card.wrap.doubleClick) { |
| | | _card.wrap.doubleClick = oriUids[_card.wrap.doubleClick] || '' |
| | | } |
| | | } |
| | | |
| | | this.updateComponent(_card) |
| | |
| | | * @description 卡片行外层信息更新(数据源,样式等) |
| | | */ |
| | | updateComponent = (card) => { |
| | | card.width = card.wrap.width |
| | | card.name = card.wrap.name |
| | | |
| | | if (!window.GLOB.styling || !card.errors) { // 样式修改时不做筛查 |
| | | card.errors = [] |
| | | |
| | |
| | | style.fontSize = card.wrap.fontSize || 14 |
| | | style.fontWeight = card.wrap.fontWeight || 'normal' |
| | | |
| | | MKEmitter.emit('changeStyle', ['font1', 'background', 'border', 'padding', 'margin', 'shadow'], style, this.getStyle) |
| | | MKEmitter.emit('changeStyle', ['font1', 'padding', 'margin'], style, this.getStyle) |
| | | } |
| | | |
| | | getStyle = (style) => { |
| | |
| | | _card.wrap.fontWeight = fontWeight |
| | | |
| | | this.updateComponent(_card) |
| | | } |
| | | |
| | | addColumns = () => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | |
| | | card.cols.push({ focus: true, uuid: Utils.getuuid(), label: 'label', field: '', type: 'text' }) |
| | | |
| | | this.setState({card}) |
| | | } |
| | | |
| | | addSearch = () => { |
| | | const { card } = this.state |
| | | |
| | | MKEmitter.emit('plusSearch', card.uuid, {uuid: Utils.getuuid(), focus: true, label: 'label', type: 'text', match: '='}, 'simple') |
| | | } |
| | | |
| | | addButton = () => { |
| | | const { card } = this.state |
| | | |
| | | let newcard = {} |
| | | newcard.uuid = Utils.getuuid() |
| | | newcard.focus = true |
| | | |
| | | newcard.label = 'label' |
| | | newcard.sqlType = '' |
| | | newcard.Ot = 'requiredSgl' |
| | | newcard.OpenType = 'pop' |
| | | newcard.icon = '' |
| | | newcard.class = 'green' |
| | | newcard.intertype = card.setting.interType || 'system' |
| | | newcard.innerFunc = card.setting.innerFunc || '' |
| | | newcard.sysInterface = card.setting.sysInterface || '' |
| | | newcard.outerFunc = card.setting.outerFunc || '' |
| | | newcard.interface = card.setting.interface || '' |
| | | newcard.execSuccess = 'grid' |
| | | newcard.execError = 'never' |
| | | newcard.verify = null |
| | | newcard.show = 'button' |
| | | newcard.style = {marginRight: '15px'} |
| | | |
| | | // 注册事件-添加按钮 |
| | | MKEmitter.emit('addButton', card.uuid, newcard) |
| | | } |
| | | |
| | | setSubConfig = (item) => { |
| | |
| | | this.updateComponent({...card, wrap: res}) |
| | | } |
| | | |
| | | clickComponent = (e) => { |
| | | if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') { |
| | | e.stopPropagation() |
| | | MKEmitter.emit('clickComponent', this.state.card) |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { card } = this.state |
| | | let options = ['action', 'search', 'form', 'cols'] |
| | | let _style = resetStyle(card.style) |
| | | |
| | | return ( |
| | | <div className="menu-normal-table-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}> |
| | | <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/> |
| | | <div className="menu-base-table-edit-box" style={card.style} id={card.uuid}> |
| | | <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <PlusOutlined className="plus" title="添加列" onClick={this.addColumns}/> |
| | | <PlusCircleOutlined className="plus" title="添加搜索" onClick={this.addSearch}/> |
| | | <PlusSquareOutlined className="plus" title="添加按钮" onClick={this.addButton}/> |
| | | <NormalForm title="表格设置" width={800} update={this.updateWrap} getForms={this.getWrapForms}> |
| | | <EditOutlined style={{color: '#1890ff'}} title="编辑"/> |
| | | </NormalForm> |
| | | <CopyComponent type="normaltable" card={card}/> |
| | | <PasteComponent config={card} options={options} updateConfig={this.updateComponent} /> |
| | | <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/> |
| | | <UserComponent config={card}/> |
| | | <DeleteOutlined className="close" title="删除组件" onClick={() => this.props.deletecomponent(card.uuid)} /> |
| | | <SettingComponent config={card} updateConfig={this.updateComponent} /> |
| | | </div> |
| | | } trigger="hover"> |
| | |
| | | <SearchComponent config={card} updatesearch={this.updateComponent}/> |
| | | <ActionComponent config={card} setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/> |
| | | <ColumnComponent config={card} updatecolumn={this.updateComponent}/> |
| | | <div className="component-name"> |
| | | <div className="center"> |
| | | <div className="title">{card.name}</div> |
| | | <div className="content"> |
| | | {card.errors && card.errors.map((err, index) => { |
| | | if (err.level === 0) { |
| | | return <span key={index} className="error">{err.detail}</span> |
| | | } else { |
| | | return <span key={index} className="waring">{err.detail};</span> |
| | | } |
| | | })} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | .menu-normal-table-edit-box { |
| | | .menu-base-table-edit-box { |
| | | position: relative; |
| | | box-sizing: border-box; |
| | | background: #ffffff; |
| | |
| | | .ant-btn.mk-link { |
| | | padding: 0; |
| | | } |
| | | } |
| | | .menu-normal-table-edit-box::after { |
| | | display: block; |
| | | content: ' '; |
| | | clear: both; |
| | | } |
| | | .menu-normal-table-edit-box:hover { |
| | | z-index: 1; |
| | | box-shadow: 0px 0px 4px #1890ff; |
| | | } |
| | |
| | | } |
| | | |
| | | const wrapForm = [ |
| | | { |
| | | type: 'text', |
| | | field: 'title', |
| | | label: '标题', |
| | | initval: wrap.title || '', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'text', |
| | | field: 'name', |
| | | label: '组件名称', |
| | | initval: wrap.name || '', |
| | | tooltip: '用于组件间的区分。', |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'number', |
| | | field: 'width', |
| | | label: '宽度', |
| | | initval: wrap.width || 24, |
| | | tooltip: '栅格布局,每行等分为24列。', |
| | | min: 1, |
| | | max: 24, |
| | | precision: 0, |
| | | required: true |
| | | }, |
| | | // { |
| | | // type: 'text', |
| | | // field: 'title', |
| | | // label: '标题', |
| | | // initval: wrap.title || '', |
| | | // required: false |
| | | // }, |
| | | // { |
| | | // type: 'text', |
| | | // field: 'name', |
| | | // label: '组件名称', |
| | | // initval: wrap.name || '', |
| | | // tooltip: '用于组件间的区分。', |
| | | // required: true |
| | | // }, |
| | | // { |
| | | // type: 'number', |
| | | // field: 'width', |
| | | // label: '宽度', |
| | | // initval: wrap.width || 24, |
| | | // tooltip: '栅格布局,每行等分为24列。', |
| | | // min: 1, |
| | | // max: 24, |
| | | // precision: 0, |
| | | // required: true |
| | | // }, |
| | | { |
| | | type: 'number', |
| | | field: 'height', |
| | | label: '高度', |
| | | label: '表格高度', |
| | | initval: wrap.height || '', |
| | | tooltip: '表格高度,空值时高度自适应。', |
| | | min: 10, |
| | |
| | | {value: 'always', label: '数据加载'}, |
| | | ] |
| | | }, |
| | | // { |
| | | // type: 'radio', |
| | | // field: 'show', |
| | | // label: '搜索按钮', |
| | | // initval: wrap.show || 'true', |
| | | // tooltip: '搜索条件存在时,可选择是否显示搜索按钮。', |
| | | // required: false, |
| | | // options: [ |
| | | // {value: 'true', label: '显示'}, |
| | | // {value: 'false', label: '隐藏'}, |
| | | // ] |
| | | // }, |
| | | { |
| | | type: 'radio', |
| | | field: 'mask', |
| | | label: '遮罩', |
| | | initval: wrap.mask || 'show', |
| | | tooltip: '数据加载时,是否显示加载中的遮罩。', |
| | | required: false, |
| | | options: [ |
| | | {value: 'show', label: '显示'}, |
| | | {value: 'hidden', label: '隐藏'}, |
| | | ] |
| | | }, |
| | | { |
| | | type: 'color', |
| | | field: 'borderColor', |
| | |
| | | tooltip: '默认值 #e8e8e8。', |
| | | required: false |
| | | }, |
| | | // { |
| | | // type: 'color', |
| | | // field: 'color', |
| | | // label: '字体颜色', |
| | | // initval: wrap.color || 'rgba(0, 0, 0, 0.65)', |
| | | // tooltip: '默认值 rgba(0, 0, 0, 0.65)。', |
| | | // required: false |
| | | // }, |
| | | // { |
| | | // type: 'number', |
| | | // field: 'fontSize', |
| | | // label: '字体大小', |
| | | // initval: wrap.fontSize || 14, |
| | | // min: 12, |
| | | // max: 30, |
| | | // precision: 0, |
| | | // required: false |
| | | // }, |
| | | // { |
| | | // type: 'number', |
| | | // field: 'advanceWidth', |
| | | // label: '高级搜索', |
| | | // initval: wrap.advanceWidth || 1000, |
| | | // tooltip: '高级搜索弹窗的宽度,注:当宽度值小于100时表示占窗口的百分比,大于100时表示宽度的绝对值。', |
| | | // min: 10, |
| | | // max: 3000, |
| | | // precision: 0, |
| | | // required: false, |
| | | // forbid: appType === 'mob' |
| | | // }, |
| | | { |
| | | type: 'select', |
| | | field: 'doubleClick', |
| | |
| | | format: 'array', // 组件属性 - 数据格式 |
| | | pageable: true, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | search: [], |
| | | action: [], |
| | |
| | | format: 'array', // 组件属性 - 数据格式 |
| | | pageable: true, // 组件属性 - 是否可分页 |
| | | switchable: true, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | search: [ |
| | | { origin: true, uuid: Utils.getuuid(), label: 'label', field: '', type: 'text', match: 'like' }, |
| | | { origin: true, uuid: Utils.getuuid(), label: 'label', field: '', type: 'select', match: 'equal' } |
| | | { origin: true, uuid: Utils.getuuid(), label: 'label', field: '', type: 'select', match: '=' } |
| | | ], |
| | | action: [ |
| | | { origin: true, uuid: Utils.getuuid(), label: '添加', intertype: 'system', OpenType: 'pop', execSuccess: 'grid', icon: 'plus', class: 'green', style: {color: 'rgb(255, 255, 255)', background: 'rgb(38, 194, 129)', marginRight: '15px'} }, |
| | |
| | | } |
| | | |
| | | .ant-tabs .ant-tabs-top-bar > .ant-tabs-nav-container { |
| | | min-height: 40px; |
| | | >.ant-tabs-tab-next:not(.ant-tabs-tab-arrow-show) + .ant-tabs-nav-wrap > .ant-tabs-nav-scroll > .ant-tabs-nav { |
| | | width: 100%; |
| | | > div > .ant-tabs-tab-disabled { |
| | |
| | | subtype: item.subtype, |
| | | config: item.config, |
| | | width: item.width || 24, |
| | | dataName: Utils.getdataName(), |
| | | name: name, |
| | | isNew: true // 新添加标志,用于初始化 |
| | | } |
New file |
| | |
| | | import React, { Component } from 'react' |
| | | import { Tabs } from 'antd' |
| | | import { is, fromJS } from 'immutable' |
| | | import { DndProvider, DragSource, DropTarget } from 'react-dnd' |
| | | |
| | | // Drag & Drop node |
| | | class TabNode extends Component { |
| | | render() { |
| | | const { connectDragSource, connectDropTarget, children } = this.props |
| | | |
| | | return connectDragSource(connectDropTarget(children)) |
| | | } |
| | | } |
| | | |
| | | const cardTarget = { |
| | | drop(props, monitor) { |
| | | const dragKey = monitor.getItem().index |
| | | const hoverKey = props.index |
| | | |
| | | if (dragKey === hoverKey) { |
| | | return; |
| | | } |
| | | |
| | | props.moveTabNode(dragKey, hoverKey) |
| | | monitor.getItem().index = hoverKey |
| | | } |
| | | } |
| | | |
| | | const cardSource = { |
| | | beginDrag(props) { |
| | | return { |
| | | id: props.id, |
| | | index: props.index, |
| | | } |
| | | } |
| | | } |
| | | |
| | | const WrapTabNode = DropTarget('DND_NODE', cardTarget, connect => ({ |
| | | connectDropTarget: connect.dropTarget(), |
| | | }))( |
| | | DragSource('DND_NODE', cardSource, (connect, monitor) => ({ |
| | | connectDragSource: connect.dragSource(), |
| | | isDragging: monitor.isDragging(), |
| | | }))(TabNode) |
| | | ) |
| | | |
| | | class DraggableTabs extends Component { |
| | | state = { |
| | | order: [] |
| | | } |
| | | |
| | | moveTabNode = (dragKey, hoverKey) => { |
| | | const newOrder = this.state.order.slice() |
| | | const { children } = this.props |
| | | |
| | | React.Children.forEach(children, c => { |
| | | if (newOrder.indexOf(c.key) === -1) { |
| | | newOrder.push(c.key) |
| | | } |
| | | }) |
| | | |
| | | const dragIndex = newOrder.indexOf(dragKey) |
| | | const hoverIndex = newOrder.indexOf(hoverKey) |
| | | |
| | | newOrder.splice(dragIndex, 1) |
| | | newOrder.splice(hoverIndex, 0, dragKey) |
| | | |
| | | this.setState({ |
| | | order: newOrder |
| | | }) |
| | | this.props.tabsMove(newOrder) |
| | | } |
| | | |
| | | renderTabBar = (props, DefaultTabBar) => ( |
| | | <DefaultTabBar {...props}> |
| | | {node => ( |
| | | <WrapTabNode key={node.key} index={node.key} moveTabNode={this.moveTabNode}> |
| | | {node} |
| | | </WrapTabNode> |
| | | )} |
| | | </DefaultTabBar> |
| | | ) |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) || |
| | | !is(fromJS(nextProps.children), fromJS(this.props.children)) || |
| | | nextProps.tabPosition !== this.props.tabPosition || |
| | | nextProps.type !== this.props.type |
| | | } |
| | | |
| | | render() { |
| | | const { order } = this.state |
| | | const { children, ...resProps } = this.props |
| | | const tabs = [] |
| | | React.Children.forEach(children, c => { |
| | | tabs.push(c) |
| | | }) |
| | | |
| | | const orderTabs = tabs.slice().sort((a, b) => { |
| | | const orderA = order.indexOf(a.key) |
| | | const orderB = order.indexOf(b.key) |
| | | |
| | | if (orderA !== -1 && orderB !== -1) { |
| | | return orderA - orderB |
| | | } |
| | | if (orderA !== -1) { |
| | | return -1 |
| | | } |
| | | if (orderB !== -1) { |
| | | return 1 |
| | | } |
| | | |
| | | const ia = tabs.indexOf(a) |
| | | const ib = tabs.indexOf(b) |
| | | |
| | | return ia - ib |
| | | }) |
| | | |
| | | return ( |
| | | <DndProvider> |
| | | <Tabs renderTabBar={this.renderTabBar} {...resProps}> |
| | | {orderTabs} |
| | | </Tabs> |
| | | </DndProvider> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default DraggableTabs |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | 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 { getTabForm, getTabsSetForm } from './options' |
| | | import './index.scss' |
| | | |
| | | 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 antvTabs extends Component { |
| | | static propTpyes = { |
| | | tabs: PropTypes.object, |
| | | deletecomponent: PropTypes.func, |
| | | updateConfig: PropTypes.func, |
| | | } |
| | | |
| | | state = { |
| | | appType: sessionStorage.getItem('appType'), |
| | | tabs: null, |
| | | editab: null, |
| | | defaultActiveKey: '' |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { tabs } = this.props |
| | | |
| | | if (tabs.isNew) { |
| | | let _tabs = { |
| | | uuid: tabs.uuid, |
| | | type: tabs.type, |
| | | tabId: tabs.tabId || '', |
| | | parentId: tabs.parentId || '', |
| | | subtype: tabs.subtype, |
| | | 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(), 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() |
| | | }) |
| | | } |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('submitSearch', this.getSearch) |
| | | MKEmitter.addListener('tabsChange', this.handleTabsChange) |
| | | MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新,清除快捷键设置 |
| | | */ |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | 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', ['background', 'border', 'padding', 'margin', 'shadow'], tabs.style, this.getStyle) |
| | | } |
| | | |
| | | getStyle = (style) => { |
| | | let _card = {...this.state.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)) || !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 |
| | | }) |
| | | this.props.updateConfig(component) |
| | | } |
| | | |
| | | updateTabComponent = (tab) => { |
| | | let tabs = fromJS(this.state.tabs).toJS() |
| | | |
| | | tabs.subtabs = tabs.subtabs.map(t => { |
| | | if (t.uuid === tab.uuid) { |
| | | return tab |
| | | } else { |
| | | return t |
| | | } |
| | | }) |
| | | |
| | | this.setState({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: '确定删除标签?', |
| | | content: '', |
| | | onOk() { |
| | | _this.setState({tabs}) |
| | | _this.props.updateConfig(tabs) |
| | | |
| | | if (uuids.length === 0) return |
| | | |
| | | MKEmitter.emit('delButtons', uuids) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | moveSwitch = (order) => { |
| | | let tabs = fromJS(this.state.tabs).toJS() |
| | | 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 { tabs, defaultActiveKey } = this.state |
| | | let _style = resetStyle(tabs.style) |
| | | |
| | | return ( |
| | | <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"> |
| | | <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 style={{textDecoration: tab.hide === 'true' ? 'line-through' : 'none'}}>{tab.icon ? <MkIcon type={tab.icon} /> : null}{tab.label}</span> |
| | | </Popover> |
| | | } 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> |
| | | ))} |
| | | </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 antvTabs |
New file |
| | |
| | | .menu-tabs-edit-box { |
| | | position: relative; |
| | | box-sizing: border-box; |
| | | background: #ffffff; |
| | | background-position: center center; |
| | | background-repeat: no-repeat; |
| | | background-size: cover; |
| | | |
| | | .ant-tabs-top-bar { |
| | | margin-bottom: 0; |
| | | } |
| | | .ant-tabs-top-content { |
| | | .tab-shell-inner { |
| | | padding-top: 15px; |
| | | } |
| | | } |
| | | .ant-tabs-left-content { |
| | | padding-left: 0; |
| | | } |
| | | .ant-tabs-right-content { |
| | | padding-right: 0; |
| | | } |
| | | .ant-tabs-bottom-bar { |
| | | margin-top: 0; |
| | | } |
| | | |
| | | >.anticon-tool { |
| | | position: absolute; |
| | | z-index: 2; |
| | | font-size: 16px; |
| | | right: 1px; |
| | | top: 1px; |
| | | cursor: pointer; |
| | | padding: 5px; |
| | | background: rgba(255, 255, 255, 0.55); |
| | | } |
| | | |
| | | .ant-tabs.ant-tabs-left, .ant-tabs.ant-tabs-bottom { |
| | | .tab-shell-inner { |
| | | padding-top: 25px; |
| | | } |
| | | } |
| | | |
| | | .ant-tabs-tabpane-active { |
| | | min-height: 200px; |
| | | } |
| | | .tab-shell-inner { |
| | | min-height: 100%; |
| | | } |
| | | |
| | | .ant-tabs .ant-tabs-top-bar > .ant-tabs-nav-container { |
| | | min-height: 40px; |
| | | >.ant-tabs-tab-next:not(.ant-tabs-tab-arrow-show) + .ant-tabs-nav-wrap > .ant-tabs-nav-scroll > .ant-tabs-nav { |
| | | width: 100%; |
| | | > div > .ant-tabs-tab-disabled { |
| | | float: right; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .ant-tabs .ant-tabs-left-bar .ant-tabs-tab { |
| | | text-align: right; |
| | | > span { |
| | | display: inline-block; |
| | | padding: 8px 24px; |
| | | } |
| | | } |
| | | .ant-tabs .ant-tabs-right-bar .ant-tabs-tab { |
| | | text-align: left; |
| | | > span { |
| | | display: inline-block; |
| | | padding: 8px 24px; |
| | | } |
| | | } |
| | | .ant-tabs-tab { |
| | | padding: 0px!important; |
| | | text-align: center; |
| | | > span { |
| | | display: inline-block; |
| | | padding: 12px 16px; |
| | | } |
| | | } |
| | | .ant-tabs-bottom .ant-tabs-bottom-bar .ant-tabs-ink-bar { |
| | | top: 0px; |
| | | } |
| | | .ant-tabs-card { |
| | | .ant-tabs-left-bar, .ant-tabs-right-bar { |
| | | .ant-tabs-tab { |
| | | > span { |
| | | padding: 0px 16px; |
| | | } |
| | | } |
| | | .ant-tabs-tab-active { |
| | | padding-left: 0px!important; |
| | | padding-right: 0px!important; |
| | | } |
| | | } |
| | | |
| | | .ant-tabs-card-bar { |
| | | .ant-tabs-tab { |
| | | > span { |
| | | display: inline-block; |
| | | padding: 0px 16px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .search-icon { |
| | | position: absolute; |
| | | top: 10px; |
| | | right: 40px; |
| | | font-size: 18px; |
| | | cursor: pointer; |
| | | padding: 3px; |
| | | } |
| | | } |
| | | .menu-tabs-edit-box:hover { |
| | | z-index: 1; |
| | | box-shadow: 0px 0px 4px #1890ff; |
| | | } |
| | | |
| | | .mob-shell { |
| | | .menu-tabs-edit-box.flex { |
| | | >.ant-tabs.ant-tabs-top, >.ant-tabs.ant-tabs-bottom { |
| | | >.ant-tabs-bar { |
| | | >.ant-tabs-nav-container { |
| | | >.ant-tabs-nav-wrap { |
| | | >.ant-tabs-nav-scroll { |
| | | >.ant-tabs-nav { |
| | | display: block; |
| | | >div { |
| | | display: flex; |
| | | >.ant-tabs-tab { |
| | | flex: 1; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | import MenuUtils from '@/utils/utils-custom.js' |
| | | |
| | | /** |
| | | * @description tab表单配置信息 |
| | | */ |
| | | export function getTabForm(tab, setting) { |
| | | let appType = sessionStorage.getItem('appType') |
| | | let roleList = sessionStorage.getItem('sysRoles') |
| | | |
| | | if (roleList) { |
| | | try { |
| | | roleList = JSON.parse(roleList) |
| | | } catch (e) { |
| | | roleList = [] |
| | | } |
| | | } else { |
| | | roleList = [] |
| | | } |
| | | |
| | | const tabForm = [ |
| | | { |
| | | type: 'text', |
| | | field: 'label', |
| | | label: '名称', |
| | | initval: tab.label || '', |
| | | required: true, |
| | | focus: true, |
| | | }, |
| | | { |
| | | type: 'mkicon', |
| | | field: 'icon', |
| | | label: '图标', |
| | | initval: tab.icon || '', |
| | | required: false, |
| | | allowClear: true, |
| | | }, |
| | | // { |
| | | // type: 'radio', |
| | | // field: 'hasSearch', |
| | | // label: '搜索', |
| | | // initval: tab.hasSearch || 'false', |
| | | // required: false, |
| | | // options: [ |
| | | // {value: 'false', label: '无'}, |
| | | // {value: 'icon', label: '有'}, |
| | | // ], |
| | | // forbid: appType !== 'mob' || setting.position !== 'top' || setting.display !== 'inline-block', |
| | | // span: 22 |
| | | // }, |
| | | { |
| | | type: 'text', |
| | | field: 'controlVal', |
| | | label: '隐藏标记', |
| | | initval: tab.controlVal || '', |
| | | tooltip: '当禁用字段值与隐藏标记相等时,标签页会隐藏。注:多个值请用逗号分隔。', |
| | | required: false, |
| | | }, |
| | | { |
| | | type: 'text', |
| | | field: 'selectVal', |
| | | label: '选中标记', |
| | | initval: tab.selectVal || '', |
| | | tooltip: '当选中字段值与选中标记相等时,标签页默认选中。', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'color', |
| | | field: 'backgroundColor', |
| | | label: '背景(内容区)', |
| | | initval: tab.backgroundColor || 'transparent', |
| | | required: false, |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'hide', |
| | | label: '隐藏', |
| | | initval: tab.hide || 'false', |
| | | required: false, |
| | | options: [ |
| | | {value: 'false', label: '否'}, |
| | | {value: 'true', label: '是'}, |
| | | ], |
| | | }, |
| | | { |
| | | type: 'multiselect', |
| | | field: 'blacklist', |
| | | label: '黑名单', |
| | | initval: tab.blacklist || [], |
| | | required: false, |
| | | options: roleList, |
| | | forbid: !!appType, |
| | | }, |
| | | ] |
| | | |
| | | return tabForm |
| | | } |
| | | |
| | | /** |
| | | * @description tabs表单配置信息 |
| | | */ |
| | | export function getTabsSetForm(setting, uuid) { |
| | | let appType = sessionStorage.getItem('appType') |
| | | let roleList = sessionStorage.getItem('sysRoles') |
| | | |
| | | let modules = MenuUtils.getSupModules(window.GLOB.customMenu.components, uuid) || [] |
| | | modules.push({ |
| | | value: 'preview', |
| | | label: '上一页(url参数)' |
| | | }) |
| | | |
| | | if (roleList) { |
| | | try { |
| | | roleList = JSON.parse(roleList) |
| | | } catch (e) { |
| | | roleList = [] |
| | | } |
| | | } else { |
| | | roleList = [] |
| | | } |
| | | |
| | | const tabForm = [ |
| | | { |
| | | type: 'text', |
| | | field: 'name', |
| | | label: '组件名称', |
| | | initval: setting.name || '', |
| | | tooltip: '用于组件间的区分。', |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'number', |
| | | field: 'width', |
| | | label: '宽度', |
| | | initval: setting.width || 24, |
| | | tooltip: '栅格布局,每行等分为24列。', |
| | | min: 1, |
| | | max: 24, |
| | | precision: 0, |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'select', |
| | | field: 'position', |
| | | label: '标签位置', |
| | | initval: setting.position || 'top', |
| | | required: true, |
| | | options: [ |
| | | {value: 'top', label: 'top'}, |
| | | {value: 'bottom', label: 'bottom'}, |
| | | {value: 'left', label: 'left'}, |
| | | {value: 'right', label: 'right'}, |
| | | ], |
| | | controlFields: [ |
| | | {field: 'display', values: ['top', 'bottom']}, |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'tabStyle', |
| | | label: '页签样式', |
| | | initval: setting.tabStyle || 'line', |
| | | tooltip: '标签位置为top时有效,默认值为line。', |
| | | required: true, |
| | | options: [ |
| | | {value: 'line', label: 'line'}, |
| | | {value: 'card', label: 'card'}, |
| | | ], |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'autoSwitch', |
| | | label: '自动切换', |
| | | initval: setting.autoSwitch || 'false', |
| | | tooltip: '存在两个及以上标签时有效。', |
| | | required: false, |
| | | options: [ |
| | | {value: 'true', label: '是'}, |
| | | {value: 'false', label: '否'}, |
| | | ], |
| | | controlFields: [ |
| | | {field: 'interval', values: ['true']}, |
| | | {field: 'tabLabel', values: ['true']}, |
| | | ] |
| | | }, |
| | | { |
| | | type: 'number', |
| | | field: 'interval', |
| | | label: '间隔(s)', |
| | | initval: setting.interval || 5, |
| | | min: 1, |
| | | max: 1000, |
| | | precision: 0, |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'tabLabel', |
| | | label: '标签栏', |
| | | initval: setting.tabLabel || 'show', |
| | | required: false, |
| | | options: [ |
| | | {value: 'show', label: '显示'}, |
| | | {value: 'hide', label: '隐藏'}, |
| | | ] |
| | | }, |
| | | { |
| | | type: 'cascader', |
| | | field: 'supModule', |
| | | label: '上级组件', |
| | | initval: setting.supModule || [], |
| | | tooltip: '标签组可以选择上级组件,填入禁用字段,用于控制标签隐藏。', |
| | | help: '用于控制标签页隐藏。', |
| | | required: false, |
| | | allowClear: true, |
| | | options: modules, |
| | | controlFields: [ |
| | | {field: 'controlField', notNull: true}, |
| | | ], |
| | | }, |
| | | { |
| | | type: 'text', |
| | | field: 'controlField', |
| | | label: '禁用字段', |
| | | initval: setting.controlField || '', |
| | | tooltip: '用于控制标签隐藏的字段,在标签中填入隐藏标记。', |
| | | required: true, |
| | | }, |
| | | { |
| | | type: 'text', |
| | | field: 'selectField', |
| | | label: '选中字段', |
| | | initval: setting.selectField || '', |
| | | tooltip: '用于控制标签页初始化选中,在标签中填入选中标记,注:数据源于url参数。', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'color', |
| | | field: 'backgroundColor', |
| | | label: '背景(标题栏)', |
| | | initval: setting.backgroundColor || 'transparent', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'permission', |
| | | label: '权限验证', |
| | | initval: setting.permission || 'false', |
| | | required: false, |
| | | options: [ |
| | | {value: 'true', label: '启用'}, |
| | | {value: 'false', label: '禁用'}, |
| | | ], |
| | | forbid: !appType |
| | | }, |
| | | { |
| | | type: 'multiselect', |
| | | field: 'blacklist', |
| | | label: '黑名单', |
| | | initval: setting.blacklist || [], |
| | | required: false, |
| | | options: roleList, |
| | | forbid: !!appType |
| | | }, |
| | | ] |
| | | |
| | | return tabForm |
| | | } |
| | |
| | | format: 'array', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | |
| | | type: card.type, |
| | | tabId: card.tabId || '', |
| | | parentId: card.parentId || '', |
| | | dataName: card.dataName || '', |
| | | format: 'array', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: true, // 组件属性 - 数据是否可切换 |
| | |
| | | subtype: item.subtype, |
| | | config: item.config, |
| | | width: item.width || 24, |
| | | dataName: Utils.getdataName(), |
| | | name: name, |
| | | floor: 1, // 组件的层级 |
| | | isNew: true // 新添加标志,用于初始化 |
| | |
| | | <div style={{display: 'inline-block'}}> |
| | | <Button className="mk-border-purple" onClick={this.trigger}><PictureOutlined /> 资源管理</Button> |
| | | <Modal |
| | | title="资源管理" |
| | | wrapClassName="picture-control-model" |
| | | wrapClassName="mk-pop-modal picture-control-model" |
| | | visible={visible} |
| | | width={1200} |
| | | maskClosable={false} |
| | |
| | | .picture-control-model { |
| | | .ant-modal { |
| | | top: 60px; |
| | | .ant-modal-body { |
| | | max-height: calc(100vh - 120px); |
| | | min-height: 510px; |
| | | padding: 10px 5px 24px; |
| | | } |
| | | } |
| | | .ant-tabs-tabpane { |
| | | padding-left: 3px; |
| | | padding-right: 3px; |
| | |
| | | |
| | | if (_type === 'cardcell') { |
| | | _parent = _p |
| | | MKEmitter.emit('changeCombineStyle', ['margin', 'padding', 'border', 'background', 'font']) |
| | | MKEmitter.emit('switchMultiStyle', 'open') |
| | | } else { |
| | | let getParents = (box) => { |
| | | box.components.forEach(item => { |
| | |
| | | getParents(menu) |
| | | } |
| | | |
| | | MKEmitter.emit('changeCombineStyle', ['margin', 'padding', 'border', 'background']) |
| | | MKEmitter.emit('switchMultiStyle', 'open') |
| | | } |
| | | |
| | | document.getElementById(card.uuid).classList.add('selected-control-element') |
| | |
| | | } |
| | | |
| | | if (components.length === 0) { |
| | | MKEmitter.emit('closeCombineStyle') |
| | | MKEmitter.emit('switchMultiStyle', 'close') |
| | | sessionStorage.setItem('style-control', 'true') |
| | | } |
| | | |
| | |
| | | document.getElementById(item.uuid).classList.remove('selected-control-element') |
| | | }) |
| | | |
| | | MKEmitter.emit('closeCombineStyle') |
| | | MKEmitter.emit('switchMultiStyle', 'close') |
| | | |
| | | this.setState({label: '批量调整', parent: null, components: []}) |
| | | } |
| | |
| | | import { is, fromJS } from 'immutable' |
| | | import { Collapse, Form, Col, InputNumber, Select, Radio, Drawer, Button } from 'antd' |
| | | import { |
| | | ColumnHeightOutlined, |
| | | FontSizeOutlined, |
| | | BoldOutlined, |
| | | LineHeightOutlined, |
| | |
| | | } |
| | | |
| | | state = { |
| | | options: [], |
| | | style: {}, |
| | | borposition: 'outer' |
| | | } |
| | |
| | | } |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('changeCombineStyle', this.initStyle) |
| | | MKEmitter.addListener('closeCombineStyle', this.closeStyle) |
| | | MKEmitter.addListener('switchMultiStyle', this.switchMultiStyle) |
| | | } |
| | | |
| | | /** |
| | |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | MKEmitter.removeListener('changeCombineStyle', this.initStyle) |
| | | MKEmitter.removeListener('closeCombineStyle', this.closeStyle) |
| | | MKEmitter.removeListener('switchMultiStyle', this.switchMultiStyle) |
| | | } |
| | | |
| | | closeStyle = () => { |
| | | this.setState({ |
| | | visible: false, |
| | | options: [] |
| | | }) |
| | | } |
| | | |
| | | initStyle = (options) => { |
| | | this.setState({ |
| | | visible: true, |
| | | style: {}, |
| | | options: options, |
| | | borposition: 'outer' |
| | | }) |
| | | switchMultiStyle = (type) => { |
| | | if (type === 'open') { |
| | | this.setState({ |
| | | visible: true, |
| | | style: {}, |
| | | borposition: 'outer' |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | visible: false |
| | | }) |
| | | } |
| | | } |
| | | |
| | | onCloseDrawer = () => { |
| | |
| | | } |
| | | |
| | | render () { |
| | | const { options, borposition } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | |
| | | > |
| | | <div className="menu-combine-style-controller"> |
| | | <Form {...formItemLayout}> |
| | | <Collapse expandIconPosition="right" destroyInactivePanel={true} defaultActiveKey={options[0]}> |
| | | {options.includes('height') ? <Panel header="高度" key="height"> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<ColumnHeightOutlined title="高度" />} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | <StyleInput defaultValue={''} options={['px', 'vh', 'vw']} onChange={this.changeHeight}/> |
| | | </Form.Item> |
| | | </Col> |
| | | </Panel> : null} |
| | | {options.includes('font') ? <Panel header="字体" key="font"> |
| | | <Collapse expandIconPosition="right" destroyInactivePanel={true} defaultActiveKey="margin"> |
| | | <Panel header="字体" key="font"> |
| | | <Col span={12}> |
| | | <Form.Item colon={false} label={<FontSizeOutlined title="字体大小"/>}> |
| | | <InputNumber defaultValue={''} min={12} max={100} precision={0} onChange={this.changeFontSize} /> |
| | |
| | | </Radio.Group> |
| | | </Form.Item> |
| | | </Col> |
| | | </Panel> : null} |
| | | {options.includes('background') ? <Panel header="背景" key="background"> |
| | | </Panel> |
| | | <Panel header="背景" key="background"> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | |
| | | <ColorSketch onChange={this.changeBackgroundColor} /> |
| | | </Form.Item> |
| | | </Col> |
| | | </Panel> : null} |
| | | {options.includes('border') ? <Panel header="边框" key="border"> |
| | | </Panel> |
| | | <Panel header="边框" key="border"> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | |
| | | label={<BorderOuterOutlined title="边框样式"/>} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | {borposition === 'outer' ? <Select defaultValue={'solid'} onChange={this.changeBorderStyle}> |
| | | <Select defaultValue={'solid'} onChange={this.changeBorderStyle}> |
| | | <Option value="solid">实线</Option> |
| | | <Option value="dotted">点划线</Option> |
| | | <Option value="dashed">虚线</Option> |
| | | <Option value="double">双线</Option> |
| | | </Select> : null} |
| | | {borposition === 'left' ? <Select defaultValue={'solid'} onChange={this.changeBorderStyle}> |
| | | <Option value="solid">实线</Option> |
| | | <Option value="dotted">点划线</Option> |
| | | <Option value="dashed">虚线</Option> |
| | | <Option value="double">双线</Option> |
| | | </Select> : null} |
| | | {borposition === 'right' ? <Select defaultValue={'solid'} onChange={this.changeBorderStyle}> |
| | | <Option value="solid">实线</Option> |
| | | <Option value="dotted">点划线</Option> |
| | | <Option value="dashed">虚线</Option> |
| | | <Option value="double">双线</Option> |
| | | </Select> : null} |
| | | {borposition === 'top' ? <Select defaultValue={'solid'} onChange={this.changeBorderStyle}> |
| | | <Option value="solid">实线</Option> |
| | | <Option value="dotted">点划线</Option> |
| | | <Option value="dashed">虚线</Option> |
| | | <Option value="double">双线</Option> |
| | | </Select> : null} |
| | | {borposition === 'bottom' ? <Select defaultValue={'solid'} onChange={this.changeBorderStyle}> |
| | | <Option value="solid">实线</Option> |
| | | <Option value="dotted">点划线</Option> |
| | | <Option value="dashed">虚线</Option> |
| | | <Option value="double">双线</Option> |
| | | </Select> : null} |
| | | </Select> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | |
| | | label={<ColumnWidthOutlined title="边框宽度"/>} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | {borposition === 'outer' ? <StyleInput defaultValue={''} options={['px']} onChange={this.changeBorderWidth}/> : null} |
| | | {borposition === 'left' ? <StyleInput defaultValue={''} options={['px']} onChange={this.changeBorderWidth}/> : null} |
| | | {borposition === 'right' ? <StyleInput defaultValue={''} options={['px']} onChange={this.changeBorderWidth}/> : null} |
| | | {borposition === 'top' ? <StyleInput defaultValue={''} options={['px']} onChange={this.changeBorderWidth}/> : null} |
| | | {borposition === 'bottom' ? <StyleInput defaultValue={''} options={['px']} onChange={this.changeBorderWidth}/> : null} |
| | | <StyleInput defaultValue={''} options={['px']} onChange={this.changeBorderWidth}/> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | |
| | | label={<BgColorsOutlined title="边框颜色"/>} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | {borposition === 'outer' ? <ColorSketch onChange={this.changeBorderColor} /> : null} |
| | | {borposition === 'left' ? <ColorSketch onChange={this.changeBorderColor} /> : null} |
| | | {borposition === 'right' ? <ColorSketch onChange={this.changeBorderColor} /> : null} |
| | | {borposition === 'top' ? <ColorSketch onChange={this.changeBorderColor} /> : null} |
| | | {borposition === 'bottom' ? <ColorSketch onChange={this.changeBorderColor} /> : null} |
| | | <ColorSketch onChange={this.changeBorderColor} /> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | |
| | | <StyleInput defaultValue={'0px'} options={['px', '%']} onChange={(val) => this.changeNormalStyle(val, 'borderRadius')}/> |
| | | </Form.Item> |
| | | </Col> |
| | | </Panel> : null} |
| | | {options.includes('shadow') ? <Panel header="阴影" key="shadow"> |
| | | </Panel> |
| | | <Panel header="阴影" key="shadow"> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | |
| | | <ColorSketch onChange={this.changeShadowColor} /> |
| | | </Form.Item> |
| | | </Col> |
| | | </Panel> : null} |
| | | {options.includes('margin') ? <Panel header="外边距" key="margin"> |
| | | </Panel> |
| | | <Panel header="外边距" key="margin"> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | |
| | | <StyleInput defaultValue={''} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'marginRight')}/> |
| | | </Form.Item> |
| | | </Col> |
| | | </Panel> : null} |
| | | {options.includes('padding') ? <Panel header="内边距" key="padding"> |
| | | </Panel> |
| | | <Panel header="内边距" key="padding"> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | |
| | | <StyleInput defaultValue={''} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'paddingRight')}/> |
| | | </Form.Item> |
| | | </Col> |
| | | </Panel> : null} |
| | | </Panel> |
| | | </Collapse> |
| | | </Form> |
| | | <div style={{textAlign: 'right'}}> |
| | |
| | | import React from 'react' |
| | | import { useDrag, useDrop } from 'react-dnd' |
| | | import { useDrop } from 'react-dnd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import './index.scss' |
| | |
| | | const AntvTabs = asyncComponent(() => import('@/menu/components/tabs/antv-tabs')) |
| | | const BaseTable = asyncComponent(() => import('@/menu/components/table/base-table')) |
| | | |
| | | const Card = ({ id, card, moveCard, findCard, delCard, updateConfig }) => { |
| | | const originalIndex = findCard(id).index |
| | | const [{ isDragging }, drag] = useDrag({ |
| | | item: { type: 'menu', id, originalIndex }, |
| | | collect: monitor => ({ |
| | | isDragging: monitor.isDragging(), |
| | | }), |
| | | }) |
| | | const Card = ({ id, card, delCard, updateConfig }) => { |
| | | const [, drop] = useDrop({ |
| | | accept: 'menu', |
| | | canDrop: () => true, |
| | | drop: (item) => { |
| | | const { id: draggedId, originalIndex } = item |
| | | if (originalIndex === undefined) { |
| | | item.dropTargetId = id |
| | | } else if (draggedId) { |
| | | if (draggedId === id) return |
| | | const { index: originIndex } = findCard(draggedId) |
| | | |
| | | if (originIndex === -1) return |
| | | |
| | | const { index: overIndex } = findCard(id) |
| | | |
| | | moveCard(draggedId, overIndex) |
| | | } |
| | | item.dropTargetId = id |
| | | } |
| | | }) |
| | | |
| | | let style = { opacity: 1} |
| | | if (isDragging) { |
| | | style = { opacity: 0.3} |
| | | } |
| | | |
| | | const getCardComponent = () => { |
| | | if (card.type === 'table') { |
| | | return (<BaseTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | return (<BaseTable card={card} updateConfig={updateConfig}/>) |
| | | } else if (card.type === 'tabs') { |
| | | return (<AntvTabs tabs={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } |
| | | } |
| | | return ( |
| | | <div className={'ant-col mk-component-card ant-col-' + (card.width || 24)} ref={node => drag(drop(node))} style={style}> |
| | | <div className={'ant-col mk-component-card ant-col-' + (card.width || 24)} ref={node => drop(node)}> |
| | | {getCardComponent()} |
| | | </div> |
| | | ) |
| | |
| | | |
| | | const Container = ({menu, handleList }) => { |
| | | const [cards, setCards] = useState(menu.components) |
| | | const moveCard = (id, atIndex) => { |
| | | const { card, index } = findCard(id) |
| | | const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] }) |
| | | handleList({...menu, components: _cards}) |
| | | setCards(_cards) |
| | | } |
| | | |
| | | if (menu.components.length > cards.length) { |
| | | setCards(menu.components) |
| | |
| | | delete item.added // 删除组件添加标记 |
| | | return |
| | | } |
| | | |
| | | let name = '' |
| | | let names = { |
| | | tabs: '标签组' |
| | | } |
| | | let i = 1 |
| | | |
| | | while (!name && names[item.component]) { |
| | | let _name = names[item.component] + i |
| | | if (menu.components.filter(com => com.name === _name).length === 0) { |
| | | name = _name |
| | | } |
| | | i++ |
| | | } |
| | | |
| | | let newcard = { |
| | | uuid: Utils.getuuid(), |
| | | type: item.component, |
| | | subtype: item.subtype, |
| | | config: item.config, |
| | | width: item.width || 24, |
| | | dataName: Utils.getdataName(), |
| | | name: name, |
| | | floor: 1, // 组件的层级 |
| | | isNew: true // 新添加标志,用于初始化 |
| | | } |
| | | |
| | |
| | | id={card.uuid} |
| | | key={card.uuid} |
| | | card={card} |
| | | moveCard={moveCard} |
| | | delCard={deleteCard} |
| | | findCard={findCard} |
| | | updateConfig={updateConfig} |
| | |
| | | margin-bottom: 15px; |
| | | .field-plus { |
| | | line-height: 35px; |
| | | padding-left: 16px; |
| | | >.anticon-plus { |
| | | color: #26C281; |
| | | padding: 2px 5px; |
| | |
| | | format: 'object', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | |
| | | format: 'object', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | |
| | | format: 'object', // 组件属性 - 数据格式 |
| | | pageable: false, // 组件属性 - 是否可分页 |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: card.dataName || '', |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | | setting: { interType: 'system' }, |
| | |
| | | } |
| | | |
| | | .ant-tabs-bar.ant-tabs-top-bar { |
| | | min-height: 32px; |
| | | margin-bottom: 0; |
| | | } |
| | | .ant-tabs.ant-tabs-left, .ant-tabs.ant-tabs-bottom { |
| | |
| | | subtype: item.subtype, |
| | | config: item.config, |
| | | width: item.width || 24, |
| | | dataName: Utils.getdataName(), |
| | | name: name, |
| | | isNew: true // 新添加标志,用于初始化 |
| | | } |
| | |
| | | subtype: item.subtype, |
| | | config: item.config, |
| | | width: item.width || 24, |
| | | dataName: Utils.getdataName(), |
| | | name: name, |
| | | floor: 1, // 组件的层级 |
| | | isNew: true // 新添加标志,用于初始化 |
| | |
| | | type: card.type, |
| | | tabId: card.tabId || '', |
| | | parentId: card.parentId || '', |
| | | dataName: card.dataName || '', |
| | | width: card.width || 24, |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | |
| | | let _card = { |
| | | uuid: card.uuid, |
| | | type: card.type, |
| | | dataName: card.dataName || '', |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | | wrap: { name: card.name, width: card.width || 1200, height: 50 }, |
| | |
| | | subtype: item.subtype, |
| | | config: item.config, |
| | | width: item.width || 24, |
| | | dataName: Utils.getdataName(), |
| | | name: name, |
| | | floor: 1, // 组件的层级 |
| | | isNew: true // 新添加标志,用于初始化 |
| | |
| | | if (!item.setting || item.setting.interType !== 'system') return |
| | | if (!item.format) return |
| | | |
| | | if (item.dataName && (!item.pageable || (item.pageable && !item.setting.laypage)) && item.setting.onload === 'true' && item.setting.sync === 'true') { |
| | | if ((!item.pageable || (item.pageable && !item.setting.laypage)) && item.setting.onload === 'true' && item.setting.sync === 'true') { |
| | | let searchlist = [] |
| | | if (item.search && item.search.length > 0) { |
| | | searchlist = Utils.initMainSearch(item.search) |
| | |
| | | if (!item.setting || item.setting.interType !== 'system') return |
| | | if (!item.format) return |
| | | |
| | | if (item.dataName && (!item.pageable || (item.pageable && !item.setting.laypage)) && item.setting.onload === 'true' && item.setting.sync === 'true') { |
| | | if ((!item.pageable || (item.pageable && !item.setting.laypage)) && item.setting.onload === 'true' && item.setting.sync === 'true') { |
| | | let searchlist = [] |
| | | if (item.search && item.search.length > 0) { |
| | | searchlist = Utils.initMainSearch(item.search) |
| | |
| | | |
| | | component.setting.customScript = _customScript // 整理后自定义脚本 |
| | | |
| | | // floor 组件的层级 |
| | | // dataName 系统生成的数据源名称 |
| | | if (component.setting.sync === 'true') { |
| | | component.dataName = Utils.getdataName() |
| | | } |
| | | |
| | | // floor 组件的层级 |
| | | // pageable 是否分页,组件属性,不分页的组件才可以统一查询 |
| | | if (params && component.dataName && (!component.pageable || (component.pageable && !component.setting.laypage)) && component.setting.onload === 'true' && component.setting.sync === 'true') { |
| | | if (params && (!component.pageable || (component.pageable && !component.setting.laypage)) && component.setting.onload === 'true' && component.setting.sync === 'true') { |
| | | let searchlist = [] |
| | | if (component.search && component.search.length > 0) { |
| | | searchlist = Utils.initMainSearch(component.search) |
| | |
| | | resourceType: '0', |
| | | options: [], |
| | | orderType: 'asc', |
| | | match: 'equal', |
| | | match: '=', |
| | | }, { |
| | | origin: true, |
| | | uuid: Utils.getuuid(), |
| | |
| | | import Utils from '@/utils/utils.js' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | |
| | | const CommonDict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | |
| | | class CommonTableBaseData { |
| | | baseConfig = { |
| | |
| | | resourceType: '0', |
| | | options: [], |
| | | orderType: 'asc', |
| | | match: 'equal', |
| | | match: '=', |
| | | }, { |
| | | origin: true, |
| | | uuid: Utils.getuuid(), |
| | |
| | | Align: 'center', |
| | | IsSort: 'false', |
| | | uuid: Utils.getuuid(), |
| | | label: CommonDict['model.operation'], |
| | | label: '操作', |
| | | type: 'action', |
| | | style: 'button', |
| | | show: 'horizontal', |
| | |
| | | searchItems = [ |
| | | { |
| | | type: 'search', |
| | | label: CommonDict['model.form.text'], |
| | | label: '文本', |
| | | subType: 'text', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'search', |
| | | label: CommonDict['model.form.select'], |
| | | label: '下拉选择', |
| | | subType: 'select', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'search', |
| | | label: CommonDict['model.form.multiselect'], |
| | | label: '下拉多选', |
| | | subType: 'multiselect', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'search', |
| | | label: CommonDict['model.form.link'], |
| | | label: '联动菜单', |
| | | subType: 'link', |
| | | url: '' |
| | | }, |
| | |
| | | }, |
| | | { |
| | | type: 'search', |
| | | label: CommonDict['model.form.datemonth'], |
| | | label: '日期(月)', |
| | | subType: 'datemonth', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'search', |
| | | label: CommonDict['model.form.daterange'], |
| | | label: '日期(区间)', |
| | | subType: 'daterange', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'search', |
| | | label: CommonDict['model.form.dategroup'], |
| | | label: '日期(组合)', |
| | | subType: 'group', |
| | | url: '' |
| | | } |
| | |
| | | actionItems = [ |
| | | { |
| | | type: 'action', |
| | | label: CommonDict['model.form.popform'], |
| | | label: '弹窗(表单)', |
| | | subType: 'pop', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'action', |
| | | label: CommonDict['model.form.prompt'], |
| | | label: '提示框', |
| | | subType: 'prompt', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'action', |
| | | label: CommonDict['model.form.exec'], |
| | | label: '直接执行', |
| | | subType: 'exec', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'action', |
| | | label: CommonDict['model.form.excelIn'], |
| | | label: '导入Excel', |
| | | subType: 'excelIn', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'action', |
| | | label: CommonDict['model.form.excelOut'], |
| | | label: '导出Excel', |
| | | subType: 'excelOut', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'action', |
| | | label: CommonDict['model.form.popview'], |
| | | label: '弹窗(标签)', |
| | | subType: 'popview', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'action', |
| | | label: CommonDict['model.form.tab'], |
| | | label: '标签页', |
| | | subType: 'tab', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'action', |
| | | label: CommonDict['model.form.newpage'], |
| | | label: '新页面', |
| | | subType: 'innerpage', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'action', |
| | | label: CommonDict['model.form.funcbutton'], |
| | | label: '功能按钮', |
| | | subType: 'funcbutton', |
| | | url: '' |
| | | } |
| | |
| | | columnItems = [ |
| | | { |
| | | type: 'columns', |
| | | label: CommonDict['model.form.text'], |
| | | label: '文本', |
| | | subType: 'text', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'columns', |
| | | label: CommonDict['model.form.number'], |
| | | label: '数字', |
| | | subType: 'number', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'columns', |
| | | label: CommonDict['model.form.picture'], |
| | | label: '图片', |
| | | subType: 'picture', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'columns', |
| | | label: CommonDict['model.form.href'], |
| | | label: '链接', |
| | | subType: 'link', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'columns', |
| | | label: CommonDict['model.form.textarea'], |
| | | label: '多行文本', |
| | | subType: 'textarea', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'columns', |
| | | label: CommonDict['model.form.colspan'], |
| | | label: '合并列', |
| | | subType: 'colspan', |
| | | url: '' |
| | | }, |
| | |
| | | tabItems = [ |
| | | { |
| | | type: 'tabs', |
| | | label: CommonDict['model.menu.tab.subtable'], |
| | | label: '子表', |
| | | subType: 'SubTable', |
| | | } |
| | | ] |
| | |
| | | Align: 'center', |
| | | IsSort: 'false', |
| | | uuid: Utils.getuuid(), |
| | | label: this.state.dict['model.operation'], |
| | | label: '操作', |
| | | type: 'action', |
| | | style: 'button', |
| | | show: 'horizontal', |
| | |
| | | Align: 'center', |
| | | IsSort: 'false', |
| | | uuid: Utils.getuuid(), |
| | | label: this.state.dict['model.operation'], |
| | | label: '操作', |
| | | type: 'action', |
| | | style: 'button', |
| | | show: 'horizontal', |
| | |
| | | value="请选择表名" |
| | | onSelect={this.onTableChange} |
| | | dropdownClassName="mk-tables" |
| | | dropdownMatchSelectWidth={false} |
| | | showArrow={false} |
| | | getPopupContainer={() => containerId ? document.getElementById(containerId) : document.body} |
| | | filterOption={(input, option) => { |
| | |
| | | >.ant-form-item-label { |
| | | width: 33.33333333%; |
| | | } |
| | | } |
| | | .mk-tables { |
| | | max-width: 300px; |
| | | } |
| | |
| | | resourceType: '0', |
| | | options: [], |
| | | orderType: 'asc', |
| | | match: 'equal', |
| | | match: '=', |
| | | }, { |
| | | origin: true, |
| | | uuid: Utils.getuuid(), |
| | |
| | | Align: 'center', |
| | | IsSort: 'false', |
| | | uuid: Utils.getuuid(), |
| | | label: CommonDict['model.operation'], |
| | | label: '操作', |
| | | type: 'action', |
| | | style: 'button', |
| | | show: 'horizontal', |
| | |
| | | label: Formdict['header.form.match'], |
| | | initVal: card.match || 'like', |
| | | required: true, |
| | | options: [{ |
| | | value: 'like', |
| | | text: 'like' |
| | | }, { |
| | | value: 'equal', |
| | | text: 'equal' |
| | | }, { |
| | | value: 'greater', |
| | | text: '>' |
| | | }, { |
| | | value: 'less', |
| | | text: '<' |
| | | }, { |
| | | value: 'greaterequal', |
| | | text: '>=' |
| | | }] |
| | | options: [] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | |
| | | } |
| | | |
| | | /** |
| | | * @description 数据源名称,用于统一查询 |
| | | * @return {String} name |
| | | * @description 组件名加后缀 |
| | | */ |
| | | static getdataName () { |
| | | static getSignName () { |
| | | let name = [] |
| | | let _options = 'abcdefghigklmnopqrstuvwxyz' |
| | | for (let i = 0; i < 6; i++) { |
| | | for (let i = 0; i < 3; i++) { |
| | | name.push(_options.substr(Math.floor(Math.random() * 26), 1)) |
| | | } |
| | | name.splice(3, 0, new Date().getTime()) |
| | | return name.join('') |
| | | return (Math.floor(Math.random()*10) + name.join('')).toUpperCase() |
| | | } |
| | | |
| | | /** |
| | |
| | | |
| | | item.uuid = _uuid |
| | | |
| | | if (item.dataName) { |
| | | item.dataName = this.getdataName() |
| | | } |
| | | |
| | | // 重置组件名称 |
| | | let sign = this.getdataName().toUpperCase().substr(-4) |
| | | let sign = this.getSignName() |
| | | if (item.plot) { // 图表 |
| | | item.plot.name = item.plot.name + sign |
| | | item.name = item.plot.name |
| | |
| | | component.setting.customScript = _customScript // 整理后自定义脚本 |
| | | |
| | | // floor 组件的层级 |
| | | // dataName 系统生成的数据源名称 |
| | | // pageable 是否分页,组件属性,不分页的组件才可以统一查询 |
| | | if (component.dataName && component.setting.sync === 'true') { |
| | | if (component.setting.sync === 'true') { |
| | | component.dataName = Utils.getdataName() |
| | | let param = this.getDefaultParam(component) |
| | | _pars.push(param) |
| | | } else { |
| | |
| | | headerStyle: {}, parentId: '', width: 24, scripts: [], pageable: false, |
| | | wrap: {name: 'logo', width: 24, datatype: 'static', cardType: '', blacklist: []}, |
| | | name: 'logo', floor: 1, switchable: true, |
| | | setting:{interType: 'system'}, tabId: '', style:{paddingTop: '8vh', paddingBottom: '10vh'}, dataName: Utils.getuuid(), format: 'object', subtype: 'propcard', type: 'card', uuid: Utils.getuuid(), columns: [] |
| | | setting:{interType: 'system'}, tabId: '', style:{paddingTop: '8vh', paddingBottom: '10vh'}, format: 'object', subtype: 'propcard', type: 'card', uuid: Utils.getuuid(), columns: [] |
| | | }) |
| | | |
| | | config.components.push({ |
| | |
| | | floor: 1, |
| | | tabId: '', |
| | | parentId: '', |
| | | dataName: '', |
| | | width: 24, |
| | | name: '用户绑定', |
| | | subtype: 'bindlogin', |
| | |
| | | headerStyle: {}, parentId: '', width: 24, scripts: [], pageable: false, |
| | | wrap: {name: 'Power', width: 24, datatype: 'static', cardType: '', blacklist: []}, |
| | | name: 'Power', floor: 1, switchable: true, |
| | | setting:{interType: 'system'}, tabId: '', style:{}, dataName: Utils.getuuid(), format: 'object', subtype: 'propcard', type: 'card', uuid: Utils.getuuid(), columns: [] |
| | | setting:{interType: 'system'}, tabId: '', style:{}, format: 'object', subtype: 'propcard', type: 'card', uuid: Utils.getuuid(), columns: [] |
| | | }) |
| | | } |
| | | |
| | |
| | | import Utils, { setGLOBFuncs } from '@/utils/utils.js' |
| | | import antdZhCN from 'antd/es/locale/zh_CN' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import SourceElement from '@/templates/zshare/dragsource' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import Source from './source' |
| | | |
| | | import '@/assets/css/design.scss' |
| | | import './index.scss' |
| | |
| | | const _locale = antdZhCN |
| | | |
| | | const MenuForm = asyncComponent(() => import('./menuform')) |
| | | const TableSource = asyncComponent(() => import('./tablesource')) |
| | | const Header = asyncComponent(() => import('@/menu/header')) |
| | | const MenuShell = asyncComponent(() => import('@/menu/tableshell')) |
| | | const BgController = asyncComponent(() => import('@/pc/bgcontroller')) |
| | | const StyleController = asyncComponent(() => import('@/menu/stylecontroller')) |
| | | const ReplaceField = asyncComponent(() => import('@/menu/replaceField')) |
| | | const Versions = asyncComponent(() => import('@/menu/versions')) |
| | | const SysInterface = asyncComponent(() => import('@/menu/sysinterface')) |
| | | const UrlFieldComponent = asyncComponent(() => import('@/menu/urlfieldcomponent')) |
| | | const PictureController = asyncComponent(() => import('@/menu/picturecontroller')) |
| | | const ModalController = asyncComponent(() => import('@/menu/modalconfig/controller')) |
| | | const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent')) |
| | | |
| | |
| | | MKEmitter.addListener('modalStatus', this.modalStatus) |
| | | MKEmitter.addListener('changePopview', this.initPopview) |
| | | MKEmitter.addListener('triggerMenuSave', this.triggerMenuSave) |
| | | MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle) |
| | | MKEmitter.addListener('updateCustomComponent', this.updateCustomComponent) |
| | | setTimeout(() => { |
| | | if (sessionStorage.getItem('app_custom_components')) { |
| | |
| | | MKEmitter.removeListener('modalStatus', this.modalStatus) |
| | | MKEmitter.removeListener('changePopview', this.initPopview) |
| | | MKEmitter.removeListener('triggerMenuSave', this.triggerMenuSave) |
| | | MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle) |
| | | MKEmitter.removeListener('updateCustomComponent', this.updateCustomComponent) |
| | | } |
| | | |
| | |
| | | }) |
| | | }) |
| | | this.setState({customComponents: coms}) |
| | | } |
| | | |
| | | updateComponentStyle = (parentId, keys, style) => { |
| | | const { config } = this.state |
| | | |
| | | if (config.uuid !== parentId) return |
| | | |
| | | let components = config.components.map(item => { |
| | | if (keys.includes(item.uuid)) { |
| | | item.style = {...item.style, ...style} |
| | | } |
| | | return item |
| | | }) |
| | | |
| | | this.setState({ |
| | | config: {...config, components}, |
| | | comloading: true |
| | | }, () => { |
| | | this.setState({ |
| | | comloading: false |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | initPopview = (card, btn) => { |
| | |
| | | {config ? <TableComponent config={config} updatetable={this.updateConfig}/> : null} |
| | | {config ? <Paragraph style={{padding: '15px 0px 0px 18px'}} copyable={{ text: MenuId }}>菜单ID</Paragraph> : null} |
| | | </Panel> |
| | | <Panel header="搜索" key="search"> |
| | | {Source.searchItems.map((item, index) => (<SourceElement key={index} content={item}/>))} |
| | | </Panel> |
| | | <Panel header="按钮" key="action"> |
| | | {Source.actionItems.map((item, index) => (<SourceElement key={index} content={item}/>))} |
| | | </Panel> |
| | | <Panel header="显示列" key="cols"> |
| | | {Source.columnItems.map((item, index) => (<SourceElement key={index} content={item}/>))} |
| | | </Panel> |
| | | <Panel header="组件" key="component"> |
| | | {Source.menuItems.map((item, index) => (<TableSource key={index} item={item}/>))} |
| | | </Panel> |
| | | <Panel header="页面样式" key="background"> |
| | | {config ? <BgController config={config} updateConfig={this.updateConfig} /> : null} |
| | | </Panel> |
| | |
| | | <div> |
| | | <Versions MenuId={MenuId} open_edition={config ? config.open_edition : ''}/> |
| | | <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/> |
| | | <SysInterface config={config} updateConfig={this.updateConfig}/> |
| | | <PictureController/> |
| | | <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={config && config.enabled} onChange={this.onEnabledChange} /> |
| | | <Button type="primary" id="save-config" onClick={this.submitConfig} loading={menuloading}>保存</Button> |
| | | <Button type="default" onClick={this.closeView}>关闭</Button> |
New file |
| | |
| | | import NormalTable from '@/assets/mobimg/normal-table.png' |
| | | |
| | | export default { |
| | | searchItems: [ |
| | | { |
| | | type: 'search', |
| | | label: '文本', |
| | | subType: 'text', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'search', |
| | | label: '下拉选择', |
| | | subType: 'select', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'search', |
| | | label: '下拉多选', |
| | | subType: 'multiselect', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'search', |
| | | label: '联动菜单', |
| | | subType: 'link', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'search', |
| | | label: '选项卡', |
| | | subType: 'checkcard', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'search', |
| | | label: '日期(天)', |
| | | subType: 'date', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'search', |
| | | label: '日期(周)', |
| | | subType: 'dateweek', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'search', |
| | | label: '日期(月)', |
| | | subType: 'datemonth', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'search', |
| | | label: '日期(区间)', |
| | | subType: 'daterange', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'search', |
| | | label: '日期(组合)', |
| | | subType: 'group', |
| | | url: '' |
| | | } |
| | | ], |
| | | actionItems: [ |
| | | { |
| | | type: 'action', |
| | | label: '弹窗(表单)', |
| | | subType: 'pop', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'action', |
| | | label: '提示框', |
| | | subType: 'prompt', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'action', |
| | | label: '直接执行', |
| | | subType: 'exec', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'action', |
| | | label: '导入Excel', |
| | | subType: 'excelIn', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'action', |
| | | label: '导出Excel', |
| | | subType: 'excelOut', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'action', |
| | | label: '弹窗(标签)', |
| | | subType: 'popview', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'action', |
| | | label: '标签页', |
| | | subType: 'tab', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'action', |
| | | label: '新页面', |
| | | subType: 'innerpage', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'action', |
| | | label: '功能按钮', |
| | | subType: 'funcbutton', |
| | | url: '' |
| | | } |
| | | ], |
| | | columnItems: [ |
| | | { |
| | | type: 'columns', |
| | | label: '文本', |
| | | subType: 'text', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'columns', |
| | | label: '数字', |
| | | subType: 'number', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'columns', |
| | | label: '图片', |
| | | subType: 'picture', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'columns', |
| | | label: '链接', |
| | | subType: 'link', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'columns', |
| | | label: '多行文本', |
| | | subType: 'textarea', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'columns', |
| | | label: '合并列', |
| | | subType: 'colspan', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'columns', |
| | | label: '序号', |
| | | subType: 'index', |
| | | url: '' |
| | | } |
| | | ], |
| | | tabItems: [ |
| | | { |
| | | type: 'tabs', |
| | | label: '子表', |
| | | subType: 'SubTable', |
| | | } |
| | | ], |
| | | menuItems: [ |
| | | { type: 'menu', url: NormalTable, component: 'table', subtype: 'basetable', title: '子表' } |
| | | ] |
| | | } |
| | | |
New file |
| | |
| | | import React from 'react' |
| | | import { useDrag } from 'react-dnd' |
| | | import './index.scss' |
| | | |
| | | const TableElement = ({item}) => { |
| | | const [, drag] = useDrag({ item }) |
| | | return ( |
| | | <div className="menu-source-item"> |
| | | <div className="property"><span>{item.title}</span></div> |
| | | <img ref={drag} src={item.url} alt=""/> |
| | | </div> |
| | | ) |
| | | } |
| | | export default TableElement |
New file |
| | |
| | | .menu-source-item { |
| | | display: inline-block; |
| | | width: 100%; |
| | | margin-bottom: 15px; |
| | | height: auto; |
| | | min-height: 70px; |
| | | |
| | | .property { |
| | | font-size: 16px; |
| | | color: rgba(0, 0, 0, 0.65); |
| | | margin-bottom: 2px; |
| | | } |
| | | |
| | | img { |
| | | width: 100%; |
| | | cursor: move; |
| | | box-shadow: 0px 0px 1px #1890ff; |
| | | } |
| | | } |