import React, {Component} from 'react'
|
import PropTypes from 'prop-types'
|
import { is, fromJS } from 'immutable'
|
import { Icon, Modal } from 'antd'
|
|
import Utils from '@/utils/utils.js'
|
import zhCN from '@/locales/zh-CN/model.js'
|
import enUS from '@/locales/en-US/model.js'
|
import { getCardDetailForm } from '@/templates/zshare/formconfig'
|
|
import DragDetail from './dragdetail'
|
import CardDetailForm from './carddetailform'
|
import avatar from '@/assets/img/avatar.png'
|
import './index.scss'
|
|
const { confirm } = Modal
|
|
class LineChart extends Component {
|
static propTpyes = {
|
card: PropTypes.object,
|
config: PropTypes.object,
|
plotchange: PropTypes.func
|
}
|
|
state = {
|
dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
|
modaltype: '',
|
formlist: null,
|
cardwidth: 0,
|
cardheight: 0,
|
cardcell: null // 卡片元素
|
}
|
|
shouldComponentUpdate (nextProps, nextState) {
|
return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
|
}
|
|
UNSAFE_componentWillReceiveProps (nextProps) {
|
if (!is(fromJS(this.props.card), fromJS(nextProps.card))) {
|
setTimeout(() => {
|
if (nextProps.card.extraAction && this.cardRef) {
|
if (this.cardRef.offsetWidth !== this.state.cardwidth || this.cardRef.offsetHeight !== this.state.cardheight) {
|
this.setState({
|
cardwidth: this.cardRef.offsetWidth,
|
cardheight: this.cardRef.offsetHeight
|
})
|
}
|
}
|
}, 200)
|
}
|
}
|
|
plotChange = (values) => {
|
const { card, config } = this.props
|
let _card = {...card, ...values}
|
let _charts = fromJS(config.charts).toJS()
|
|
_charts = _charts.map(item => {
|
if (item.uuid === _card.uuid) {
|
return _card
|
}
|
return item
|
})
|
|
this.props.plotchange({...config, charts: _charts})
|
}
|
|
handleList = (list) => {
|
this.plotChange({details: list})
|
}
|
|
editdetail = (_cell) => {
|
const { config } = this.props
|
if (!_cell) {
|
_cell = {
|
datatype: 'dynamic',
|
elemType: 'detail',
|
width: 100,
|
fontWeight: 'normal',
|
fontSize: 14
|
}
|
}
|
|
let _columns = config.columns.filter(col => ['text', 'number', 'link'].includes(col.type))
|
_columns = _columns.map(col => {
|
return {
|
uuid: col.uuid,
|
value: col.field,
|
text: col.label
|
}
|
})
|
|
if (_columns.filter(col => col.value === _cell.field).length === 0) {
|
_cell.field = ''
|
}
|
|
this.setState({
|
cardcell: _cell,
|
modaltype: 'detail',
|
formlist: getCardDetailForm(_cell, _columns, 'detail')
|
})
|
}
|
|
editHeader = () => {
|
const { config, card } = this.props
|
|
let _columns = config.columns.filter(col => ['text', 'number'].includes(col.type))
|
_columns = _columns.map(col => {
|
return {
|
uuid: col.uuid,
|
value: col.field,
|
text: col.label
|
}
|
})
|
let _actions = config.action.filter(item =>
|
(item.Ot && item.Ot !== 'notRequired' && !['excelIn', 'excelOut'].includes(item.OpenType)) ||
|
item.funcType === 'changeuser'
|
)
|
|
let actionIds = []
|
_actions = _actions.map(item => {
|
actionIds.push(item.uuid)
|
|
return {
|
value: item.uuid,
|
icon: item.icon,
|
text: item.label
|
}
|
})
|
|
let _cell = fromJS(card.header).toJS()
|
if (_columns.filter(col => col.value === _cell.field).length === 0) {
|
_cell.field = ''
|
}
|
if (_cell.actions.length > 0) {
|
_cell.actions = _cell.actions.filter(item => actionIds.includes(item.value))
|
}
|
|
this.setState({
|
cardcell: _cell,
|
modaltype: 'header',
|
formlist: getCardDetailForm(_cell, _columns, 'header', _actions)
|
})
|
}
|
|
editBottom = () => {
|
const { config, card } = this.props
|
|
let _actions = config.action.filter(item =>
|
(item.Ot && item.Ot !== 'notRequired' && !['excelIn', 'excelOut'].includes(item.OpenType)) ||
|
item.funcType === 'changeuser'
|
)
|
|
let actionIds = []
|
_actions = _actions.map(item => {
|
actionIds.push(item.uuid)
|
|
return {
|
value: item.uuid,
|
icon: item.icon,
|
text: item.label
|
}
|
})
|
|
let _cell = fromJS(card.bottom).toJS()
|
|
if (_cell.actions.length > 0) {
|
_cell.actions = _cell.actions.filter(item => actionIds.includes(item.value))
|
}
|
|
this.setState({
|
cardcell: _cell,
|
modaltype: 'bottom',
|
formlist: getCardDetailForm(_cell, [], 'bottom', _actions)
|
})
|
}
|
|
editAvatar = () => {
|
const { config, card } = this.props
|
|
let _columns = []
|
config.columns.forEach(col => {
|
if (['picture'].includes(col.type)) {
|
_columns.push({
|
type: 'picture',
|
uuid: col.uuid,
|
value: col.field,
|
text: col.label
|
})
|
} else if (['text', 'number'].includes(col.type) && col.marks) {
|
let mark = col.marks.filter(_mark => _mark.signType === 'icon' && _mark.icon)[0]
|
if (mark) {
|
_columns.push({
|
type: 'icon',
|
uuid: col.uuid,
|
value: col.field,
|
text: col.label,
|
icon: mark.icon,
|
color: mark.color[1]
|
})
|
}
|
}
|
})
|
|
let _cell = fromJS(card.avatar).toJS()
|
if (_columns.filter(col => col.value === _cell.field && col.type === _cell.type).length === 0) {
|
_cell.field = ''
|
_cell.content = ''
|
}
|
|
this.setState({
|
cardcell: _cell,
|
modaltype: 'avatar',
|
formlist: getCardDetailForm(_cell, _columns, 'avatar', [], card.widthType === 'ratio')
|
})
|
}
|
|
handleSubmit = () => {
|
const { modaltype } = this.state
|
|
this.cardFormRef.handleConfirm().then(res => {
|
if (modaltype === 'detail') {
|
let _details = fromJS(this.props.card.details).toJS()
|
if (!res.uuid) {
|
res.uuid = Utils.getuuid()
|
_details.push(res)
|
} else {
|
_details = _details.map(item => {
|
if (item.uuid === res.uuid) return res
|
return item
|
})
|
}
|
|
this.setState({
|
cardcell: null,
|
modaltype: '',
|
formlist: null
|
})
|
this.plotChange({details: _details})
|
} else if (modaltype === 'header') {
|
this.setState({
|
cardcell: null,
|
modaltype: '',
|
formlist: null
|
})
|
this.plotChange({header: res})
|
} else if (modaltype === 'bottom') {
|
this.setState({
|
cardcell: null,
|
modaltype: '',
|
formlist: null
|
})
|
this.plotChange({bottom: res})
|
} else if (modaltype === 'avatar') {
|
this.setState({
|
cardcell: null,
|
modaltype: '',
|
formlist: null
|
})
|
this.plotChange({avatar: res})
|
}
|
})
|
}
|
|
editModalCancel = () => {
|
this.setState({
|
cardcell: null,
|
modaltype: '',
|
formlist: null
|
})
|
}
|
|
deletedetail = (cell) => {
|
const { card } = this.props
|
const { dict } = this.state
|
let _this = this
|
|
confirm({
|
content: dict['model.confirm'] + dict['model.delete'] + ` - ${cell.content} ?`,
|
okText: dict['model.confirm'],
|
cancelText: dict['model.cancel'],
|
onOk() {
|
let _details = fromJS(card.details).toJS()
|
|
_details = _details.filter(item => item.uuid !== cell.uuid)
|
|
_this.plotChange({details: _details})
|
},
|
onCancel() {}
|
})
|
}
|
|
deleteElem = (type) => {
|
const { dict } = this.state
|
let _this = this
|
|
confirm({
|
content: dict['model.confirm'] + dict['model.delete'] + '?',
|
okText: dict['model.confirm'],
|
cancelText: dict['model.cancel'],
|
onOk() {
|
let _subelement = fromJS(_this.props.card.subelement).toJS()
|
_subelement = _subelement.filter(_type => _type !== type)
|
|
_this.plotChange({subelement: _subelement})
|
},
|
onCancel() {}
|
})
|
}
|
|
componentDidMount() {
|
const { card } = this.props
|
|
if (card.extraAction && this.cardRef) {
|
this.setState({
|
cardwidth: this.cardRef.offsetWidth,
|
cardheight: this.cardRef.offsetHeight
|
})
|
}
|
}
|
|
componentDidUpdate() {
|
const { card } = this.props
|
|
if (card.extraAction && this.cardRef) {
|
if (this.cardRef.offsetWidth !== this.state.cardwidth || this.cardRef.offsetHeight !== this.state.cardheight) {
|
this.setState({
|
cardwidth: this.cardRef.offsetWidth,
|
cardheight: this.cardRef.offsetHeight
|
})
|
}
|
}
|
}
|
|
render() {
|
const { card } = this.props
|
const { dict, modaltype, cardcell, cardwidth, cardheight } = this.state
|
let _width = '100%'
|
if (card.bottom && card.bottom.actions.length > 0) {
|
_width = Math.floor((100 / card.bottom.actions.length) * 10000) / 10000 + '%'
|
}
|
let outclass = card.widthType === 'ratio' ? ' ant-col ant-col-' + card.cardWidth : ''
|
if (card.background) {
|
outclass += ' background ' + card.background
|
}
|
if (card.border === 'hidden') {
|
outclass += ' without-border'
|
} else {
|
outclass += ' ant-card-bordered'
|
}
|
|
let metastyle = {}
|
if (card.subelement.includes('avatar')) {
|
let _cardWidth = card.cardWidth
|
|
// 计算卡片宽度
|
if (card.widthType === 'ratio' && card.over !== 'roll') {
|
let _outWidth = document.body.offsetWidth - 260
|
_cardWidth = Math.floor(_outWidth * card.cardWidth / 24 - 20)
|
}
|
|
if (card.avatar.type === 'picture') {
|
if (card.avatar.widthType === 'ratio') {
|
if (card.avatar.width < 90 && card.avatar.display !== 'block') {
|
metastyle.display = 'flex'
|
}
|
} else {
|
if (card.avatar.width < _cardWidth * 0.9 && card.avatar.display !== 'block') {
|
metastyle.display = 'flex'
|
}
|
}
|
} else {
|
if (card.avatar.size < _cardWidth * 0.9 && card.avatar.display !== 'block') {
|
metastyle.display = 'flex'
|
}
|
}
|
}
|
|
return (
|
<div className="line-card-edit-box mingke-table">
|
{card.title ? <p className="chart-title">{card.title}</p> : null}
|
<div
|
ref={(ref) => this.cardRef = ref}
|
className={'ant-card chart-card ' + outclass}
|
style={card.widthType === 'absolute' ? { width: card.cardWidth } : null}
|
>
|
{card.subelement.includes('header') ?
|
<div className="ant-card-head">
|
<Icon className="edit" title="Edit" type="edit" onClick={this.editHeader} />
|
<Icon className="edit close" title="close" type="close" onClick={() => this.deleteElem('header')} />
|
<div className="ant-card-head-wrapper">
|
<div className="ant-card-head-title">{card.header.content}</div>
|
{card.header.actions && card.header.actions.length > 0 ?
|
<div className="ant-card-extra">
|
<span>
|
{['icon', 'all'].includes(card.header.show) ? <Icon type={card.header.actions[0].icon || 'dash'}/> : null}
|
{['text', 'all'].includes(card.header.show) ? card.header.actions[0].text : null}
|
</span>
|
</div> : null
|
}
|
</div>
|
</div> : null
|
}
|
<div className="ant-card-body">
|
<div className="ant-card-meta" style={metastyle}>
|
<Icon type="plus" onClick={() => this.editdetail()} />
|
{card.subelement.includes('avatar') ?
|
<div className="ant-card-meta-avatar" style={{width: card.avatar.avatarWidth || 32, paddingTop: card.avatar.avatarWidth || 32}}>
|
<Icon className="edit" title="Edit" type="edit" onClick={this.editAvatar} />
|
<Icon className="edit close" title="close" type="close" onClick={() => this.deleteElem('avatar')} />
|
<span className="ant-avatar ant-avatar-circle ant-avatar-image" style={{borderRadius: card.avatar.radius === 'true' ? '50%' : 0}}>
|
{card.avatar.type === 'picture' ? <img src={avatar} alt=""/> : null}
|
{card.avatar.type === 'icon' ? <Icon className={'font ' + card.avatar.color} style={{fontSize: card.avatar.size + 'px'}} type={card.avatar.icon} /> : null}
|
</span>
|
</div> : null
|
}
|
<div className="ant-card-meta-detail" style={metastyle.display ? {flex: 1} : null}>
|
<DragDetail
|
cardObj={card}
|
handleList={this.handleList}
|
handleMenu={this.editdetail}
|
deleteMenu={this.deletedetail}
|
/>
|
</div>
|
</div>
|
</div>
|
{card.subelement.includes('bottom') ?
|
<ul className="ant-card-actions">
|
<Icon className="edit" title="Edit" type="edit" onClick={this.editBottom} />
|
<Icon className="edit close" title="close" type="close" onClick={() => this.deleteElem('bottom')} />
|
{card.bottom.actions.map((item, i) => (<li key={i} style={{width: _width}}>
|
<span>
|
{['icon', 'all'].includes(card.bottom.show) ? <Icon type={item.icon || 'dash'}/> : null}
|
{['text', 'all'].includes(card.bottom.show) ? item.text : null}
|
</span>
|
</li>))}
|
</ul> : null
|
}
|
</div>
|
{card.extraAction ?
|
<div className={'ant-card chart-card chart-card-insert' + outclass} style={{ width: cardwidth, height: cardheight }} >
|
<Icon type="plus" style={cardwidth > cardheight ? {fontSize: cardheight / 2 + 'px', lineHeight: cardheight + 'px'} : {fontSize: cardwidth / 2 + 'px', lineHeight: cardheight + 'px'}} />
|
</div> : null
|
}
|
{/* 显示列编辑 */}
|
<Modal
|
title="编辑"
|
visible={!!modaltype}
|
width={650}
|
maskClosable={false}
|
onOk={this.handleSubmit}
|
onCancel={this.editModalCancel}
|
destroyOnClose
|
>
|
<CardDetailForm
|
dict={dict}
|
card={cardcell}
|
inputSubmit={this.handleSubmit}
|
formlist={this.state.formlist}
|
wrappedComponentRef={(inst) => this.cardFormRef = inst}
|
/>
|
</Modal>
|
</div>
|
)
|
}
|
}
|
|
export default LineChart
|