From 4751cbd63d9f24ab2aaa5c5930a7aca0263471c0 Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期一, 19 四月 2021 23:36:51 +0800 Subject: [PATCH] 2021-04-19 --- src/mob/components/navbar/normal-navbar/menusetting/index.jsx | 62 ++ src/mob/components/navbar/normal-navbar/index.jsx | 181 ++++++++ src/mob/components/navbar/normal-navbar/menusetting/menutable/index.jsx | 185 ++++++++ src/mob/components/navbar/normal-navbar/menusetting/menuform/index.jsx | 205 +++++++++ src/mob/components/navbar/normal-navbar/menusetting/menuform/index.scss | 0 src/pc/menushell/card.jsx | 19 src/mob/components/navbar/normal-navbar/index.scss | 133 ++++++ src/menu/components/tabs/antv-tabs/index.scss | 5 src/mob/components/navbar/normal-navbar/wrapsetting/settingform/index.jsx | 102 ++++ src/mob/components/navbar/normal-navbar/wrapsetting/settingform/index.scss | 11 /dev/null | 38 - src/templates/modalconfig/dragelement/index.jsx | 1 src/mob/mobshell/card.jsx | 40 + src/utils/option.js | 134 ------ src/mob/components/navbar/normal-navbar/menusetting/index.scss | 11 src/mob/components/navbar/normal-navbar/wrapsetting/index.scss | 7 src/mob/components/navbar/normal-navbar/menusetting/menutable/index.scss | 23 + src/mob/components/navbar/normal-navbar/wrapsetting/index.jsx | 83 +++ 18 files changed, 1,044 insertions(+), 196 deletions(-) diff --git a/src/menu/components/tabs/antv-tabs/index.scss b/src/menu/components/tabs/antv-tabs/index.scss index 42be21b..8282c7b 100644 --- a/src/menu/components/tabs/antv-tabs/index.scss +++ b/src/menu/components/tabs/antv-tabs/index.scss @@ -37,7 +37,6 @@ } .ant-tabs .ant-tabs-left-bar .ant-tabs-tab { - padding: 0px; text-align: right; > span { display: inline-block; @@ -45,7 +44,6 @@ } } .ant-tabs .ant-tabs-right-bar .ant-tabs-tab { - padding: 0px; text-align: left; > span { display: inline-block; @@ -53,7 +51,7 @@ } } .ant-tabs-tab { - padding: 0px; + padding: 0px!important; text-align: center; > span { display: inline-block; @@ -78,7 +76,6 @@ .ant-tabs-card-bar { .ant-tabs-tab { - padding: 0px; > span { display: inline-block; padding: 0px 16px; diff --git a/src/mob/components/navbar/normal-navbar/index.jsx b/src/mob/components/navbar/normal-navbar/index.jsx new file mode 100644 index 0000000..7f03f32 --- /dev/null +++ b/src/mob/components/navbar/normal-navbar/index.jsx @@ -0,0 +1,181 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Icon, Popover } from 'antd' + +import asyncIconComponent from '@/utils/asyncIconComponent' + +import MKEmitter from '@/utils/events.js' +import zhCN from '@/locales/zh-CN/model.js' +import enUS from '@/locales/en-US/model.js' +import './index.scss' + +const WrapComponent = asyncIconComponent(() => import('./wrapsetting')) +const MenuComponent = asyncIconComponent(() => import('./menusetting')) + +class NormalNavbar extends Component { + static propTpyes = { + card: PropTypes.object, + deletecomponent: PropTypes.func, + updateConfig: PropTypes.func, + } + + state = { + dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, + card: null, + back: false + } + + UNSAFE_componentWillMount () { + const { card } = this.props + + if (card.isNew) { + let _card = { + uuid: card.uuid, + type: card.type, + floor: card.floor, + dataName: '', + width: card.width || 24, + name: card.name, + subtype: card.subtype, + wrap: { name: card.name, width: card.width || 1200 }, + style: { }, + menus: [], + } + + if (card.config) { + let config = fromJS(card.config).toJS() + + _card.wrap = config.wrap + _card.wrap.name = card.name + _card.style = config.style + } + + this.setState({ + card: _card + }) + this.props.updateConfig(_card) + } else { + this.setState({ + card: fromJS(card).toJS() + }) + } + } + + componentDidMount () { + MKEmitter.addListener('submitStyle', this.getStyle) + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + /** + * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆 + */ + componentWillUnmount () { + this.setState = () => { + return + } + MKEmitter.removeListener('submitStyle', this.getStyle) + } + + /** + * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級 + */ + updateComponent = (component) => { + this.setState({ + card: component + }) + + component.width = component.wrap.width + component.name = component.wrap.name + + this.props.updateConfig(component) + } + + getStyle = (comIds, style) => { + const { card } = this.state + + if (comIds[0] !== card.uuid) return + + let _card = {...card} + if (comIds.length === 1) { + _card = {...card, style} + } + + this.setState({ + card: _card + }) + + this.props.updateConfig(_card) + } + + changeStyle = () => { + const { card } = this.state + + MKEmitter.emit('changeStyle', [card.uuid], ['font', 'background', 'shadow'], card.style) + } + + clickComponent = (e) => { + if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') { + e.stopPropagation() + MKEmitter.emit('clickComponent', this.state.card) + } + } + + changeMenu = (menu) => { + if (menu.property === 'link') { + window.open(menu.link) + return + } + MKEmitter.emit('changeEditMenu', { + fixed: menu.property === 'menu', + MenuID: menu.property === 'linkmenu' ? menu.linkMenuId : menu.MenuID, + copyMenuId: menu.property === 'menu' ? menu.copyMenuId : '', + MenuNo: menu.MenuNo, + MenuName: menu.name, + }) + } + + render() { + const { card } = this.state + + let _style = {...card.style} + if (_style.shadow) { + _style.boxShadow = '0 0 4px ' + _style.shadow + } + + return ( + <div className="normal-navbar-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}> + <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ + <div className="mk-popover-control"> + <MenuComponent config={card} updateConfig={this.updateComponent} /> + <WrapComponent config={card} updateConfig={this.updateComponent} /> + <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" /> + <Icon className="close" title="鍒犻櫎缁勪欢" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} /> + </div> + } trigger="hover"> + <Icon type="tool" /> + </Popover> + <div className="menu"> + {card.menus.map(menu => { + return ( + <div class="am-tab-bar-tab"> + <div class="am-tab-bar-tab-icon"> + <span class="am-badge am-tab-bar-tab-badge tab-badge"> + <Icon type="font-colors" /> + <sup class="am-badge-text">1</sup> + </span> + </div> + <p class="am-tab-bar-tab-title">{menu.name}</p> + </div> + ) + })} + </div> + </div> + ) + } +} + +export default NormalNavbar \ No newline at end of file diff --git a/src/mob/components/navbar/normal-navbar/index.scss b/src/mob/components/navbar/normal-navbar/index.scss new file mode 100644 index 0000000..67d1e9f --- /dev/null +++ b/src/mob/components/navbar/normal-navbar/index.scss @@ -0,0 +1,133 @@ +.normal-navbar-edit-box { + position: fixed; + bottom: 0px; + left: 0px; + width: 100%; + box-sizing: border-box; + background: #ffffff; + background-position: center center; + background-repeat: no-repeat; + background-size: cover; + min-height: 50px; + z-index: 3; + + .menu { + display: block; + font-size: inherit; + color: inherit; + .ant-menu { + background: transparent; + line-height: inherit; + font-size: inherit; + color: inherit; + border: 0; + .ant-menu-item:hover, .ant-menu-item-active { + color: unset; + } + .ant-menu-item span { + display: inline-block; + } + } + .ant-menu-horizontal > .ant-menu-item:hover, .ant-menu-horizontal > .ant-menu-item-active, .ant-menu-horizontal > .ant-menu-item-open, .ant-menu-horizontal > .ant-menu-item-selected { + color: unset; + } + } + .card-control { + position: absolute; + top: 0px; + left: 0px; + .anticon-tool { + right: auto; + left: 1px; + padding: 1px; + } + } + .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); + } + + .card-item { + overflow: hidden; + position: relative; + background-color: #ffffff; + background-position: center center; + background-repeat: no-repeat; + background-size: cover; + min-height: 20px; + } + + .card-item:hover { + box-shadow: 0px 0px 2px #1890ff; + } + + .model-menu-card-cell-list .card-detail-row > .anticon-plus { + position: absolute; + right: -30px; + font-size: 16px; + } + .model-menu-action-list { + line-height: 40px; + .ant-row > .anticon-plus { + position: absolute; + right: -30px; + font-size: 16px; + } + } + .card-add-button { + text-align: right; + clear: left; + .anticon-plus { + font-size: 20px; + color: #26C281; + padding: 5px; + margin-right: 10px; + } + } + .ant-pagination { + float: right; + margin: 10px; + } + + .model-menu-action-list { + .page-card { + line-height: 55px; + } + } +} +.normal-navbar-edit-box::after { + display: block; + content: ' '; + clear: both; +} +.normal-navbar-edit-box:hover { + box-shadow: 0px 0px 4px #1890ff; +} +.top-menu-popover { + padding-top: 0!important; +} +.normal-navbar-submenu { + .ant-menu-item-group { + float: left; + } + .ant-menu-item { + height: 32px; + line-height: 32px; + span { + display: inline-block; + width: 100%; + height: 100%; + padding: 0 16px 0 28px; + } + padding: 0; + } + .ant-menu .ant-menu-item-selected { + background-color: #ffffff; + } +} \ No newline at end of file diff --git a/src/mob/components/navbar/normal-navbar/menusetting/index.jsx b/src/mob/components/navbar/normal-navbar/menusetting/index.jsx new file mode 100644 index 0000000..18f00b1 --- /dev/null +++ b/src/mob/components/navbar/normal-navbar/menusetting/index.jsx @@ -0,0 +1,62 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Icon, Modal } from 'antd' + +import zhCN from '@/locales/zh-CN/model.js' +import enUS from '@/locales/en-US/model.js' +import MenuTable from './menutable' +import './index.scss' + +class DataSource extends Component { + static propTpyes = { + config: PropTypes.any, + updateConfig: PropTypes.func + } + + state = { + dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, + visible: false + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) + } + + verifySubmit = () => { + const { config } = this.props + let menus = this.mTable.state.data || [] + + this.props.updateConfig({...config, menus}) + this.setState({visible: false}) + } + + render () { + const { config } = this.props + const { visible, dict } = this.state + + return ( + <div className="model-menu-setting-wrap"> + <Icon type="menu" title="鑿滃崟" onClick={() => this.setState({ visible: true })}/> + <Modal + wrapClassName="popview-modal" + title="鑿滃崟缂栬緫" + visible={visible} + width={950} + maskClosable={false} + okText={dict['model.submit']} + onOk={this.verifySubmit} + onCancel={() => { this.setState({ visible: false }) }} + destroyOnClose + > + <MenuTable + menus={config.menus} + ref={(ref) => { this.mTable = ref }} + /> + </Modal> + </div> + ) + } +} + +export default DataSource \ No newline at end of file diff --git a/src/mob/components/navbar/normal-navbar/menusetting/index.scss b/src/mob/components/navbar/normal-navbar/menusetting/index.scss new file mode 100644 index 0000000..3a906d8 --- /dev/null +++ b/src/mob/components/navbar/normal-navbar/menusetting/index.scss @@ -0,0 +1,11 @@ +.model-menu-setting-wrap { + display: inline-block; + + >.anticon-menu { + color: purple; + } + + >.anticon-edit { + color: #1890ff; + } +} \ No newline at end of file diff --git a/src/mob/components/navbar/normal-navbar/menusetting/menuform/index.jsx b/src/mob/components/navbar/normal-navbar/menusetting/menuform/index.jsx new file mode 100644 index 0000000..8bf7a82 --- /dev/null +++ b/src/mob/components/navbar/normal-navbar/menusetting/menuform/index.jsx @@ -0,0 +1,205 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { Form, Row, Col, Input, Radio, Tooltip, Icon, Select } from 'antd' + +import './index.scss' + +const { TextArea } = Input + +class SettingForm extends Component { + static propTpyes = { + menu: PropTypes.object, // 鍗$墖琛屼俊鎭� + inputSubmit: PropTypes.func // 鍥炶溅浜嬩欢 + } + + state = { + property: this.props.menu.property || 'menu', + appMenus: [], + } + + UNSAFE_componentWillMount () { + let appMenus = sessionStorage.getItem('appMenus') + if (appMenus) { + try { + appMenus = JSON.parse(appMenus) + } catch { + appMenus = [] + } + } else { + appMenus = [] + } + + this.setState({appMenus}) + } + + componentDidMount() { + const { menu } = this.props + + if (!menu.MenuID) { + let _form = document.getElementById('name') + _form && _form.select() + } + } + + handleConfirm = () => { + // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭� + return new Promise((resolve, reject) => { + this.props.form.validateFieldsAndScroll((err, values) => { + if (!err) { + resolve(values) + } else { + reject(err) + } + }) + }) + } + + handleSubmit = (e) => { + e.preventDefault() + + if (this.props.inputSubmit) { + this.props.inputSubmit() + } + } + + changeProperty = (e) => { + let val = e.target.value + + this.setState({property: val}) + } + + render() { + const { menu } = this.props + const { getFieldDecorator } = this.props.form + const { property, appMenus } = this.state + + const formItemLayout = { + labelCol: { + xs: { span: 24 }, + sm: { span: 8 } + }, + wrapperCol: { + xs: { span: 24 }, + sm: { span: 16 } + } + } + + return ( + <Form {...formItemLayout}> + <Row gutter={24}> + <Col span={22}> + <Form.Item label="鑿滃崟鍚嶇О"> + {getFieldDecorator('name', { + initialValue: menu.name, + rules: [ + { + required: true, + message: '璇疯緭鍏ヨ彍鍗曞悕绉�!' + } + ] + })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} + </Form.Item> + </Col> + <Col span={22}> + <Form.Item label="鑿滃崟鍙傛暟"> + {getFieldDecorator('MenuNo', { + initialValue: menu.MenuNo || '', + rules: [ + { + required: true, + message: '璇疯緭鍏ヨ彍鍗曞弬鏁�!' + } + ] + })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} + </Form.Item> + </Col> + <Col span={22}> + <Form.Item label="鍥炬爣"> + {getFieldDecorator('icon', { + initialValue: menu.icon || '' + })( + <Select> + {appMenus.map(item => (<Select.Option key={item.MenuID} value={item.MenuID}>{item.MenuName}</Select.Option>))} + </Select> + )} + </Form.Item> + </Col> + <Col span={22}> + <Form.Item label="鑿滃崟灞炴��"> + {getFieldDecorator('property', { + initialValue: menu.property || 'menu' + })( + <Radio.Group onChange={this.changeProperty}> + <Radio value="menu">鑿滃崟</Radio> + <Radio value="link">閾炬帴</Radio> + <Radio value="linkmenu">鍏宠仈鑿滃崟</Radio> + </Radio.Group> + )} + </Form.Item> + </Col> + <Col span={22}> + <Form.Item label="闅愯棌"> + {getFieldDecorator('hidden', { + initialValue: menu.hidden || 'false' + })( + <Radio.Group> + <Radio value="false">鍚�</Radio> + <Radio value="true">鏄�</Radio> + </Radio.Group> + )} + </Form.Item> + </Col> + {property === 'link' ? <Col span={22}> + <Form.Item label="閾炬帴鍦板潃"> + {getFieldDecorator('link', { + initialValue: menu.link || '', + rules: [{ + required: true, + message: '璇疯緭鍏ラ摼鎺ュ湴鍧�!' + }] + })(<TextArea rows={2} />)} + </Form.Item> + </Col> : null} + {property === 'linkmenu' ? <Col span={22}> + <Form.Item label={ + <Tooltip placement="topLeft" title="鍏宠仈褰撳墠app涓凡鏈夌殑鑿滃崟銆�"> + <Icon type="question-circle" style={{color: '#c49f47', marginRight: '3px'}}/> + 鍏宠仈鑿滃崟 + </Tooltip> + }> + {getFieldDecorator('linkMenuId', { + initialValue: menu.linkMenuId || '', + rules: [{ + required: true, + message: '璇烽�夋嫨鍏宠仈鑿滃崟!' + }] + })( + <Select> + {appMenus.map(item => (<Select.Option key={item.MenuID} value={item.MenuID}>{item.MenuName}</Select.Option>))} + </Select> + )} + </Form.Item> + </Col> : null} + {property === 'menu' ? <Col span={22}> + <Form.Item label={ + <Tooltip placement="topLeft" title="澶嶅埗鑿滃崟浠呭湪褰撳墠鑿滃崟涓嶅瓨鍦ㄦ椂鏈夋晥銆�"> + <Icon type="question-circle" style={{color: '#c49f47', marginRight: '3px'}}/> + 澶嶅埗鑿滃崟 + </Tooltip> + }> + {getFieldDecorator('copyMenuId', { + initialValue: menu.copyMenuId || '' + })( + <Select> + {appMenus.map(item => (<Select.Option key={item.MenuID} value={item.MenuID}>{item.MenuName}</Select.Option>))} + </Select> + )} + </Form.Item> + </Col> : null} + </Row> + </Form> + ) + } +} + +export default Form.create()(SettingForm) \ No newline at end of file diff --git a/src/mob/components/navbar/normal-navbar/menusetting/menuform/index.scss b/src/mob/components/navbar/normal-navbar/menusetting/menuform/index.scss new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/mob/components/navbar/normal-navbar/menusetting/menuform/index.scss diff --git a/src/mob/components/navbar/normal-navbar/menusetting/menutable/index.jsx b/src/mob/components/navbar/normal-navbar/menusetting/menutable/index.jsx new file mode 100644 index 0000000..8fc36cf --- /dev/null +++ b/src/mob/components/navbar/normal-navbar/menusetting/menutable/index.jsx @@ -0,0 +1,185 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Table, Button, Modal, Icon } from 'antd' + +import MenuForm from '../menuform' +import Utils from '@/utils/utils.js' +import MKEmitter from '@/utils/events.js' +import './index.scss' + +const { confirm } = Modal + +class MenuTable extends Component { + static propTpyes = { + menus: PropTypes.object, // 鍗$墖琛屼俊鎭� + } + + state = { + data: [], + editMenu: null, + columns: [ + { title: '鑿滃崟鍚嶇О', dataIndex: 'name', key: 'name' }, + { title: '鑿滃崟鍙傛暟', dataIndex: 'MenuNo', key: 'MenuNo' }, + { title: '鑿滃崟灞炴��', dataIndex: 'property', key: 'property', render: text => { + const trans = {menu: '鑿滃崟', link: '閾炬帴', linkmenu: '鍏宠仈鑿滃崟'} + + return trans[text] + }}, + { title: '鏄惁闅愯棌', dataIndex: 'hidden', key: 'hidden', render: (text, record) => { + const trans = {'true': '鏄�', 'false': '鍚�'} + return trans[text] || '鍚�' + }}, + { title: '鎿嶄綔', key: 'operation', align: 'center', width: '190px', render: (text, record) => + (<div> + <Button type="link" style={{padding: '0 5px', marginRight: '5px'}} onClick={() => this.editMenu(record)}>缂栬緫</Button> + <Button type="link" style={{color: '#ff4d4f', padding: '0 5px', marginRight: '5px'}} onClick={() => this.delMenu(record)}>鍒犻櫎</Button> + <Icon type="arrow-up" style={{color: '#26C281', cursor: 'pointer', padding: '0 5px', marginRight: '5px'}} onClick={() => this.moveUp(record)}/> + <Icon type="arrow-down" style={{color: '#ff4d4f', cursor: 'pointer', padding: '0 5px'}} onClick={() => this.moveDown(record)}/> + </div>) + } + ] + } + + UNSAFE_componentWillMount () { + const { menus } = this.props + + this.setState({data: fromJS(menus).toJS()}) + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + moveUp = (record) => { + let data = fromJS(this.state.data).toJS() + + let dragIndex = data.findIndex(c => c.MenuID === record.MenuID) + let hoverIndex = dragIndex - 1 + + if (hoverIndex === -1) return + + data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1)) + this.setState({data}) + } + + moveDown = (record) => { + let data = fromJS(this.state.data).toJS() + + let dragIndex = data.findIndex(c => c.MenuID === record.MenuID) + let hoverIndex = dragIndex + 1 + + if (hoverIndex === data.length) return + + data.splice(hoverIndex, 0, ...data.splice(dragIndex, 1)) + this.setState({data}) + } + + delMenu = (record) => { + const { data } = this.state + const _this = this + + confirm({ + title: (record.property === 'classify' && record.sublist.length > 0 ? '鑿滃崟涓嬪惈鏈夊瓙鑿滃崟锛�' : '') + '纭畾鍒犻櫎鍚楋紵', + content: '', + onOk() { + _this.setState({data: data.filter(item => item.MenuID !== record.MenuID)}) + + let uuids = [record.MenuID] + record.sublist && record.sublist.forEach(item => { + uuids.push(item.MenuID) + + item.sublist && item.sublist.forEach(cell => { + uuids.push(cell.MenuID) + }) + }) + MKEmitter.emit('delButtons', uuids) + }, + onCancel() {} + }) + } + + editMenu = (record) => { + this.setState({editMenu: record, visible: true}) + } + + plusMenu = () => { + let _menu = { + name: '鑿滃崟', + property: 'menu' + } + + this.setState({editMenu: _menu, visible: true}) + } + + menuSubmit = () => { + const { editMenu, data } = this.state + + this.menuRef.handleConfirm().then(res => { + let _menu = {...editMenu, ...res} + if (!_menu.MenuID) { + _menu.MenuID = Utils.getuuid() + this.setState({data: [...data, _menu], editMenu: null, visible: false}) + } else { + this.setState({ + editMenu: null, + visible: false, + data: data.map(item => { + if (item.MenuID === _menu.MenuID) { + return _menu + } else { + return item + } + }) + }) + } + }) + } + + menuUpdate = (res) => { + const { data } = this.state + + this.setState({ + data: data.map(item => { + if (item.MenuID === res.MenuID) { + return res + } else { + return item + } + }) + }) + } + + render() { + const { columns, data, visible, editMenu } = this.state + + return ( + <div className="menu-control-wrap"> + <Button className="menu-plus mk-green" onClick={this.plusMenu}>娣诲姞</Button> + <Table + rowKey="MenuID" + columns={columns} + dataSource={data} + pagination={false} + /> + <Modal + title="缂栬緫" + visible={visible} + width={600} + maskClosable={false} + onOk={this.menuSubmit} + onCancel={() => { this.setState({ visible: false }) }} + destroyOnClose + > + <MenuForm + menu={editMenu} + inputSubmit={this.menuSubmit} + wrappedComponentRef={(inst) => this.menuRef = inst} + /> + </Modal> + </div> + ) + } +} + +export default MenuTable \ No newline at end of file diff --git a/src/mob/components/navbar/normal-navbar/menusetting/menutable/index.scss b/src/mob/components/navbar/normal-navbar/menusetting/menutable/index.scss new file mode 100644 index 0000000..725a1d5 --- /dev/null +++ b/src/mob/components/navbar/normal-navbar/menusetting/menutable/index.scss @@ -0,0 +1,23 @@ +.menu-control-wrap { + position: relative; + + .menu-plus { + float: right; + position: relative; + z-index: 1; + margin-bottom: 5px; + } + .ant-empty { + margin: 5px 0; + } + thead tr { + background: #fbfbfb; + } + tbody > tr { + background: #ffffff; + } + + .ant-table-body { + margin: 0!important; + } +} \ No newline at end of file diff --git a/src/mob/components/navbar/normal-navbar/wrapsetting/index.jsx b/src/mob/components/navbar/normal-navbar/wrapsetting/index.jsx new file mode 100644 index 0000000..81346a6 --- /dev/null +++ b/src/mob/components/navbar/normal-navbar/wrapsetting/index.jsx @@ -0,0 +1,83 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Icon, Modal } from 'antd' + +import zhCN from '@/locales/zh-CN/model.js' +import enUS from '@/locales/en-US/model.js' +import SettingForm from './settingform' +import './index.scss' + +class DataSource extends Component { + static propTpyes = { + config: PropTypes.any, + updateConfig: PropTypes.func + } + + state = { + dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, + visible: false, + wrap: null + } + + UNSAFE_componentWillMount () { + const { config } = this.props + + this.setState({wrap: fromJS(config.wrap).toJS()}) + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) + } + + editDataSource = () => { + this.setState({ + visible: true + }) + } + + verifySubmit = () => { + const { config } = this.props + + this.verifyRef.handleConfirm().then(res => { + + this.setState({ + wrap: res, + visible: false + }) + this.props.updateConfig({...config, wrap: res}) + }) + } + + render () { + const { config } = this.props + const { visible, dict, wrap } = this.state + + return ( + <div className="model-menu-setting-wrap"> + <Icon type="edit" title="缂栬緫" onClick={() => this.editDataSource()} /> + <Modal + wrapClassName="popview-modal" + title={config.type === 'table' ? '琛ㄦ牸璁剧疆' : '鍗$墖璁剧疆'} + visible={visible} + width={800} + maskClosable={false} + okText={dict['model.submit']} + onOk={this.verifySubmit} + onCancel={() => { this.setState({ visible: false }) }} + destroyOnClose + > + <SettingForm + dict={dict} + wrap={wrap} + config={config} + inputSubmit={this.verifySubmit} + wrappedComponentRef={(inst) => this.verifyRef = inst} + /> + </Modal> + </div> + ) + } +} + +export default DataSource \ No newline at end of file diff --git a/src/mob/components/navbar/normal-navbar/wrapsetting/index.scss b/src/mob/components/navbar/normal-navbar/wrapsetting/index.scss new file mode 100644 index 0000000..04372e6 --- /dev/null +++ b/src/mob/components/navbar/normal-navbar/wrapsetting/index.scss @@ -0,0 +1,7 @@ +.model-menu-setting-wrap { + display: inline-block; + + >.anticon-edit { + color: #1890ff; + } +} \ No newline at end of file diff --git a/src/mob/components/navbar/normal-navbar/wrapsetting/settingform/index.jsx b/src/mob/components/navbar/normal-navbar/wrapsetting/settingform/index.jsx new file mode 100644 index 0000000..25d3f54 --- /dev/null +++ b/src/mob/components/navbar/normal-navbar/wrapsetting/settingform/index.jsx @@ -0,0 +1,102 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { Form, Row, Col, Input, InputNumber } from 'antd' + +import './index.scss' + +class SettingForm extends Component { + static propTpyes = { + dict: PropTypes.object, // 瀛楀吀椤� + config: PropTypes.object, // 鍗$墖琛屼俊鎭� + wrap: PropTypes.object, // 鏁版嵁婧愰厤缃� + inputSubmit: PropTypes.func // 鍥炶溅浜嬩欢 + } + + state = {} + + handleConfirm = () => { + // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭� + return new Promise((resolve, reject) => { + this.props.form.validateFieldsAndScroll((err, values) => { + if (!err) { + resolve(values) + } else { + reject(err) + } + }) + }) + } + + handleSubmit = (e) => { + e.preventDefault() + + if (this.props.inputSubmit) { + this.props.inputSubmit() + } + } + + render() { + const { wrap } = this.props + const { getFieldDecorator } = this.props.form + const formItemLayout = { + labelCol: { + xs: { span: 24 }, + sm: { span: 8 } + }, + wrapperCol: { + xs: { span: 24 }, + sm: { span: 16 } + } + } + + return ( + <div className="model-menu-setting-form"> + <Form {...formItemLayout}> + <Row gutter={24}> + <Col span={12}> + <Form.Item label="瀵艰埅鏍忓悕绉�"> + {getFieldDecorator('name', { + initialValue: wrap.name, + rules: [ + { + required: true, + message: this.props.dict['form.required.input'] + '瀵艰埅鏍忓悕绉�!' + } + ] + })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} + </Form.Item> + </Col> + <Col span={12}> + <Form.Item label="鑿滃崟鍙傛暟"> + {getFieldDecorator('MenuNo', { + initialValue: wrap.MenuNo, + rules: [ + { + required: true, + message: this.props.dict['form.required.input'] + '鑿滃崟鍙傛暟!' + } + ] + })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} + </Form.Item> + </Col> + <Col span={12}> + <Form.Item label="楂樺害"> + {getFieldDecorator('height', { + initialValue: wrap.height || 50, + rules: [ + { + required: true, + message: this.props.dict['form.required.input'] + '楂樺害!' + } + ] + })(<InputNumber min={50} max={200} precision={0} onPressEnter={this.handleSubmit} />)} + </Form.Item> + </Col> + </Row> + </Form> + </div> + ) + } +} + +export default Form.create()(SettingForm) \ No newline at end of file diff --git a/src/mob/components/navbar/normal-navbar/wrapsetting/settingform/index.scss b/src/mob/components/navbar/normal-navbar/wrapsetting/settingform/index.scss new file mode 100644 index 0000000..159130b --- /dev/null +++ b/src/mob/components/navbar/normal-navbar/wrapsetting/settingform/index.scss @@ -0,0 +1,11 @@ +.model-menu-setting-form { + position: relative; + + .anticon-question-circle { + color: #c49f47; + margin-right: 3px; + } + .ant-input-number { + width: 100%; + } +} \ No newline at end of file diff --git a/src/mob/home/index.jsx b/src/mob/home/index.jsx deleted file mode 100644 index dde5d1f..0000000 --- a/src/mob/home/index.jsx +++ /dev/null @@ -1,126 +0,0 @@ -import React, {Component} from 'react' -// import PropTypes from 'prop-types' -import { is, fromJS } from 'immutable' -import { Flex, WhiteSpace, Tabs } from 'antd-mobile' - -import zhCN from '@/locales/zh-CN/mob.js' -import enUS from '@/locales/en-US/mob.js' -import './index.scss' - -const PlaceHolder = ({ className = '', children = ''}) => ( - <div className={`${className} placeholder`}>{children ? children : 'Block'}</div> -) - -const tabs2 = [ - { title: '绠�浠�', sub: '1' }, - { title: '宸ヤ綔鍙�', sub: '2' }, - { title: '涓汉涓績', sub: '3' }, -] - -class MobHome extends Component { - // static propTpyes = { - // collapse: PropTypes.bool, - // } - state = { - dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, - } - - shouldComponentUpdate (nextProps, nextState) { - return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) - } - - render () { - - return ( - <div className="mob-home"> - <Tabs tabs={tabs2} - initialPage={1} - tabBarPosition="bottom" - renderTab={tab => <span>{tab.title}</span>} - > - <div className="home-tab"> - <div className="flex-container"> - <div className="sub-title">Basic</div> - <Flex> - <Flex.Item><PlaceHolder ><span> test</span></PlaceHolder></Flex.Item> - <Flex.Item><PlaceHolder /></Flex.Item> - </Flex> - <WhiteSpace size="lg" /> - <Flex> - <Flex.Item><PlaceHolder /></Flex.Item> - <Flex.Item><PlaceHolder /></Flex.Item> - <Flex.Item><PlaceHolder /></Flex.Item> - </Flex> - <WhiteSpace size="lg" /> - <Flex> - <Flex.Item><PlaceHolder /></Flex.Item> - <Flex.Item><PlaceHolder /></Flex.Item> - <Flex.Item><PlaceHolder /></Flex.Item> - <Flex.Item><PlaceHolder /></Flex.Item> - </Flex> - <WhiteSpace size="lg" /> - - <div className="sub-title">Wrap</div> - <Flex wrap="wrap"> - <PlaceHolder className="inline" /> - <PlaceHolder className="inline" /> - <PlaceHolder className="inline" /> - <PlaceHolder className="inline" /> - <PlaceHolder className="inline" /> - <PlaceHolder className="inline" /> - <PlaceHolder className="inline" /> - </Flex> - <WhiteSpace size="lg" /> - - <div className="sub-title">Align</div> - <Flex justify="center"> - <PlaceHolder className="inline" /> - <PlaceHolder className="inline" /> - <PlaceHolder className="inline" /> - </Flex> - <WhiteSpace /> - <Flex justify="end"> - <PlaceHolder className="inline" /> - <PlaceHolder className="inline" /> - <PlaceHolder className="inline" /> - </Flex> - <WhiteSpace /> - <Flex justify="between"> - <PlaceHolder className="inline" /> - <PlaceHolder className="inline" /> - <PlaceHolder className="inline" /> - </Flex> - - <WhiteSpace /> - <Flex align="start"> - <PlaceHolder className="inline" /> - <PlaceHolder className="inline small" /> - <PlaceHolder className="inline" /> - </Flex> - <WhiteSpace /> - <Flex align="end"> - <PlaceHolder className="inline" /> - <PlaceHolder className="inline small" /> - <PlaceHolder className="inline" /> - </Flex> - <WhiteSpace /> - <Flex align="baseline"> - <PlaceHolder className="inline" /> - <PlaceHolder className="inline small" /> - <PlaceHolder className="inline" /> - </Flex> - </div> - </div> - <div className="home-tab"> - Content of second tab - </div> - <div className="home-tab"> - Content of third tab - </div> - </Tabs> - </div> - ) - } -} - -export default MobHome \ No newline at end of file diff --git a/src/mob/home/index.scss b/src/mob/home/index.scss deleted file mode 100644 index 9b2141a..0000000 --- a/src/mob/home/index.scss +++ /dev/null @@ -1,38 +0,0 @@ -.mob-home { - width: 100%; - height: 100%; - overflow: hidden; - > .am-tabs { - > .am-tabs-tab-bar-wrap { - .am-tabs-default-bar-underline { - display: none; - } - .am-tabs-default-bar-tab { - cursor: pointer; - } - } - > .am-tabs-content-wrap { - > .am-tabs-pane-wrap { - .home-tab { - display: flex; - align-items: center; - justify-content: center; - } - } - > .am-tabs-pane-wrap::-webkit-scrollbar { - width: 4px; - } - > .am-tabs-pane-wrap::-webkit-scrollbar-thumb { - box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13); - background: rgba(0, 0, 0, 0.13); - border-radius: 5px; - } - > .am-tabs-pane-wrap::-webkit-scrollbar-track { - box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05); - border: 1px solid rgba(0, 0, 0, 0.07); - background: rgba(0, 0, 0, 0); - border-radius: 3px; - } - } - } -} \ No newline at end of file diff --git a/src/mob/mobshell/card.jsx b/src/mob/mobshell/card.jsx index 3a2a1fa..47eb3c6 100644 --- a/src/mob/mobshell/card.jsx +++ b/src/mob/mobshell/card.jsx @@ -18,6 +18,7 @@ const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group')) const CodeSandbox = asyncComponent(() => import('@/menu/components/code/sandbox')) const NormalLogin = asyncComponent(() => import('@/pc/components/login/normal-login')) +const NormalNavbar = asyncComponent(() => import('@/mob/components/navbar/normal-navbar')) const Card = ({ id, card, moveCard, findCard, delCard, updateConfig }) => { const originalIndex = findCard(id).index @@ -52,6 +53,25 @@ style = { opacity: 0.3} } + let col = 'ant-col-' + (card.width || 24) + if (card.type === 'navbar') { + col = '' + } else if (card.type === 'login') { + let height = '' + if (card.wrap && card.wrap.height) { + // scaleview + height = card.wrap.height.replace(/\d+vw/ig, (word) => { + return parseFloat(word) * 420 / 100 + 'px' + // return parseFloat(word) * 350 / 100 + 'px' + }).replace(/\d+vh/ig, (word) => { + return parseFloat(word) * 738 / 100 + 'px' + // return parseFloat(word) * 615 / 100 + 'px' + }) + } + + style.minHeight = height + } + const getCardComponent = () => { if (card.type === 'bar' || card.type === 'line') { return (<AntvBar card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) @@ -81,27 +101,13 @@ return (<CodeSandbox card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'login') { return (<NormalLogin card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'navbar') { + return (<NormalNavbar card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } - } - - if (card.type === 'login') { - let height = '' - if (card.wrap && card.wrap.height) { - // scaleview - height = card.wrap.height.replace(/\d+vw/ig, (word) => { - return parseFloat(word) * 420 / 100 + 'px' - // return parseFloat(word) * 350 / 100 + 'px' - }).replace(/\d+vh/ig, (word) => { - return parseFloat(word) * 738 / 100 + 'px' - // return parseFloat(word) * 615 / 100 + 'px' - }) - } - - style.minHeight = height } 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 ' + col} ref={node => drag(drop(node))} style={style}> {getCardComponent()} </div> ) diff --git a/src/pc/menushell/card.jsx b/src/pc/menushell/card.jsx index 2074191..fc878d3 100644 --- a/src/pc/menushell/card.jsx +++ b/src/pc/menushell/card.jsx @@ -58,6 +58,20 @@ let col = ' ant-col ant-col-' + (card.width || 24) if (card.type === 'navbar') { col = '' + } else if (card.type === 'login') { + let height = '' + if (card.wrap && card.wrap.height) { + // scaleview + height = card.wrap.height.replace(/\d+vw/ig, (word) => { + return parseFloat(word) * 420 / 100 + 'px' + // return parseFloat(word) * 350 / 100 + 'px' + }).replace(/\d+vh/ig, (word) => { + return parseFloat(word) * 738 / 100 + 'px' + // return parseFloat(word) * 615 / 100 + 'px' + }) + } + + style.minHeight = height } const getCardComponent = () => { @@ -96,10 +110,7 @@ } else if (card.type === 'code') { return (<CodeSandbox card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'login') { - return (<> - <NormalLogin card={card} updateConfig={updateConfig} deletecomponent={delCard}/> - <div style={{float: 'right', height: card.wrap ? card.wrap.height : ''}}></div> - </>) + return (<NormalLogin card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } } return ( diff --git a/src/templates/modalconfig/dragelement/index.jsx b/src/templates/modalconfig/dragelement/index.jsx index 42ded36..478da3c 100644 --- a/src/templates/modalconfig/dragelement/index.jsx +++ b/src/templates/modalconfig/dragelement/index.jsx @@ -33,6 +33,7 @@ const editCard = id => { const { card } = findCard(id) + delete card.focus handleForm(card) } diff --git a/src/utils/option.js b/src/utils/option.js index 62da633..d6c490b 100644 --- a/src/utils/option.js +++ b/src/utils/option.js @@ -681,19 +681,8 @@ 'step-forward', 'fast-backward', 'fast-forward', - 'shrink', - 'arrows-alt', - 'up-circle', - 'down-circle', - 'left-circle', - 'right-circle', 'double-right', 'double-left', - 'vertical-left', - 'vertical-right', - 'vertical-align-top', - 'vertical-align-middle', - 'vertical-align-bottom', 'forward', 'backward', 'rollback', @@ -703,29 +692,8 @@ 'swap-left', 'swap-right', 'play-circle', - 'up-square', - 'down-square', - 'left-square', - 'right-square', 'login', 'logout', - 'menu-fold', - 'menu-unfold', - 'border-bottom', - 'border-horizontal', - 'border-inner', - 'border-outer', - 'border-left', - 'border-right', - 'border-top', - 'border-verticle', - 'pic-center', - 'pic-left', - 'pic-right', - 'radius-bottomleft', - 'radius-bottomright', - 'radius-upleft', - 'radius-upright', 'fullscreen', 'fullscreen-exit' ], @@ -734,25 +702,18 @@ 'question-circle', 'plus', 'plus-circle', - 'pause', 'pause-circle', 'minus', 'minus-circle', - 'plus-square', - 'minus-square', - 'info', 'info-circle', - 'exclamation', 'exclamation-circle', 'close', 'close-circle', - 'close-square', 'check', 'check-circle', 'check-square', 'clock-circle', 'warning', - 'issues-close', 'stop' ], edit: [ @@ -762,33 +723,14 @@ 'scissor', 'delete', 'snippets', - 'diff', 'highlight', - 'align-center', - 'align-left', - 'align-right', - 'bg-colors', - 'bold', - 'italic', - 'underline', - 'strikethrough', 'redo', 'undo', 'zoom-in', 'zoom-out', - 'font-colors', - 'font-size', - 'line-height', 'dash', - 'small-dash', 'sort-ascending', - 'sort-descending', - 'drag', - 'ordered-list', - 'unordered-list', - 'radius-setting', - 'column-width', - 'column-height' + 'sort-descending' ], data: [ 'area-chart', @@ -797,64 +739,23 @@ 'dot-chart', 'line-chart', 'radar-chart', - 'heat-map', 'fall', 'rise', 'stock', - 'box-plot', - 'fund', - 'sliders' ], trademark: [ 'android', 'apple', - 'windows', - 'ie', 'chrome', - 'github', 'aliwangwang', 'dingding', - 'weibo-square', - 'weibo-circle', - 'taobao-circle', - 'html5', 'weibo', 'twitter', 'wechat', - 'youtube', 'alipay-circle', 'taobao', - 'skype', 'qq', - 'medium-workmark', - 'gitlab', - 'medium', - 'linkedin', - 'google-plus', - 'dropbox', - 'facebook', - 'codepen', - 'code-sandbox', - 'amazon', - 'google', - 'codepen-circle', 'alipay', - 'ant-design', - 'ant-cloud', - 'aliyun', - 'zhihu', - 'slack', - 'slack-square', - 'behance', - 'behance-square', - 'dribbble', - 'dribbble-square', - 'instagram', - 'yuque', - 'alibaba', - 'yahoo', - 'reddit', - 'sketch' ], normal: [ 'account-book', @@ -864,42 +765,19 @@ 'audio', 'bank', 'bell', - 'book', 'bug', - 'bulb', - 'calculator', - 'build', 'calendar', 'camera', - 'car', - 'carry-out', 'cloud', - 'code', 'compass', - 'contacts', - 'container', - 'control', 'credit-card', - 'crown', 'customer-service', 'dashboard', 'database', 'dislike', 'environment', - 'experiment', 'eye-invisible', 'eye', - 'file-add', - 'file-excel', - 'file-exclamation', - 'file-image', - 'file-markdown', - 'file-pdf', - 'file-ppt', - 'file-text', - 'file-unknown', - 'file-word', - 'file-zip', 'file', 'filter', 'fire', @@ -907,22 +785,13 @@ 'folder-add', 'folder', 'folder-open', - 'frown', - 'funnel-plot', - 'gift', - 'hdd', 'heart', 'home', 'hourglass', 'idcard', - 'insurance', - 'interaction', - 'layout', 'like', 'lock', 'mail', - 'medicine-box', - 'meh', 'message', 'mobile', 'phone', @@ -931,7 +800,6 @@ 'smile', 'star', 'thunderbolt', - 'trophy', 'unlock', 'barcode', 'key', -- Gitblit v1.8.0