| | |
| | | .ant-input-number { |
| | | width: 100%; |
| | | } |
| | | .ant-tabs-nav-wrap { |
| | | text-align: center; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | class antvBarLineChart extends Component { |
| | | static propTpyes = { |
| | | config: PropTypes.object, |
| | | menu: PropTypes.object, |
| | | card: PropTypes.object, |
| | | updateConfig: PropTypes.func, |
| | | } |
| | |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { card, config } = this.props |
| | | const { card, menu } = this.props |
| | | |
| | | if (card.isNew) { |
| | | let _plot = { |
| | |
| | | _plot.shape = 'hv' |
| | | } |
| | | |
| | | let name = '' |
| | | let names = { |
| | | bar: '柱状图', |
| | | line: '折线图', |
| | | } |
| | | let i = 1 |
| | | |
| | | while (!name) { |
| | | let _name = names[card.type] + i |
| | | if (config.components.filter(com => com.setting && com.setting.name === _name).length === 0) { |
| | | name = _name |
| | | } |
| | | i++ |
| | | } |
| | | |
| | | let dataName = '' |
| | | |
| | | if (card.floor === 1) { |
| | | while (!dataName) { |
| | | let _dataName = Utils.getdataName() |
| | | if (config.components.filter(com => com.dataName === _dataName).length === 0) { |
| | | if (menu.components.filter(com => com.dataName === _dataName).length === 0) { |
| | | dataName = _dataName |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | switchable: false, // 组件属性 - 数据是否可切换 |
| | | dataName: dataName, |
| | | subtype: card.subtype, |
| | | setting: {span: 12, height: 400, interType: 'system', name}, |
| | | setting: {span: card.floor === 1 ? 12 : 24, height: 400, interType: 'system', name: card.name}, |
| | | columns: [], |
| | | scripts: [], |
| | | search: [], |
| | |
| | | } |
| | | } |
| | | |
| | | plotChange = (_plot) => { |
| | | const { config } = this.props |
| | | |
| | | if (_plot.datatype === 'statistics') { |
| | | _plot.Yaxis = [_plot.InfoValue] |
| | | } |
| | | |
| | | let _charts = fromJS(config.charts).toJS() |
| | | |
| | | _charts = _charts.map(item => { |
| | | if (item.uuid === _plot.uuid) { |
| | | if (!is(fromJS(item), fromJS(_plot))) { |
| | | let _element = document.getElementById(_plot.uuid) |
| | | if (_element) { |
| | | _element.innerHTML = '' |
| | | } |
| | | } |
| | | return _plot |
| | | } |
| | | return item |
| | | }) |
| | | |
| | | this.props.plotchange({...config, charts: _charts}) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | updateComponent = (component) => { |
| | |
| | | |
| | | render() { |
| | | const { card } = this.state |
| | | const { config } = this.props |
| | | const { menu } = this.props |
| | | |
| | | return ( |
| | | <div className="menu-line-chart-edit-box" style={{height: card.setting.height || 400}}> |
| | | <SettingComponent |
| | | config={card} |
| | | menu={config} |
| | | menu={menu} |
| | | updateConfig={this.updateComponent} |
| | | /> |
| | | <div className="chart-header"> |
| | | <span className="chart-title">{card.setting.title || ''}</span> |
| | | <SearchComponent |
| | | menu={config} |
| | | menu={menu} |
| | | config={card} |
| | | sysRoles={config.sysRoles} |
| | | sysRoles={menu.sysRoles} |
| | | optionLibs={null} |
| | | updatesearch={this.updateComponent} |
| | | /> |
| | | </div> |
| | | <ActionComponent |
| | | type="chart" |
| | | menu={config} |
| | | menu={menu} |
| | | config={card} |
| | | tabs={[]} |
| | | // setSubConfig={(_btn) => this.setSubConfig(_btn, 'button')} |
| | |
| | | |
| | | const SettingComponent = asyncComponent(() => import('../tabsetting')) |
| | | const TabLabelComponent = asyncComponent(() => import('../tablabelform')) |
| | | const TabComponents = asyncComponent(() => import('../tabcomponents')) |
| | | |
| | | const { TabPane } = Tabs |
| | | const { confirm } = Modal |
| | | |
| | | class antvBarLineChart extends Component { |
| | | static propTpyes = { |
| | | config: PropTypes.object, |
| | | menu: PropTypes.object, |
| | | tabs: PropTypes.object, |
| | | updateConfig: PropTypes.func, |
| | | } |
| | |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { tabs, config } = this.props |
| | | const { tabs } = this.props |
| | | |
| | | if (tabs.isNew) { |
| | | let name = '' |
| | | let i = 1 |
| | | |
| | | while (!name) { |
| | | let _name = '标签页' + i |
| | | if (config.components.filter(com => com.setting && com.setting.name === _name).length === 0) { |
| | | name = _name |
| | | } |
| | | i++ |
| | | } |
| | | |
| | | let _tabs = { |
| | | uuid: tabs.uuid, |
| | | type: tabs.type, |
| | | floor: tabs.floor, |
| | | subtype: tabs.subtype, |
| | | setting: {span: 12, position: 'top', tabStyle: 'line', name}, |
| | | setting: {span: 12, position: 'top', tabStyle: 'line', name: tabs.name}, |
| | | subtabs: [{ |
| | | uuid: Utils.getuuid(), |
| | | label: 'Tab 1', |
| | | icon: '', |
| | | subcomponents: [], |
| | | components: [], |
| | | }, { |
| | | uuid: Utils.getuuid(), |
| | | label: 'Tab 2', |
| | | icon: '', |
| | | subcomponents: [], |
| | | components: [], |
| | | }, { |
| | | uuid: Utils.getuuid(), |
| | | label: 'Tab 3', |
| | | icon: '', |
| | | subcomponents: [], |
| | | components: [], |
| | | }] |
| | | } |
| | | this.setState({ |
| | |
| | | } |
| | | } |
| | | |
| | | componentDidMount () { } |
| | | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | if (!is(fromJS(this.props.plot), fromJS(nextProps.plot))) { |
| | | |
| | | } |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | updateComponent = (component) => { |
| | | |
| | | 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) |
| | | } |
| | | |
| | | tabAdd = (e) => { |
| | |
| | | uuid: '', |
| | | label: '', |
| | | icon: '', |
| | | subcomponents: [] |
| | | components: [] |
| | | }, |
| | | labelvisible: true |
| | | }) |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { menu } = this.props |
| | | const { tabs, dict, labelvisible, editab } = this.state |
| | | |
| | | return ( |
| | |
| | | <span>{tab.icon ? <Icon type={tab.icon} /> : null}{tab.label}</span> |
| | | </Popover> |
| | | } key={tab.uuid}> |
| | | Content of Tab Pane {tab.label} |
| | | {/* Content of Tab Pane {tab.label} */} |
| | | <TabComponents menu={menu} config={tab} handleList={this.updateTabComponent} deleteCard={this.deleteCard} /> |
| | | </TabPane> |
| | | ))} |
| | | <TabPane className="tab-add" disabled tab={<Icon onClick={this.tabAdd} type="plus" />} key="add"></TabPane> |
| | |
| | | top: 0px; |
| | | } |
| | | .ant-tabs-card { |
| | | .ant-tabs-card-bar .ant-tabs-tab:last-child { |
| | | .ant-tabs-left-bar, .ant-tabs-right-bar { |
| | | .ant-tabs-tab { |
| | | > span { |
| | | padding: 0px 16px; |
| | | } |
| | | .anticon-plus { |
| | | padding: 0px 16px; |
| | | } |
| | | } |
| | | .ant-tabs-tab-active { |
| | | padding-left: 0px!important; |
| | | padding-right: 0px!important; |
| | | } |
| | | } |
| | | |
| | | .ant-tabs-card-bar { |
| | | .ant-tabs-tab { |
| | | padding: 0px; |
| | | > span { |
| | | display: inline-block; |
| | | padding: 0px 16px; |
| | | } |
| | | } |
| | | .ant-tabs-tab:last-child { |
| | | padding: 0px; |
| | | border: 0px; |
| | | background: transparent; |
| | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .menu-tabs-edit-box:hover { |
| | | box-shadow: 0px 0px 2px #e8e8e8; |
| | | } |
New file |
| | |
| | | import React from 'react' |
| | | import { useDrag, useDrop } from 'react-dnd' |
| | | import { Icon } from 'antd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import './index.scss' |
| | | |
| | | const AntvBar = asyncComponent(() => import('@/menu/components/chart/antv-bar')) |
| | | const AntvTabs = asyncComponent(() => import('@/menu/components/tabs/antv-tabs')) |
| | | |
| | | const Card = ({ id, menu, card, moveCard, findCard, delCard, hasDrop, doubleClickCard, updateConfig }) => { |
| | | const originalIndex = findCard(id).index |
| | | const [{ isDragging }, drag] = useDrag({ |
| | | item: { type: 'menu', id, originalIndex }, |
| | | collect: monitor => ({ |
| | | isDragging: monitor.isDragging(), |
| | | }), |
| | | }) |
| | | const [, drop] = useDrop({ |
| | | accept: 'menu', |
| | | canDrop: () => true, |
| | | drop: (item) => { |
| | | if (!item.hasOwnProperty('originalIndex')) { |
| | | hasDrop(card) |
| | | } |
| | | }, |
| | | hover({ id: draggedId }) { |
| | | if (!draggedId) return |
| | | if (draggedId !== id) { |
| | | const { index: overIndex } = findCard(id) |
| | | moveCard(draggedId, overIndex) |
| | | } |
| | | }, |
| | | }) |
| | | |
| | | let style = { opacity: 1} |
| | | if (isDragging) { |
| | | style = { opacity: 0.3} |
| | | } |
| | | |
| | | const getCardComponent = () => { |
| | | if (card.type === 'bar' || card.type === 'line') { |
| | | return (<AntvBar menu={menu} card={card} updateConfig={updateConfig} />) |
| | | } else if (card.type === 'tabs') { |
| | | return (<AntvTabs menu={menu} tabs={card} updateConfig={updateConfig} />) |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div className={'ant-col mk-component-card ant-col-' + (card.setting ? card.setting.span : 24)} ref={node => drag(drop(node))} style={style}> |
| | | {getCardComponent()} |
| | | <Icon className="remove-component" title="delete" type="delete" onClick={() => delCard(id)} /> |
| | | </div> |
| | | ) |
| | | } |
| | | export default Card |
New file |
| | |
| | | import React, { useState } from 'react' |
| | | import { useDrop } from 'react-dnd' |
| | | import { is, fromJS } from 'immutable' |
| | | import update from 'immutability-helper' |
| | | import { Empty, notification } from 'antd' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import Card from './card' |
| | | import './index.scss' |
| | | |
| | | const Container = ({menu, config, handleList, deleteCard, doubleClickCard }) => { |
| | | let target = null |
| | | |
| | | const [cards, setCards] = useState(config.components) |
| | | const moveCard = (id, atIndex) => { |
| | | const { card, index } = findCard(id) |
| | | const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] }) |
| | | handleList({...config, components: _cards}) |
| | | } |
| | | |
| | | if (!is(fromJS(cards), fromJS(config.components))) { |
| | | setCards(config.components) |
| | | } |
| | | |
| | | const findCard = id => { |
| | | const card = cards.filter(c => `${c.uuid}` === id)[0] |
| | | return { |
| | | card, |
| | | index: cards.indexOf(card), |
| | | } |
| | | } |
| | | |
| | | const hasDrop = (item) => { |
| | | target = item |
| | | } |
| | | |
| | | const updateConfig = (element) => { |
| | | handleList({...config, components: cards.map(item => item.uuid === element.uuid ? element : item)}) |
| | | } |
| | | |
| | | const [, drop] = useDrop({ |
| | | accept: 'menu', |
| | | drop(item) { |
| | | if (item.hasOwnProperty('originalIndex') || item.added) { |
| | | return |
| | | } |
| | | item.added = true |
| | | |
| | | if (item.component === 'search') { // 搜索组件不可重复添加 |
| | | if (cards.filter(card => card.type === 'search').length > 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '搜索条件不可重复添加!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | } |
| | | |
| | | let newcard = { |
| | | uuid: Utils.getuuid(), |
| | | type: item.component, |
| | | subtype: item.subtype, |
| | | floor: 2, // 组件的层级 |
| | | isNew: true // 新添加标志,用于初始化 |
| | | } |
| | | |
| | | let targetId = cards.length > 0 ? cards[cards.length - 1].uuid : 0 |
| | | if (target) { |
| | | targetId = target.uuid |
| | | } |
| | | |
| | | const { index: overIndex } = findCard(`${targetId}`) |
| | | let targetIndex = overIndex |
| | | |
| | | targetIndex++ |
| | | |
| | | const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] }) |
| | | |
| | | handleList({...config, components: _cards}) |
| | | target = null |
| | | } |
| | | }) |
| | | |
| | | return ( |
| | | <div ref={drop} className="ant-row tab-shell-inner"> |
| | | {cards.map(card => ( |
| | | <Card |
| | | id={card.uuid} |
| | | key={card.uuid} |
| | | menu={menu} |
| | | config={config} |
| | | card={card} |
| | | moveCard={moveCard} |
| | | delCard={deleteCard} |
| | | findCard={findCard} |
| | | hasDrop={hasDrop} |
| | | updateConfig={updateConfig} |
| | | doubleClickCard={doubleClickCard} |
| | | /> |
| | | ))} |
| | | {cards.length === 0 ? |
| | | <Empty description="请添加组件" /> : null |
| | | } |
| | | </div> |
| | | ) |
| | | } |
| | | export default Container |
New file |
| | |
| | | .tab-shell-inner { |
| | | margin: -8px; |
| | | |
| | | >.ant-col { |
| | | padding: 8px; |
| | | } |
| | | .anticon { |
| | | cursor: unset; |
| | | } |
| | | |
| | | .mk-component-card { |
| | | position: relative; |
| | | .remove-component { |
| | | position: absolute; |
| | | right: 42px; |
| | | top: -16px; |
| | | color: #ff4d4f; |
| | | border-radius: 2px; |
| | | font-size: 16px; |
| | | padding: 5px; |
| | | cursor: pointer; |
| | | opacity: 0; |
| | | transition: opacity 0.2s; |
| | | } |
| | | } |
| | | .mk-component-card:hover { |
| | | .remove-component { |
| | | opacity: 1; |
| | | } |
| | | .model-datasource > .anticon-setting, .model-menu-tabs-setting > .anticon-setting { |
| | | opacity: 1; |
| | | } |
| | | } |
| | | >.ant-empty { |
| | | padding: 60px 0px 70px; |
| | | } |
| | | |
| | | .model-datasource > .anticon-setting, .model-menu-tabs-setting > .anticon-setting { |
| | | font-size: 16px; |
| | | padding: 5px; |
| | | position: absolute; |
| | | right: 0px; |
| | | top: -30px; |
| | | opacity: 0; |
| | | cursor: pointer; |
| | | transition: opacity 0.2s; |
| | | } |
| | | } |
| | |
| | | const AntvBar = asyncComponent(() => import('@/menu/components/chart/antv-bar')) |
| | | const AntvTabs = asyncComponent(() => import('@/menu/components/tabs/antv-tabs')) |
| | | |
| | | const Card = ({ id, config, card, moveCard, findCard, delCard, hasDrop, doubleClickCard, updateConfig }) => { |
| | | const Card = ({ id, menu, card, moveCard, findCard, delCard, hasDrop, doubleClickCard, updateConfig }) => { |
| | | const originalIndex = findCard(id).index |
| | | const [{ isDragging }, drag] = useDrag({ |
| | | item: { type: 'menu', id, originalIndex }, |
| | |
| | | |
| | | const getCardComponent = () => { |
| | | if (card.type === 'bar' || card.type === 'line') { |
| | | return (<AntvBar config={config} card={card} updateConfig={updateConfig} />) |
| | | return (<AntvBar menu={menu} card={card} updateConfig={updateConfig} />) |
| | | } else if (card.type === 'tabs') { |
| | | return (<AntvTabs config={config} tabs={card} updateConfig={updateConfig} />) |
| | | return (<AntvTabs menu={menu} tabs={card} updateConfig={updateConfig} />) |
| | | } |
| | | } |
| | | |
| | |
| | | import Card from './card' |
| | | import './index.scss' |
| | | |
| | | const Container = ({config, handleList, deleteCard, doubleClickCard }) => { |
| | | const Container = ({menu, handleList, deleteCard, doubleClickCard }) => { |
| | | let target = null |
| | | |
| | | const [cards, setCards] = useState(config.components) |
| | | 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({...config, components: _cards}) |
| | | handleList({...menu, components: _cards}) |
| | | } |
| | | |
| | | if (!is(fromJS(cards), fromJS(config.components))) { |
| | | setCards(config.components) |
| | | if (!is(fromJS(cards), fromJS(menu.components))) { |
| | | setCards(menu.components) |
| | | } |
| | | |
| | | const findCard = id => { |
| | |
| | | } |
| | | |
| | | const updateConfig = (element) => { |
| | | handleList({...config, components: cards.map(item => item.uuid === element.uuid ? element : item)}) |
| | | handleList({...menu, components: cards.map(item => item.uuid === element.uuid ? element : item)}) |
| | | } |
| | | |
| | | const [, drop] = useDrop({ |
| | | accept: 'menu', |
| | | drop(item) { |
| | | if (item.hasOwnProperty('originalIndex')) { |
| | | if (item.hasOwnProperty('originalIndex') || item.added) { |
| | | return |
| | | } |
| | | |
| | | if (item.component === 'search') { // 搜索组件不可重复添加 |
| | | if (cards.filter(card => card.type === 'search').length > 0) { |
| | | notification.warning({ |
| | |
| | | }) |
| | | return |
| | | } |
| | | } |
| | | |
| | | let name = '' |
| | | let names = { |
| | | bar: '柱状图', |
| | | line: '折线图', |
| | | tabs: '标签组' |
| | | } |
| | | let i = 1 |
| | | |
| | | while (!name && names[item.component]) { |
| | | let _name = names[item.component] + i |
| | | if (menu.components.filter(com => com.setting && com.setting.name === _name).length === 0) { |
| | | name = _name |
| | | } |
| | | i++ |
| | | } |
| | | |
| | | let newcard = { |
| | |
| | | |
| | | const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] }) |
| | | |
| | | handleList({...config, components: _cards}) |
| | | handleList({...menu, components: _cards}) |
| | | target = null |
| | | } |
| | | }) |
| | |
| | | <Card |
| | | id={card.uuid} |
| | | key={card.uuid} |
| | | config={config} |
| | | menu={menu} |
| | | card={card} |
| | | moveCard={moveCard} |
| | | delCard={deleteCard} |
New file |
| | |
| | | import React from 'react' |
| | | import { useDrag, useDrop } from 'react-dnd' |
| | | import { Icon } from 'antd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import './index.scss' |
| | | |
| | | const AntvBar = asyncComponent(() => import('@/menu/components/chart/antv-bar')) |
| | | const AntvTabs = asyncComponent(() => import('@/menu/components/tabs/antv-tabs')) |
| | | |
| | | const Card = ({ id, menu, card, moveCard, findCard, delCard, hasDrop, doubleClickCard, updateConfig }) => { |
| | | const originalIndex = findCard(id).index |
| | | const [{ isDragging }, drag] = useDrag({ |
| | | item: { type: 'menu', id, originalIndex }, |
| | | collect: monitor => ({ |
| | | isDragging: monitor.isDragging(), |
| | | }), |
| | | }) |
| | | const [, drop] = useDrop({ |
| | | accept: 'menu', |
| | | canDrop: () => true, |
| | | drop: (item) => { |
| | | if (!item.hasOwnProperty('originalIndex')) { |
| | | hasDrop(card) |
| | | } |
| | | }, |
| | | hover({ id: draggedId }) { |
| | | if (!draggedId) return |
| | | if (draggedId !== id) { |
| | | const { index: overIndex } = findCard(id) |
| | | moveCard(draggedId, overIndex) |
| | | } |
| | | }, |
| | | }) |
| | | |
| | | let style = { opacity: 1} |
| | | if (isDragging) { |
| | | style = { opacity: 0.3} |
| | | } |
| | | |
| | | const getCardComponent = () => { |
| | | if (card.type === 'bar' || card.type === 'line') { |
| | | return (<AntvBar menu={menu} card={card} updateConfig={updateConfig} />) |
| | | } else if (card.type === 'tabs') { |
| | | return (<AntvTabs menu={menu} tabs={card} updateConfig={updateConfig} />) |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div className={'ant-col mk-component-card ant-col-' + (card.setting ? card.setting.span : 12)} ref={node => drag(drop(node))} style={style}> |
| | | {getCardComponent()} |
| | | <Icon className="remove-component" title="delete" type="delete" onClick={() => delCard(id)} /> |
| | | </div> |
| | | ) |
| | | } |
| | | export default Card |
New file |
| | |
| | | import React, { useState } from 'react' |
| | | import { useDrop } from 'react-dnd' |
| | | import { is, fromJS } from 'immutable' |
| | | import update from 'immutability-helper' |
| | | import { Empty, notification } from 'antd' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import Card from './card' |
| | | import './index.scss' |
| | | |
| | | const Container = ({menu, handleList, deleteCard, doubleClickCard }) => { |
| | | let target = null |
| | | |
| | | 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 hasDrop = (item) => { |
| | | target = item |
| | | } |
| | | |
| | | const updateConfig = (element) => { |
| | | handleList({...menu, components: cards.map(item => item.uuid === element.uuid ? element : item)}) |
| | | } |
| | | |
| | | const [, drop] = useDrop({ |
| | | accept: 'menu', |
| | | drop(item) { |
| | | if (item.hasOwnProperty('originalIndex') || item.added) { |
| | | return |
| | | } |
| | | if (item.component === 'search') { // 搜索组件不可重复添加 |
| | | if (cards.filter(card => card.type === 'search').length > 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '搜索条件不可重复添加!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | } |
| | | |
| | | let name = '' |
| | | let names = { |
| | | bar: '柱状图', |
| | | line: '折线图', |
| | | tabs: '标签组' |
| | | } |
| | | let i = 1 |
| | | |
| | | while (!name && names[item.component]) { |
| | | let _name = names[item.component] + i |
| | | if (menu.components.filter(com => com.setting && com.setting.name === _name).length === 0) { |
| | | name = _name |
| | | } |
| | | i++ |
| | | } |
| | | |
| | | let newcard = { |
| | | uuid: Utils.getuuid(), |
| | | type: item.component, |
| | | subtype: item.subtype, |
| | | floor: 1, // 组件的层级 |
| | | isNew: true // 新添加标志,用于初始化 |
| | | } |
| | | |
| | | let targetId = cards.length > 0 ? cards[cards.length - 1].uuid : 0 |
| | | if (target) { |
| | | targetId = target.uuid |
| | | } |
| | | |
| | | const { index: overIndex } = findCard(`${targetId}`) |
| | | let targetIndex = overIndex |
| | | |
| | | targetIndex++ |
| | | |
| | | const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] }) |
| | | |
| | | handleList({...menu, components: _cards}) |
| | | target = null |
| | | } |
| | | }) |
| | | |
| | | return ( |
| | | <div ref={drop} className="ant-row menu-shell-inner"> |
| | | {cards.map(card => ( |
| | | <Card |
| | | id={card.uuid} |
| | | key={card.uuid} |
| | | menu={menu} |
| | | card={card} |
| | | moveCard={moveCard} |
| | | delCard={deleteCard} |
| | | findCard={findCard} |
| | | hasDrop={hasDrop} |
| | | updateConfig={updateConfig} |
| | | doubleClickCard={doubleClickCard} |
| | | /> |
| | | ))} |
| | | {cards.length === 0 ? |
| | | <Empty description="请添加组件" /> : null |
| | | } |
| | | </div> |
| | | ) |
| | | } |
| | | export default Container |
New file |
| | |
| | | .menu-shell-inner { |
| | | min-height: calc(100vh - 150px); |
| | | margin: -8px; |
| | | |
| | | >.ant-col { |
| | | padding: 8px; |
| | | } |
| | | .anticon { |
| | | cursor: unset; |
| | | } |
| | | |
| | | .mk-component-card { |
| | | position: relative; |
| | | .remove-component { |
| | | position: absolute; |
| | | right: 42px; |
| | | top: -16px; |
| | | color: #ff4d4f; |
| | | border-radius: 2px; |
| | | font-size: 16px; |
| | | padding: 5px; |
| | | cursor: pointer; |
| | | opacity: 0; |
| | | transition: opacity 0.2s; |
| | | } |
| | | } |
| | | .mk-component-card:hover { |
| | | .remove-component { |
| | | opacity: 1; |
| | | } |
| | | .model-datasource > .anticon-setting, .model-menu-tabs-setting > .anticon-setting { |
| | | opacity: 1; |
| | | } |
| | | } |
| | | >.ant-empty { |
| | | padding-top: 150px; |
| | | } |
| | | |
| | | .model-datasource > .anticon-setting, .model-menu-tabs-setting > .anticon-setting { |
| | | font-size: 16px; |
| | | padding: 5px; |
| | | position: absolute; |
| | | right: 0px; |
| | | top: -30px; |
| | | opacity: 0; |
| | | cursor: pointer; |
| | | transition: opacity 0.2s; |
| | | } |
| | | } |
| | |
| | | activeKey: 'uname_pwd', |
| | | username: '', |
| | | password: '', |
| | | remember: true, |
| | | delay: null, |
| | | loginWays: [], |
| | | smsId: '', |
| | |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { loginWays } = this.props |
| | | let remember = true |
| | | let _url = window.location.href.split('#')[0] |
| | | |
| | | if (localStorage.getItem(_url + 'remember') === 'false') { |
| | | remember = false |
| | | } |
| | | |
| | | let smsId = '' |
| | | let _loginWays = [] |
| | |
| | | this.setState({ |
| | | smsId: smsId, |
| | | loginWays: _loginWays, |
| | | activeKey: _loginWays[0].type |
| | | activeKey: _loginWays[0].type, |
| | | remember |
| | | }) |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | rememberChange = (e) => { |
| | | let val = e.target.checked |
| | | let _url = window.location.href.split('#')[0] |
| | | |
| | | localStorage.setItem(_url + 'remember', val) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新 |
| | | */ |
| | |
| | | |
| | | render() { |
| | | const { getFieldDecorator } = this.props.form |
| | | const { activeKey, verdisabled, delay, loginWays } = this.state |
| | | const { activeKey, verdisabled, delay, loginWays, remember } = this.state |
| | | |
| | | return ( |
| | | <Form className={`login-form login-form-${loginWays.length}`} id="login-form" onSubmit={this.handleSubmit}> |
| | |
| | | {activeKey === 'uname_pwd' ? <Form.Item className="minline"> |
| | | {getFieldDecorator('remember', { |
| | | valuePropName: 'checked', |
| | | initialValue: true, |
| | | })(<Checkbox>{this.props.dict['login.remember']}</Checkbox>)} |
| | | initialValue: remember, |
| | | })(<Checkbox onChange={this.rememberChange}>{this.props.dict['login.remember']}</Checkbox>)} |
| | | </Form.Item> : null} |
| | | {this.props.langList && this.props.langList.length > 0 ? <Form.Item className="minline right"> |
| | | {getFieldDecorator('lang', { |
| | |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | | |
| | | this.getMenuParam() |
| | | // this.testFunc() |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | |
| | | <Button type="primary" onClick={this.submitConfig} loading={this.state.menuloading}>{dict['mob.save']}</Button> |
| | | </div> |
| | | } style={{ width: '100%' }}> |
| | | {config && config.components ? <MenuShell config={config} handleList={this.updateConfig} deleteCard={this.deleteCard} /> : null} |
| | | {config && config.components ? <MenuShell menu={config} handleList={this.updateConfig} deleteCard={this.deleteCard} /> : null} |
| | | </Card> |
| | | </div> |
| | | </div> |