From 6c56a138c17dc9aff9d175d20645eb176d2e024b Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期三, 03 三月 2021 19:03:18 +0800 Subject: [PATCH] 2021-03-03 --- src/pc/components/navbar/normal-navbar/index.jsx | 322 +------------ src/pc/components/navbar/normal-navbar/wrapsetting/index.jsx | 83 +++ src/pc/modulesource/option.jsx | 2 src/templates/sharecomponent/settingcomponent/settingform/simplescript/index.jsx | 10 src/pc/components/navbar/normal-navbar/menusetting/menutable/index.scss | 10 src/pc/components/navbar/normal-navbar/wrapsetting/settingform/index.scss | 11 src/pc/menushell/index.jsx | 165 +++++++ src/pc/components/navbar/normal-navbar/menusetting/index.jsx | 73 +++ src/pc/components/navbar/normal-navbar/menusetting/menutable/index.jsx | 168 +++++++ src/pc/menushell/index.scss | 23 + src/pc/components/navbar/normal-navbar/menusetting/menuform/index.scss | 0 src/pc/components/navbar/normal-navbar/wrapsetting/index.scss | 7 src/index.js | 2 src/assets/mobimg/navbar.png | 0 src/menu/stylecontroller/index.jsx | 20 src/views/pcdesign/index.jsx | 5 src/pc/menushell/card.jsx | 90 +++ src/menu/components/tabs/tablabelform/index.jsx | 31 + src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx | 133 +++++ src/menu/components/share/actioncomponent/actionform/index.jsx | 5 src/pc/components/navbar/normal-navbar/wrapsetting/settingform/index.jsx | 137 +++++ src/tabviews/custom/index.jsx | 10 src/pc/components/navbar/normal-navbar/index.scss | 39 + src/pc/components/navbar/normal-navbar/menusetting/index.scss | 7 package.json | 2 src/menu/components/tabs/antv-tabs/index.jsx | 1 26 files changed, 1,055 insertions(+), 301 deletions(-) diff --git a/package.json b/package.json index ad7bc05..dc3fd68 100644 --- a/package.json +++ b/package.json @@ -188,7 +188,7 @@ ] ] }, - "homepage": "./build", + "homepage": ".", "devDependencies": { "typescript": "^4.0.2" } diff --git a/src/assets/mobimg/navbar.png b/src/assets/mobimg/navbar.png new file mode 100644 index 0000000..1ea001e --- /dev/null +++ b/src/assets/mobimg/navbar.png Binary files differ diff --git a/src/index.js b/src/index.js index 4f87b72..f53f790 100644 --- a/src/index.js +++ b/src/index.js @@ -60,7 +60,7 @@ // 娴嬭瘯绯荤粺鏂囦欢缃簬admin涓� // fetch(process.env.NODE_ENV === 'production' ? '../options.json' : './options.json') -fetch('./options.json') +fetch('../options.json') .then(response => response.json()) .catch(() => { document.getElementById('root').innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh;">绯荤粺閰嶇疆淇℃伅鑾峰彇澶辫触锛岃鑱旂郴绠$悊鍛橈紒</div>' diff --git a/src/menu/components/share/actioncomponent/actionform/index.jsx b/src/menu/components/share/actioncomponent/actionform/index.jsx index db302a9..bd7648b 100644 --- a/src/menu/components/share/actioncomponent/actionform/index.jsx +++ b/src/menu/components/share/actioncomponent/actionform/index.jsx @@ -266,7 +266,7 @@ this.props.form.setFieldsValue(_fieldval) }) } else if (key === 'funcType') { - let _options = this.getOptions(this.state.openType, this.state.interType, value, card.pageTemplate, procMode) + let _options = this.getOptions(openType, this.state.interType, value, card.pageTemplate, procMode) let _fieldval = {} this.setState({ @@ -330,10 +330,9 @@ }) } else if (key === 'pageTemplate') { let _fieldval = {} - let _options = this.getOptions(this.state.openType, this.state.interType, this.state.funcType, value, procMode) + let _options = this.getOptions(openType, this.state.interType, this.state.funcType, value, procMode) this.setState({ - openType: value, formlist: this.state.formlist.map(item => { item.hidden = !_options.includes(item.key) diff --git a/src/menu/components/tabs/antv-tabs/index.jsx b/src/menu/components/tabs/antv-tabs/index.jsx index 2a6e059..01c055b 100644 --- a/src/menu/components/tabs/antv-tabs/index.jsx +++ b/src/menu/components/tabs/antv-tabs/index.jsx @@ -216,6 +216,7 @@ this.tabLabelRef.handleConfirm().then(res => { editab.label = res.label editab.icon = res.icon + editab.blacklist = res.blacklist if (editab.uuid) { tabs.subtabs = tabs.subtabs.map(t => { diff --git a/src/menu/components/tabs/tablabelform/index.jsx b/src/menu/components/tabs/tablabelform/index.jsx index 3a63a0d..784a9f9 100644 --- a/src/menu/components/tabs/tablabelform/index.jsx +++ b/src/menu/components/tabs/tablabelform/index.jsx @@ -12,10 +12,21 @@ inputSubmit: PropTypes.func // 鍥炶溅浜嬩欢 } - state = {} + state = {roleList: []} UNSAFE_componentWillMount () { + let roleList = sessionStorage.getItem('sysRoles') + if (roleList) { + try { + roleList = JSON.parse(roleList) + } catch { + roleList = [] + } + } else { + roleList = [] + } + this.setState({roleList}) } handleConfirm = () => { @@ -42,6 +53,7 @@ render() { const { tab } = this.props const { getFieldDecorator } = this.props.form + const { roleList } = this.state const formItemLayout = { labelCol: { @@ -85,6 +97,23 @@ )} </Form.Item> </Col> + <Col span={24}> + <Form.Item label="榛戝悕鍗�"> + {getFieldDecorator('blacklist', { + initialValue: tab.blacklist || [] + })( + <Select + showSearch + mode="multiple" + filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} + > + {roleList.map(option => + <Select.Option key={option.uuid} value={option.value}>{option.text}</Select.Option> + )} + </Select> + )} + </Form.Item> + </Col> </Row> </Form> ) diff --git a/src/menu/stylecontroller/index.jsx b/src/menu/stylecontroller/index.jsx index 9735a7e..cc674a1 100644 --- a/src/menu/stylecontroller/index.jsx +++ b/src/menu/stylecontroller/index.jsx @@ -268,6 +268,15 @@ this.updateStyle(_style) } + changeWidth = (val) => { + let _val = val + if (_val === '0px') { + _val = 'auto' + } + + this.updateStyle({width: _val}) + } + changeHeight = (val) => { let _val = val if (_val === '0px') { @@ -313,6 +322,17 @@ <div className="menu-style-controller"> <Form {...formItemLayout}> {card ? <Collapse expandIconPosition="right" destroyInactivePanel={true} defaultActiveKey={options[0]}> + {options.includes('width') ? <Panel header="瀹藉害" key="width"> + <Col span={24}> + <Form.Item + colon={false} + label={<Icon title="瀹藉害" type="column-width" />} + labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } + > + <StyleInput defaultValue={card.width || ''} options={['px']} onChange={this.changeWidth}/> + </Form.Item> + </Col> + </Panel> : null} {options.includes('height') ? <Panel header="楂樺害" key="height"> <Col span={24}> <Form.Item diff --git a/src/pc/components/navbar/normal-navbar/index.jsx b/src/pc/components/navbar/normal-navbar/index.jsx index 1ce4fff..a67fe8e 100644 --- a/src/pc/components/navbar/normal-navbar/index.jsx +++ b/src/pc/components/navbar/normal-navbar/index.jsx @@ -1,31 +1,25 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' -import { connect } from 'react-redux' import { is, fromJS } from 'immutable' -import { Icon, Popover, Modal, Pagination, notification } from 'antd' +import { Icon, Popover } from 'antd' -import asyncComponent from '@/utils/asyncComponent' import asyncIconComponent from '@/utils/asyncIconComponent' import MKEmitter from '@/utils/events.js' -import Utils from '@/utils/utils.js' +// import Utils from '@/utils/utils.js' import zhCN from '@/locales/zh-CN/model.js' import enUS from '@/locales/en-US/model.js' import './index.scss' -const SettingComponent = asyncIconComponent(() => import('@/menu/datasource')) const WrapComponent = asyncIconComponent(() => import('./wrapsetting')) -const CardComponent = asyncComponent(() => import('../cardcomponent')) -const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent')) +const MenuComponent = asyncIconComponent(() => import('./menusetting')) +// const CardComponent = asyncComponent(() => import('../cardcomponent')) 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 NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader')) -const ActionComponent = asyncComponent(() => import('@/menu/components/share/actioncomponent')) -const { confirm } = Modal +// const { confirm } = Modal -class DataCardEditComponent extends Component { +class NormalNavbar extends Component { static propTpyes = { card: PropTypes.object, deletecomponent: PropTypes.func, @@ -46,36 +40,15 @@ uuid: card.uuid, type: card.type, floor: card.floor, - tabId: card.tabId || '', - parentId: card.parentId || '', - format: 'array', // 缁勪欢灞炴�� - 鏁版嵁鏍煎紡 - pageable: true, // 缁勪欢灞炴�� - 鏄惁鍙垎椤� - switchable: true, // 缁勪欢灞炴�� - 鏁版嵁鏄惁鍙垏鎹� dataName: card.dataName || '', width: card.width || 24, name: card.name, subtype: card.subtype, - setting: { interType: 'system' }, - wrap: { name: card.name, width: card.width || 24, title: '', pagestyle: 'page', switch: 'false' }, - style: { marginLeft: '0px', marginRight: '0px', marginTop: '8px', marginBottom: '8px' }, - headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' }, - columns: [], - scripts: [], - action: [], - search: [], - btnlog: [], - subcards: [{ - uuid: Utils.getuuid(), - setting: { width: 6, type: 'simple'}, - style: { - borderWidth: '1px', borderColor: '#e8e8e8', - paddingTop: '15px', paddingBottom: '15px', paddingLeft: '15px', paddingRight: '15px', - marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' - }, - backStyle: {}, - elements: [], - backElements: [] - }] + wrap: { name: card.name, width: card.width || 1200 }, + logoStyle: { width: '100px' }, + style: { }, + links: [], + menus: [], } if (card.config) { @@ -84,28 +57,6 @@ _card.wrap = config.wrap _card.wrap.name = card.name _card.style = config.style - _card.headerStyle = config.headerStyle - - _card.subcards = config.subcards.map(scard => { - scard.uuid = Utils.getuuid() - scard.elements = scard.elements.map(elem => { - elem.uuid = Utils.getuuid() - return elem - }) - scard.backElements = scard.backElements.map(elem => { - elem.uuid = Utils.getuuid() - return elem - }) - return scard - }) - _card.action = config.action.map(col => { - col.uuid = Utils.getuuid() - return col - }) - _card.search = config.search.map(col => { - col.uuid = Utils.getuuid() - return col - }) } this.setState({ @@ -113,9 +64,6 @@ }) this.props.updateConfig(_card) } else { - card.action = card.action || [] // 鍏煎 - card.search = card.search || [] // 鍏煎 - this.setState({ card: fromJS(card).toJS() }) @@ -124,12 +72,10 @@ componentDidMount () { MKEmitter.addListener('submitStyle', this.getStyle) - MKEmitter.addListener('submitModal', this.handleSave) - MKEmitter.addListener('logButton', this.logButton) } shouldComponentUpdate (nextProps, nextState) { - return !is(fromJS(this.state), fromJS(nextState)) || (!this.props.menu && nextProps.menu) + return !is(fromJS(this.state), fromJS(nextState)) } /** @@ -140,22 +86,6 @@ return } MKEmitter.removeListener('submitStyle', this.getStyle) - MKEmitter.removeListener('submitModal', this.handleSave) - MKEmitter.removeListener('logButton', this.logButton) - } - - logButton = (id, item) => { - const { card } = this.state - - if (id !== card.uuid) return - - let btnlog = card.btnlog || [] - btnlog.push(item) - - this.setState({ - card: {...card, btnlog} - }) - this.props.updateConfig({...card, btnlog}) } /** @@ -188,54 +118,17 @@ this.props.updateConfig(card) } - /** - * @description 鍗曚釜鍗$墖淇℃伅鏇存柊 - */ - deleteCard = (cell) => { - let card = fromJS(this.state.card).toJS() - let _this = this - - confirm({ - content: '纭畾鍒犻櫎鍗$墖鍚楋紵', - onOk() { - card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid) - - let uuids = [] - cell.elements && cell.elements.forEach(c => { - if (c.eleType === 'button') { - uuids.push(c.uuid) - } - }) - cell.backElements && cell.backElements.forEach(c => { - if (c.eleType === 'button') { - uuids.push(c.uuid) - } - }) - MKEmitter.emit('delButtons', uuids) - - if (card.btnlog) { - card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid) - } - - _this.setState({card}) - _this.props.updateConfig(card) - }, - onCancel() {} - }) - } - - changeStyle = () => { - const { card } = this.state - - MKEmitter.emit('changeStyle', [card.uuid], ['background', 'border', 'padding', 'margin'], card.style) - } - getStyle = (comIds, style) => { const { card } = this.state - if (comIds.length !== 1 || comIds[0] !== card.uuid) return + if (comIds[0] !== card.uuid) return - let _card = {...card, style} + let _card = {...card} + if (comIds.length === 1) { + _card = {...card, style} + } else if (comIds[1] === 'logo') { + _card = {...card, logoStyle: style} + } this.setState({ card: _card @@ -244,134 +137,16 @@ this.props.updateConfig(_card) } - addSearch = () => { + changeStyle = () => { const { card } = this.state - let newcard = {} - newcard.uuid = Utils.getuuid() - newcard.focus = true - - newcard.label = 'label' - newcard.type = 'select' - newcard.resourceType = '0' - newcard.options = [] - newcard.setAll = 'false' - newcard.orderType = 'asc' - newcard.display = 'dropdown' - newcard.match = '=' - - // 娉ㄥ唽浜嬩欢-娣诲姞鎼滅储 - MKEmitter.emit('addSearch', card.uuid, newcard) + MKEmitter.emit('changeStyle', [card.uuid], ['background', 'shadow'], card.style) } - addButton = () => { + changeLogoStyle = () => { const { card } = this.state - let newcard = {} - newcard.uuid = Utils.getuuid() - newcard.focus = true - - newcard.label = 'label' - 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.btnstyle = {marginRight: '15px'} - - // 娉ㄥ唽浜嬩欢-娣诲姞鎸夐挳 - MKEmitter.emit('addButton', card.uuid, newcard) - } - - setSubConfig = (item) => { - const { card } = this.state - let btn = fromJS(item).toJS() - - if (btn.OpenType === 'pop' || btn.execMode === 'pop') { - if (!btn.modal) { - btn.modal = { - setting: { title: btn.label, width: 60, cols: '2', container: 'view', focus: '', finish: 'close', clickouter: 'unclose', display: 'modal' }, - tables: [], - groups: [], - fields: [] - } - } - MKEmitter.emit('changeModal', card, btn) - } else if (btn.OpenType === 'popview') { - MKEmitter.emit('changePopview', card, btn) - } - } - - handleSave = (_cards, btn, modal) => { - let card = fromJS(this.state.card).toJS() - - if (card.uuid !== _cards.uuid) return - - let _index = card.action.findIndex(cell => cell.uuid === btn.uuid) - - if (_index === -1) return - - card.action = card.action.map(cell => { - if (cell.uuid === btn.uuid) { - cell.modal = modal - } - - return cell - }) - - this.setState({card}) - this.props.updateConfig(card) - } - - handleLog = (type, logs, item) => { - let card = fromJS(this.state.card).toJS() - - if (type === 'revert') { - let done = false - if (item.$parentId) { - card.subcards.forEach(col => { - if (item.$parentId === col.uuid) { - if (item.$side !== 'back') { - col.elements = col.elements ? [...col.elements, item] : [item] - } else { - col.backElements = col.backElements ? [...col.backElements, item] : [item] - } - done = true - } - }) - } - - if (!done) { - card.action = card.action ? [...card.action, item] : [item] - } - - card.btnlog = logs - - this.setState({ card }) - this.props.updateConfig(card) - notification.success({ - top: 92, - message: '鎭㈠鎴愬姛锛�', - duration: 2 - }) - } else { - card.btnlog = logs - this.setState({ card }) - this.props.updateConfig(card) - notification.success({ - top: 92, - message: '娓呴櫎鎴愬姛锛�', - duration: 2 - }) - } + MKEmitter.emit('changeStyle', [card.uuid, 'logo'], ['width', 'margin'], card.logoStyle) } clickComponent = (e) => { @@ -384,54 +159,39 @@ render() { const { card } = this.state - let offset = 0 - if (card.wrap.cardFloat && card.wrap.cardFloat !== 'left') { - let _width = 0 - card.subcards.forEach(card => { - _width += card.setting.width - }) - offset = _width < 24 ? 24 - _width : 0 - if (card.wrap.cardFloat === 'center') { - offset = Math.floor(offset / 2) - } + let _style = {...card.style} + if (_style.shadow) { + _style.boxShadow = '0 0 4px ' + _style.shadow } return ( - <div className="menu-data-card-edit-box" style={{...card.style}} onClick={this.clickComponent} id={card.uuid}> - <NormalHeader defaultshow="hidden" config={card} updateComponent={this.updateComponent}/> + <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"> - <Icon className="plus" title="娣诲姞鎼滅储" onClick={this.addSearch} type="plus-circle" /> - <Icon className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton} type="plus-square" /> + <MenuComponent config={card} updateConfig={this.updateComponent} /> <WrapComponent config={card} updateConfig={this.updateComponent} /> - <CopyComponent type="datacard" card={card}/> - <PasteComponent config={card} options={['action', 'search', 'form']} updateConfig={this.updateComponent} /> + <CopyComponent type="normalnarbar" card={card}/> <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" /> - <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} /> <UserComponent config={card}/> <Icon className="close" title="鍒犻櫎缁勪欢" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} /> - <SettingComponent config={card} updateConfig={this.updateComponent} /> </div> } trigger="hover"> <Icon type="tool" /> </Popover> - <ActionComponent config={card} setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/> - {card.subcards.map((subcard, index) => (<CardComponent key={subcard.uuid} offset={!index ? offset : 0} cards={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))} - <div style={{clear: 'both'}}></div> - {card.wrap.pagestyle !== 'switch' && card.setting.laypage === 'true' ? <Pagination total={85} size="small" showTotal={total => `鍏� ${total} 鏉} pageSize={20} defaultCurrent={1}/> : null} + <div className="navbar-wrap" style={{width: card.wrap.width + 'px', height: card.wrap.height + 'px', lineHeight: card.wrap.height + 'px'}}> + {card.wrap.logo ? <Popover overlayClassName="mk-popover-control-wrap top-menu-popover" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ + <div className="mk-popover-control"> + <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeLogoStyle} type="font-colors" /> + </div> + } trigger="hover"> + <div className="logo" style={card.logoStyle}><img src={card.wrap.logo} alt=""/></div> + </Popover> : null} + <div className="menu">sdf</div> + <div className="link">asdfds</div> + </div> </div> ) } } -const mapStateToProps = (state) => { - return { - menu: state.customMenu - } -} - -const mapDispatchToProps = () => { - return {} -} - -export default connect(mapStateToProps, mapDispatchToProps)(DataCardEditComponent) \ No newline at end of file +export default NormalNavbar \ No newline at end of file diff --git a/src/pc/components/navbar/normal-navbar/index.scss b/src/pc/components/navbar/normal-navbar/index.scss index 6346310..bdba21d 100644 --- a/src/pc/components/navbar/normal-navbar/index.scss +++ b/src/pc/components/navbar/normal-navbar/index.scss @@ -1,12 +1,36 @@ -.menu-data-card-edit-box { - position: relative; +.normal-navbar-edit-box { + position: fixed; + top: 0px; + left: 0px; + width: 100%; box-sizing: border-box; background: #ffffff; background-position: center center; background-repeat: no-repeat; background-size: cover; - min-height: 20px; + min-height: 50px; + z-index: 2; + .navbar-wrap { + margin: 0 auto; + display: flex; + + .logo { + display: inline-block; + img { + max-width: 100%; + max-height: 100%; + } + } + .menu { + flex: 1; + display: inline-block; + } + .link { + flex: 1; + display: inline-block; + } + } .card-control { position: absolute; top: 0px; @@ -21,7 +45,7 @@ position: absolute; z-index: 2; font-size: 16px; - right: 1px; + right: 25px; top: 1px; cursor: pointer; padding: 5px; @@ -76,12 +100,15 @@ } } } -.menu-data-card-edit-box::after { +.normal-navbar-edit-box::after { display: block; content: ' '; clear: both; } -.menu-data-card-edit-box:hover { +.normal-navbar-edit-box:hover { z-index: 1; box-shadow: 0px 0px 4px #1890ff; } +.top-menu-popover { + padding-top: 0!important; +} \ No newline at end of file diff --git a/src/pc/components/navbar/normal-navbar/menusetting/index.jsx b/src/pc/components/navbar/normal-navbar/menusetting/index.jsx new file mode 100644 index 0000000..bb5070f --- /dev/null +++ b/src/pc/components/navbar/normal-navbar/menusetting/index.jsx @@ -0,0 +1,73 @@ +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 + } + + UNSAFE_componentWillMount () { + const { config } = this.props + + this.setState({menus: fromJS(config.menus).toJS()}) + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) + } + + 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 } = 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={800} + 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/pc/components/navbar/normal-navbar/menusetting/index.scss b/src/pc/components/navbar/normal-navbar/menusetting/index.scss new file mode 100644 index 0000000..04372e6 --- /dev/null +++ b/src/pc/components/navbar/normal-navbar/menusetting/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/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx b/src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx new file mode 100644 index 0000000..bd7216a --- /dev/null +++ b/src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx @@ -0,0 +1,133 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { Form, Row, Col, Input, Radio, Tooltip, Icon } 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' + } + + UNSAFE_componentWillMount () { + + } + + 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 } = 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={24}> + <Form.Item label="鑿滃崟鍚嶇О"> + {getFieldDecorator('name', { + initialValue: menu.name, + rules: [ + { + required: true, + message: '璇疯緭鍏ヨ彍鍗曞悕绉�!' + } + ] + })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} + </Form.Item> + </Col> + <Col span={24}> + <Form.Item label="灞炴��"> + {getFieldDecorator('property', { + initialValue: menu.property || 'menu' + })( + <Radio.Group onChange={this.changeProperty}> + <Radio value="menu">鑿滃崟</Radio> + <Radio value="link">閾炬帴</Radio> + <Radio value="classify">鍒嗙被</Radio> + </Radio.Group> + )} + </Form.Item> + </Col> + {property === 'link' ? <Col span={24}> + <Form.Item label={ + <Tooltip placement="topLeft" title="閾炬帴鑷冲綋鍓嶇郴缁熺殑鑿滃崟鏃讹紝鍙互浣跨敤 $ + 鑿滃崟ID锛屼緥濡傦細$dsdffowejdsfi銆�"> + <Icon type="question-circle" style={{color: '#c49f47', marginRight: '3px'}}/> + 閾炬帴鍦板潃 + </Tooltip> + }> + {getFieldDecorator('link', { + initialValue: menu.link || '', + rules: [ + { + required: true, + message: '璇疯緭鍏ラ摼鎺ュ湴鍧�!' + } + ] + })(<TextArea rows={2} />)} + </Form.Item> + </Col> : null} + {property === 'menu' ? <Col span={24}> + <Form.Item label={ + <Tooltip placement="topLeft" title="澶嶅埗鍏朵粬鑿滃崟鏃讹紝璇峰~鍐欏搴旂殑鑿滃崟ID銆�"> + <Icon type="question-circle" style={{color: '#c49f47', marginRight: '3px'}}/> + 澶嶅埗鑿滃崟 + </Tooltip> + }> + {getFieldDecorator('copyMenu', { + initialValue: menu.copyMenu || '' + })( + <Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} /> + )} + </Form.Item> + </Col> : null} + </Row> + </Form> + ) + } +} + +export default Form.create()(SettingForm) \ No newline at end of file diff --git a/src/pc/components/navbar/normal-navbar/menusetting/menuform/index.scss b/src/pc/components/navbar/normal-navbar/menusetting/menuform/index.scss new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/pc/components/navbar/normal-navbar/menusetting/menuform/index.scss diff --git a/src/pc/components/navbar/normal-navbar/menusetting/menutable/index.jsx b/src/pc/components/navbar/normal-navbar/menusetting/menutable/index.jsx new file mode 100644 index 0000000..6d38929 --- /dev/null +++ b/src/pc/components/navbar/normal-navbar/menusetting/menutable/index.jsx @@ -0,0 +1,168 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Table, Button, Modal } from 'antd' + +import MenuForm from '../menuform' +import Utils from '@/utils/utils.js' +import './index.scss' + +class SubTable extends Component { + static propTpyes = { + menus: PropTypes.object, // 鍗$墖琛屼俊鎭� + } + + state = { + data: [], + columns: [ + { title: 'Date', dataIndex: 'date', key: 'date' }, + { title: 'Name', dataIndex: 'name', key: 'name' }, + { + title: 'Status', + key: 'state', + render: () => ( + <span> + Finished + </span> + ), + }, + { title: 'Upgrade Status', dataIndex: 'upgradeNum', key: 'upgradeNum' }, + { + title: 'Action', + dataIndex: 'operation', + key: 'operation', + render: () => ( + <span className="table-operation"> + <a href>Pause</a> + <a href>Stop</a> + </span> + ), + }, + ] + } + + UNSAFE_componentWillMount () { + // const { data } = this.props + + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + handleSubmit = (e) => { + e.preventDefault() + + if (this.props.inputSubmit) { + this.props.inputSubmit() + } + } + + render() { + const { columns, data } = this.state + + return ( + <Table + className="components-table-demo-nested" + columns={columns} + dataSource={data} + /> + ) + } +} + +class MenuTable extends Component { + static propTpyes = { + menus: PropTypes.object, // 鍗$墖琛屼俊鎭� + } + + state = { + data: [], + editMenu: null, + columns: [ + { title: '鑿滃崟鍚嶇О', dataIndex: 'name', key: 'name' }, + { title: '灞炴��', dataIndex: 'property', key: 'property', render: text => { + if (text === 'menu') { + return '鑿滃崟' + } else { + return '鍒嗙被' + } + }}, + { title: 'Action', key: 'operation', render: () => <a href="#d">Publish</a> }, + ] + } + + UNSAFE_componentWillMount () { + const { menus } = this.props + + this.setState({data: fromJS(menus).toJS()}) + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + plusMenu = () => { + let _menu = { + name: '鑿滃崟', + property: 'classify', + level: 1, + children: [] + } + + this.setState({editMenu: _menu, visible: true}) + } + + menuSubmit = () => { + const { editMenu, data } = this.state + + this.menuRef.handleConfirm().then(res => { + let _menu = {...editMenu, ...res} + if (!_menu.uuid) { + _menu.uuid = Utils.getuuid() + this.setState({data: [...data, _menu]}) + } else { + this.setState({data: data.map(item => { + if (item.uuid === _menu.uuid) { + return _menu + } 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 + className="components-table-demo-nested" + columns={columns} + expandedRowRender={<SubTable />} + dataSource={data} + /> + <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/pc/components/navbar/normal-navbar/menusetting/menutable/index.scss b/src/pc/components/navbar/normal-navbar/menusetting/menutable/index.scss new file mode 100644 index 0000000..1a060dd --- /dev/null +++ b/src/pc/components/navbar/normal-navbar/menusetting/menutable/index.scss @@ -0,0 +1,10 @@ +.menu-control-wrap { + position: relative; + + .menu-plus { + float: right; + position: relative; + z-index: 1; + margin-bottom: 5px; + } +} \ No newline at end of file diff --git a/src/pc/components/navbar/normal-navbar/wrapsetting/index.jsx b/src/pc/components/navbar/normal-navbar/wrapsetting/index.jsx new file mode 100644 index 0000000..81346a6 --- /dev/null +++ b/src/pc/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/pc/components/navbar/normal-navbar/wrapsetting/index.scss b/src/pc/components/navbar/normal-navbar/wrapsetting/index.scss new file mode 100644 index 0000000..04372e6 --- /dev/null +++ b/src/pc/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/pc/components/navbar/normal-navbar/wrapsetting/settingform/index.jsx b/src/pc/components/navbar/normal-navbar/wrapsetting/settingform/index.jsx new file mode 100644 index 0000000..3a72098 --- /dev/null +++ b/src/pc/components/navbar/normal-navbar/wrapsetting/settingform/index.jsx @@ -0,0 +1,137 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { Form, Row, Col, Input, Tooltip, Icon, InputNumber } from 'antd' + +import asyncComponent from '@/utils/asyncComponent' +import './index.scss' + +const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent')) + +class SettingForm extends Component { + static propTpyes = { + dict: PropTypes.object, // 瀛楀吀椤� + config: PropTypes.object, // 鍗$墖琛屼俊鎭� + wrap: PropTypes.object, // 鏁版嵁婧愰厤缃� + inputSubmit: PropTypes.func // 鍥炶溅浜嬩欢 + } + + state = { + roleList: [] + } + + UNSAFE_componentWillMount () { + let roleList = sessionStorage.getItem('sysRoles') + if (roleList) { + try { + roleList = JSON.parse(roleList) + } catch { + roleList = [] + } + } else { + roleList = [] + } + + this.setState({roleList}) + } + + 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={ + <Tooltip placement="topLeft" title="瀵艰埅鏍忎富浣撳唴瀹瑰搴︼紙鍖呮嫭logo銆佽彍鍗曘�侀摼鎺ョ瓑锛夈��"> + <Icon type="question-circle" /> + 瀹藉害 + </Tooltip> + }> + {getFieldDecorator('width', { + initialValue: wrap.width || 1200, + rules: [ + { + required: true, + message: this.props.dict['form.required.input'] + '瀹藉害!' + } + ] + })(<InputNumber min={400} precision={0} 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> + <Col span={12}> + <Form.Item label="logo"> + {getFieldDecorator('logo', { + initialValue: wrap.logo + })( + <SourceComponent type="image" /> + )} + </Form.Item> + </Col> + </Row> + </Form> + </div> + ) + } +} + +export default Form.create()(SettingForm) \ No newline at end of file diff --git a/src/pc/components/navbar/normal-navbar/wrapsetting/settingform/index.scss b/src/pc/components/navbar/normal-navbar/wrapsetting/settingform/index.scss new file mode 100644 index 0000000..159130b --- /dev/null +++ b/src/pc/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/pc/menushell/card.jsx b/src/pc/menushell/card.jsx new file mode 100644 index 0000000..06beb23 --- /dev/null +++ b/src/pc/menushell/card.jsx @@ -0,0 +1,90 @@ +import React from 'react' +import { useDrag, useDrop } from 'react-dnd' + +import asyncComponent from '@/utils/asyncComponent' +import './index.scss' + +const AntvBar = asyncComponent(() => import('@/menu/components/chart/antv-bar')) +const MainSearch = asyncComponent(() => import('@/menu/components/search/main-search')) +const AntvPie = asyncComponent(() => import('@/menu/components/chart/antv-pie')) +const AntvTabs = asyncComponent(() => import('@/menu/components/tabs/antv-tabs')) +const DataCard = asyncComponent(() => import('@/menu/components/card/data-card')) +const PropCard = asyncComponent(() => import('@/menu/components/card/prop-card')) +const TableCard = asyncComponent(() => import('@/menu/components/card/table-card')) +const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table')) +const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group')) +const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor')) +const CodeSandbox = asyncComponent(() => import('@/menu/components/code/sandbox')) +const NormalNavbar = asyncComponent(() => import('@/pc/components/navbar/normal-navbar')) + +const Card = ({ id, card, moveCard, findCard, delCard, updateConfig }) => { + const originalIndex = findCard(id).index + const [{ isDragging }, drag] = useDrag({ + item: { type: 'menu', id, originalIndex, floor: card.floor }, + collect: monitor => ({ + isDragging: monitor.isDragging(), + }), + }) + const [, drop] = useDrop({ + accept: 'menu', + canDrop: () => true, + drop: (item) => { + const { id: draggedId, originalIndex, floor } = item + if (originalIndex === undefined) { + item.dropTargetId = id + } else if (draggedId && floor === card.floor) { + if (draggedId === id) return + const { index: originIndex } = findCard(draggedId) + + if (originIndex === -1) return + + const { index: overIndex } = findCard(id) + + moveCard(draggedId, overIndex) + } + } + }) + + let style = { opacity: 1} + if (isDragging) { + style = { opacity: 0.3} + } + let col = ' ant-col ant-col-' + (card.width || 24) + if (card.type === 'navbar') { + col = '' + } + + const getCardComponent = () => { + if (card.type === 'bar' || card.type === 'line') { + return (<AntvBar card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'navbar') { + return (<NormalNavbar card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'search') { + return (<MainSearch card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'pie') { + return (<AntvPie card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'tabs') { + return (<AntvTabs tabs={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'card' && card.subtype === 'datacard') { + return (<DataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'card' && card.subtype === 'propcard') { + return (<PropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'table' && card.subtype === 'tablecard') { + return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'table' && card.subtype === 'normaltable') { + return (<NormalTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'group' && card.subtype === 'normalgroup') { + return (<NormalGroup group={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'editor') { + return (<BraftEditor card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'code') { + return (<CodeSandbox card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } + } + return ( + <div className={`mk-component-card ${col}`} ref={node => drag(drop(node))} style={style}> + {getCardComponent()} + </div> + ) +} +export default Card diff --git a/src/pc/menushell/index.jsx b/src/pc/menushell/index.jsx new file mode 100644 index 0000000..714e6c9 --- /dev/null +++ b/src/pc/menushell/index.jsx @@ -0,0 +1,165 @@ +import React, { useState } from 'react' +import { useDrop } from 'react-dnd' +import { is, fromJS } from 'immutable' +import update from 'immutability-helper' +import { Empty, notification, Modal } from 'antd' + +import Utils from '@/utils/utils.js' +import MKEmitter from '@/utils/events.js' +import MenuUtils from '@/menu/utils/menuUtils.js' +import Card from './card' +import './index.scss' + +const { confirm } = Modal + +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}) + } + + if (!is(fromJS(cards), fromJS(menu.components))) { + setCards(menu.components) + } + + const findCard = id => { + const card = cards.filter(c => `${c.uuid}` === id)[0] + return { + card, + index: cards.indexOf(card), + } + } + + const updateConfig = (element) => { + handleList({...menu, components: cards.map(item => item.uuid === element.uuid ? element : item)}) + } + + const deleteCard = (id) => { + const { card } = findCard(id) + + let hasComponent = false + if (card.type === 'tabs') { + card.subtabs.forEach(tab => { + if (tab.components.length > 0) { + hasComponent = true + } + }) + } + + let uuids = MenuUtils.getDelButtonIds(card) + + confirm({ + title: `纭畾鍒犻櫎銆�${card.name}銆嬪悧锛焋, + content: hasComponent ? '褰撳墠缁勪欢涓惈鏈夊瓙缁勪欢锛�' : '', + onOk() { + MKEmitter.emit('delButtons', uuids) + handleList({...menu, components: cards.filter(item => item.uuid !== card.uuid)}) + }, + onCancel() {} + }) + } + + const [, drop] = useDrop({ + accept: 'menu', + drop(item) { + if (item.hasOwnProperty('originalIndex') || item.added) { + delete item.added // 鍒犻櫎缁勪欢娣诲姞鏍囪 + return + } + + if (item.component === 'search') { // 鎼滅储缁勪欢涓嶅彲閲嶅娣诲姞 + if (cards.filter(card => card.type === 'search').length > 0) { + notification.warning({ + top: 92, + message: '鎼滅储鏉′欢涓嶅彲閲嶅娣诲姞锛�', + duration: 5 + }) + return + } + } else if (item.component === 'navbar') { + if (cards.filter(card => card.type === 'navbar').length > 0) { + notification.warning({ + top: 92, + message: '瀵艰埅鏍忎笉鍙噸澶嶆坊鍔狅紒', + duration: 5 + }) + return + } + } + + let name = '' + let names = { + bar: '鏌辩姸鍥�', + line: '鎶樼嚎鍥�', + tabs: '鏍囩缁�', + pie: '楗煎浘', + search: '鎼滅储', + table: '琛ㄦ牸', + group: '鍒嗙粍', + editor: '瀵屾枃鏈�', + code: '鑷畾涔�', + navbar: '瀵艰埅鏍�', + card: '鍗$墖' + } + 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 // 鏂版坊鍔犳爣蹇楋紝鐢ㄤ簬鍒濆鍖� + } + + let targetId = '' + + if (item.dropTargetId) { + targetId = item.dropTargetId + delete item.dropTargetId + } else if (cards.length > 0) { + targetId = cards.slice(-1)[0].uuid + } + + const { index: overIndex } = findCard(`${targetId}`) + const _cards = update(cards, { $splice: [[overIndex + 1, 0, newcard]] }) + + handleList({...menu, components: _cards}) + } + }) + + return ( + <div ref={drop} className="menu-shell-inner" id="menu-shell-inner" style={menu.style}> + <div className="ant-row"> + {cards.map(card => ( + <Card + id={card.uuid} + key={card.uuid} + card={card} + moveCard={moveCard} + delCard={deleteCard} + findCard={findCard} + updateConfig={updateConfig} + /> + ))} + </div> + {cards.length === 0 ? + <Empty description="璇锋坊鍔犵粍浠�" /> : null + } + </div> + ) +} +export default Container diff --git a/src/pc/menushell/index.scss b/src/pc/menushell/index.scss new file mode 100644 index 0000000..21f8a7d --- /dev/null +++ b/src/pc/menushell/index.scss @@ -0,0 +1,23 @@ +.menu-shell-inner { + min-height: calc(100vh - 100px); + width: 100%; + background-size: 100%; + + .anticon { + cursor: unset; + } + + .mk-component-card { + position: relative; + } + + >.ant-empty { + padding-top: 150px; + } + .anticon-tool { + color: rgba(0, 0, 0, 0.55); + } + .anticon-tool:hover { + color: #1890ff; + } +} \ No newline at end of file diff --git a/src/pc/modulesource/option.jsx b/src/pc/modulesource/option.jsx index 9c9ee1c..81ce70d 100644 --- a/src/pc/modulesource/option.jsx +++ b/src/pc/modulesource/option.jsx @@ -14,9 +14,11 @@ import Pie1 from '@/assets/mobimg/ring.png' import Pie2 from '@/assets/mobimg/nightingale.png' import Mainsearch from '@/assets/mobimg/mainsearch.png' +import Navbar from '@/assets/mobimg/navbar.png' // 缁勪欢閰嶇疆淇℃伅 export const menuOptions = [ + { type: 'menu', url: Navbar, component: 'navbar', subtype: 'navbar', title: '瀵艰埅鏍�', width: 1200 }, { type: 'menu', url: tabs, component: 'tabs', subtype: 'tabs', title: '鏍囩椤�', width: 24 }, { type: 'menu', url: Mainsearch, component: 'search', subtype: 'mainsearch', title: '鎼滅储鏉′欢', width: 24 }, { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '鏁版嵁鍗�', width: 24 }, diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx index 01b346d..1cf5080 100644 --- a/src/tabviews/custom/index.jsx +++ b/src/tabviews/custom/index.jsx @@ -414,6 +414,16 @@ return false } + item.subtabs = item.subtabs.filter(tab => { + if ( + tab.blacklist && tab.blacklist.length > 0 && + tab.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0 + ) { + return false + } + return true + }) + item.subtabs = item.subtabs.map(tab => { tab.components = this.filterComponent(tab.components, roleId, permAction, permMenus) return tab diff --git a/src/templates/sharecomponent/settingcomponent/settingform/simplescript/index.jsx b/src/templates/sharecomponent/settingcomponent/settingform/simplescript/index.jsx index 3a5c5d5..c733f72 100644 --- a/src/templates/sharecomponent/settingcomponent/settingform/simplescript/index.jsx +++ b/src/templates/sharecomponent/settingcomponent/settingform/simplescript/index.jsx @@ -415,14 +415,14 @@ <div className="modal-menu-setting-script"> <Form {...formItemLayout}> <Row gutter={24}> - <Col span={8}> - <Form.Item label={'鍥炶皟琛ㄥ悕'} style={{whiteSpace: 'nowrap', margin: 0}}> + <Col span={4}> + <Form.Item labelCol={{span: 17}} wrapperCol={{span: 7}} label={'鍥炶皟琛ㄥ悕'} style={{whiteSpace: 'nowrap', margin: 0}}> {setting.cbTable} </Form.Item> </Col> - <Col span={16}> - <Form.Item label={'鎶ラ敊瀛楁'} style={{margin: 0}}> - ErrorCode, retmsg + <Col span={20}> + <Form.Item labelCol={{span: 4}} wrapperCol={{span: 20}} label={'鎶ラ敊瀛楁'} style={{margin: 0}}> + ErrorCode锛堝鍔犲悗缂�NT琛ㄧず鏁版嵁涓嶅洖婊氾紝濡侲NT銆丯NT銆丗NT銆丯MNT锛�, retmsg </Form.Item> </Col> {usefulFields ? <Col span={24} className="sqlfield"> diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx index 9628725..959975f 100644 --- a/src/views/pcdesign/index.jsx +++ b/src/views/pcdesign/index.jsx @@ -5,10 +5,8 @@ import moment from 'moment' import HTML5Backend from 'react-dnd-html5-backend' import { ConfigProvider, notification, Modal, Collapse, Switch, Button, Icon } from 'antd' -// import html2canvas from 'html2canvas' import Api from '@/api' -// import options from '@/store/options.js' import Utils from '@/utils/utils.js' import zhCN from '@/locales/zh-CN/mob.js' import enUS from '@/locales/en-US/mob.js' @@ -25,7 +23,7 @@ const { confirm } = Modal const MenuForm = asyncComponent(() => import('./menuform')) -const MenuShell = asyncComponent(() => import('@/menu/menushell')) +const MenuShell = asyncComponent(() => import('@/pc/menushell')) const SourceWrap = asyncComponent(() => import('@/pc/modulesource')) const BgController = asyncComponent(() => import('@/pc/bgcontroller')) const PasteController = asyncComponent(() => import('@/menu/pastecontroller')) @@ -40,6 +38,7 @@ sessionStorage.setItem('isEditState', 'true') sessionStorage.setItem('editMenuType', 'menu') // 缂栬緫鑿滃崟绫诲瀷 +sessionStorage.setItem('appType', 'pc') // 搴旂敤绫诲瀷 document.body.className = '' window.GLOB.UserComponentMap = new Map() // 缂撳瓨鐢ㄦ埛鑷畾涔夌粍浠� -- Gitblit v1.8.0