| | |
| | | precision: 0, |
| | | label: '宽度', |
| | | initVal: card.width || 12, |
| | | tooltip: '每行等分为24份。', |
| | | tooltip: '栅格布局,每行等分为24列。', |
| | | forbid: type !== 'card', |
| | | required: true |
| | | }, |
| | |
| | | |
| | | const doubleClickCard = id => { |
| | | const { card } = findCard(id) |
| | | console.log(card) |
| | | if (card.OpenType === 'pop') { |
| | | handleSubConfig(card) |
| | | } |
| | |
| | | precision: 0, |
| | | label: '宽度', |
| | | initVal: card.width || 12, |
| | | tooltip: '每行等分为24份。', |
| | | tooltip: '栅格布局,每行等分为24列。', |
| | | required: true |
| | | }, |
| | | { |
| | |
| | | const { elements } = this.state |
| | | |
| | | this.verifyRef.handleConfirm().then(res => { |
| | | console.log(res) |
| | | let _elements = elements.map(cell => { |
| | | if (cell.uuid === res.uuid) { |
| | | res.eleType = 'button' |
| | |
| | | } |
| | | |
| | | handleSubConfig = (item) => { |
| | | console.log(item) |
| | | |
| | | } |
| | | |
| | | render() { |
| | |
| | | <Row gutter={24}> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="栅格布局,每行等分24份。"> |
| | | <Tooltip placement="topLeft" title="栅格布局,每行等分为24列。"> |
| | | <Icon type="question-circle" /> |
| | | 卡片宽度 |
| | | </Tooltip> |
| | |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="栅格布局,每行等分24份。"> |
| | | <Tooltip placement="topLeft" title="栅格布局,每行等分为24列。"> |
| | | <Icon type="question-circle" /> |
| | | 宽度 |
| | | </Tooltip> |
| | |
| | | key: 'width', |
| | | label: '宽度', |
| | | initVal: card.width, |
| | | tooltip: '栅格布局,每行等分24份。', |
| | | tooltip: '栅格布局,每行等分为24列。', |
| | | min: 1, |
| | | max: 24, |
| | | decimal: 0, |
| | |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="栅格布局,每行等分24份。"> |
| | | <Tooltip placement="topLeft" title="栅格布局,每行等分为24列。"> |
| | | <Icon type="question-circle" /> |
| | | 宽度 |
| | | </Tooltip> |
| | |
| | | onChange: PropTypes.func |
| | | } |
| | | state = { |
| | | color: this.props.defaultValue || this.props.value, |
| | | color: '', |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { defaultValue, value } = this.props |
| | | let initVal = '' |
| | | |
| | | if (this.props['data-__meta']) { |
| | | initVal = this.props['data-__meta'].initialValue |
| | | } else if (defaultValue) { |
| | | initVal = defaultValue |
| | | } else if (value) { |
| | | initVal = value |
| | | } |
| | | |
| | | this.setState({color: initVal}) |
| | | } |
| | | |
| | | handleChange = (color) => { |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { menuType } = this.props |
| | | const { BID, searchlist, loadingview, viewlost, config, loading, data, triggerTime } = this.state |
| | | |
| | | return ( |
| | |
| | | BID={BID} |
| | | dict={this.state.dict} |
| | | searchlist={searchlist} |
| | | menuType={this.props.menuType} |
| | | menuType={menuType} |
| | | dataManager={this.props.dataManager} |
| | | refreshdata={this.refreshbysearch} |
| | | /> : null |
| | | } |
| | | {config && config.calendar ? <CalendarComponent calendar={config.calendar} loading={loading} data={data} triggerDate={this.triggerDate} changeDate={this.changeDate}/> : null} |
| | | {options.sysType !== 'cloud' ? <Button |
| | | {options.sysType !== 'cloud' && menuType !== 'HS' ? <Button |
| | | icon="copy" |
| | | shape="circle" |
| | | className="common-table-copy" |
| | |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | let _config = fromJS(this.props.config).toJS() |
| | | console.log(_config) |
| | | |
| | | this.setState({ |
| | | config: _config, |
| | |
| | | |
| | | |
| | | render() { |
| | | const { menuType } = this.props |
| | | const { loadingview, viewlost, config } = this.state |
| | | |
| | | return ( |
| | | <div className="custom-page-wrap" id={this.state.ContainerId} style={config ? config.style : null}> |
| | | {loadingview && <Spin size="large" />} |
| | | <Row>{this.getComponents()}</Row> |
| | | {options.sysType !== 'cloud' ? <Button |
| | | {options.sysType !== 'cloud' && menuType !== 'HS' ? <Button |
| | | icon="copy" |
| | | shape="circle" |
| | | className="common-table-copy" |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { menuType } = this.props |
| | | const { setting, loadingview, viewlost, config, triggerBtn, userConfig, tabActive, tabgroups, treeNodes, treedata, expandedKeys, selectedKeys } = this.state |
| | | |
| | | return ( |
| | |
| | | )} |
| | | </Col> |
| | | </Row> : null} |
| | | |
| | | {options.sysType !== 'cloud' ? <Button |
| | | {options.sysType !== 'cloud' && menuType !== 'HS' ? <Button |
| | | icon="copy" |
| | | shape="circle" |
| | | className="tree-page-copy" |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | // import { fromJS } from 'immutable' |
| | | import { Col, Row } from 'antd' |
| | | |
| | | import './index.scss' |
| | | |
| | | |
| | | class CheckCard extends Component { |
| | | static propTpyes = { |
| | | multiple: PropTypes.bool, // 是否可多选 |
| | | width: PropTypes.number, // 宽度 |
| | | display: PropTypes.string, // 显示为:text(文本)、picture(图片) |
| | | fields: PropTypes.array, // 字段集 |
| | | options: PropTypes.array, // 数据列表 |
| | | onChange: PropTypes.func, // 数据切换 |
| | | } |
| | | |
| | | state = { |
| | | selectKeys: null, // 选中数据id |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | |
| | | } |
| | | |
| | | getCards = () => { |
| | | const { display, options, fields } = this.props |
| | | if (display === 'picture') { |
| | | return options.map(item => { |
| | | <Col> |
| | | <div> |
| | | {fields.map(col => { |
| | | return <span></span> |
| | | })} |
| | | </div> |
| | | </Col> |
| | | }) |
| | | } else { |
| | | return <Col></Col> |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | |
| | | return ( |
| | | <Row gutter={24}>{this.getCards()}</Row> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default CheckCard |
New file |
| | |
| | | .check-card-edit-box { |
| | | |
| | | } |
| | |
| | | import Utils from '@/utils/utils.js' |
| | | import './index.scss' |
| | | |
| | | // let Url = '/Upload' |
| | | // if (process.env.NODE_ENV === 'production') { |
| | | // Url = document.location.origin + '/' + window.GLOB.service + 'zh-CN/Home/Upload' |
| | | // } |
| | | |
| | | let service = '' |
| | | if (process.env.NODE_ENV === 'production') { |
| | | service = document.location.origin + '/' + window.GLOB.service |
| | |
| | | |
| | | class FileUpload extends Component { |
| | | static propTpyes = { |
| | | value: PropTypes.array, // 按钮信息、表单列表 |
| | | value: PropTypes.array, // 文件数组 |
| | | maxFile: PropTypes.any, // 最大文件数 |
| | | fileType: PropTypes.string // 文件显示类型 |
| | | } |
| | |
| | | duration: 5 |
| | | }) |
| | | } |
| | | |
| | | // getExtraData = () => { |
| | | // return { |
| | | // RootPath: 'Content/images/upload/' |
| | | // } |
| | | // } |
| | | |
| | | shardupload = (params) => { |
| | | let param = params.chunks.shift() |
| | |
| | | chunkFileReader.readAsArrayBuffer(blobSlice.call(file, start, end)) |
| | | } |
| | | |
| | | // loadNext() |
| | | return false |
| | | } |
| | | |
| | |
| | | multiple: false, |
| | | onChange: this.onChange, |
| | | onRemove: this.onRemove, |
| | | // data: this.getExtraData, |
| | | beforeUpload: this.beforeUpload, |
| | | className: uploadable |
| | | } |
| | | |
| | | return ( |
| | | <Upload {...props}> |
| | | <Button> |
| | | {fileType !== 'picture-card' ? <Button> |
| | | <Icon type="upload" /> 点击上传 |
| | | </Button> |
| | | </Button> : null} |
| | | {fileType === 'picture-card' ? <span style={{whiteSpace: 'nowrap'}}> |
| | | <Icon type="upload" /> 点击上传 |
| | | </span> : null} |
| | | {showprogress ? <Progress percent={percent} size="small" /> : null} |
| | | </Upload> |
| | | ) |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | // import { fromJS } from 'immutable' |
| | | import { Col, Row } from 'antd' |
| | | |
| | | import './index.scss' |
| | | |
| | | |
| | | class CheckCard extends Component { |
| | | static propTpyes = { |
| | | multiple: PropTypes.bool, // 是否可多选 |
| | | ratio: PropTypes.string, // 图片比例 |
| | | width: PropTypes.number, // 宽度 |
| | | display: PropTypes.string, // 显示为:text(文本)、picture(图片) |
| | | fields: PropTypes.array, // 字段集 |
| | | options: PropTypes.array, // 数据列表 |
| | | onChange: PropTypes.func, // 数据切换 |
| | | } |
| | | |
| | | state = { |
| | | selectKeys: null, // 选中数据id |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | |
| | | } |
| | | |
| | | getCards = () => { |
| | | const { display, width, options, fields, ratio } = this.props |
| | | |
| | | let paddingTop = '100%' |
| | | if (ratio === '4:3') { |
| | | paddingTop = '75%' |
| | | } else if (ratio === '3:2') { |
| | | paddingTop = '66.7%' |
| | | } else if (ratio === '16:9') { |
| | | paddingTop = '56.25%' |
| | | } |
| | | |
| | | if (display !== 'picture') { |
| | | return options.map(item => { |
| | | return <Col span={width} key={item.key}> |
| | | <div className="card-cell"> |
| | | {fields.map(col => { |
| | | return <span key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span> |
| | | })} |
| | | </div> |
| | | </Col> |
| | | }) |
| | | } else { |
| | | return options.map(item => { |
| | | return <Col span={width} key={item.key}> |
| | | <div className="card-pic-cell" style={{paddingTop, backgroundImage: `url(${item.$url})`}}> |
| | | </div> |
| | | </Col> |
| | | }) |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | |
| | | return ( |
| | | <div className="check-card-edit-box" style={{marginTop: '10px'}}> |
| | | <Row gutter={12}>{this.getCards()}</Row> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default CheckCard |
New file |
| | |
| | | .check-card-edit-box { |
| | | .card-cell { |
| | | border: 1px solid #bcbcbc; |
| | | border-radius: 4px; |
| | | padding: 6px; |
| | | span { |
| | | display: block; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | } |
| | | .card-pic-cell { |
| | | border: 1px solid #bcbcbc; |
| | | border-radius: 4px; |
| | | background-size: cover; |
| | | background-position: center; |
| | | } |
| | | } |
| | |
| | | import { useDrag, useDrop } from 'react-dnd' |
| | | import { Icon, Select, DatePicker, Input, InputNumber, Button, Popover, Switch, Radio, Checkbox } from 'antd' |
| | | import moment from 'moment' |
| | | |
| | | import CheckCard from '../checkCard' |
| | | import './index.scss' |
| | | |
| | | const { MonthPicker } = DatePicker |
| | | const { TextArea } = Input |
| | | |
| | | const Card = ({ id, card, cols, moveCard, findCard, editCard, closeCard, copyCard, hasDrop }) => { |
| | | const Card = ({ id, card, cols, moveCard, findCard, editCard, closeCard, copyCard }) => { |
| | | const originalIndex = findCard(id).index |
| | | const [{ isDragging }, drag] = useDrag({ |
| | | item: { type: 'form', id, originalIndex }, |
| | |
| | | const [, drop] = useDrop({ |
| | | accept: 'form', |
| | | canDrop: () => true, |
| | | drop: ({ id: draggedId, originalIndex }) => { |
| | | drop: (item) => { |
| | | const { id: draggedId, originalIndex } = item |
| | | |
| | | if (originalIndex === undefined) { |
| | | hasDrop(card) |
| | | item.dropTargetId = id |
| | | } else if (draggedId) { |
| | | if (draggedId !== id) { |
| | | const { index: overIndex } = findCard(id) |
| | |
| | | } |
| | | let labelCol = 'ant-col-sm-8' |
| | | let wrapCol = 'ant-col-sm-16' |
| | | if (card.type === 'textarea') { |
| | | let isEntireLine = false |
| | | |
| | | if (card.entireLine === 'true' || ['textarea', 'hint', 'checkcard'].includes(card.type)) { |
| | | isEntireLine = true |
| | | } |
| | | |
| | | if (isEntireLine) { |
| | | if (cols === '2') { |
| | | labelCol = 'ant-col-sm-4' |
| | | wrapCol = 'ant-col-sm-20' |
| | |
| | | <Checkbox value="C">C</Checkbox> |
| | | <Checkbox value="D">D</Checkbox> |
| | | </Checkbox.Group>) |
| | | } else if (card.type === 'hint') { |
| | | formItem = <div style={{marginTop: '10px', color: 'rgba(0, 0, 0, 0.85)'}}>{card.message}</div> |
| | | } else if (card.type === 'checkcard') { |
| | | formItem = <CheckCard width={card.width} ratio={card.ratio} display={card.display} fields={card.fields} options={card.options} /> |
| | | } |
| | | |
| | | return ( |
| | |
| | | <div ref={node => drag(drop(node))}> |
| | | {<div className="ant-row ant-form-item"> |
| | | <div className={'ant-col ant-form-item-label ant-col-xs-24 ' + labelCol}> |
| | | <label title={card.label}>{card.label}</label> |
| | | {card.label ? <label className={card.required === 'true' ? 'required' : ''}>{card.tooltip ? |
| | | <Icon type="question-circle" /> : null} |
| | | {card.label}</label> : null} |
| | | </div> |
| | | <div className={'ant-col ant-form-item-control-wrapper ant-col-xs-24 ' + wrapCol}> |
| | | {formItem} |
| | |
| | | import './index.scss' |
| | | |
| | | const Container = ({list, group, setting, placeholder, handleList, handleForm, closeForm }) => { |
| | | let target = null |
| | | |
| | | const [cards, setCards] = useState(list) |
| | | const moveCard = (id, atIndex) => { |
| | | const { card, index } = findCard(id) |
| | |
| | | |
| | | const editCard = id => { |
| | | const { card } = findCard(id) |
| | | handleForm(card, 'edit') |
| | | handleForm(card) |
| | | } |
| | | |
| | | const closeCard = id => { |
| | |
| | | } |
| | | |
| | | const copyCard = id => { |
| | | const { card } = findCard(id) |
| | | handleForm(card, 'copy') |
| | | } |
| | | |
| | | const hasDrop = (item) => { |
| | | target = item |
| | | const { card, index: overIndex } = findCard(id) |
| | | |
| | | let _card = fromJS(card).toJS() |
| | | _card.uuid = Utils.getuuid() |
| | | _card.focus = true |
| | | |
| | | // 复制到剪切板 |
| | | let oInput = document.createElement('input') |
| | | let val = JSON.parse(JSON.stringify(_card)) |
| | | val.copyType = 'form' |
| | | |
| | | oInput.value = window.btoa(window.encodeURIComponent(JSON.stringify(val))) |
| | | document.body.appendChild(oInput) |
| | | oInput.select() |
| | | document.execCommand('Copy') |
| | | oInput.className = 'oInput' |
| | | oInput.style.display = 'none' |
| | | document.body.removeChild(oInput) |
| | | |
| | | const _cards = update(cards, { $splice: [[overIndex + 1, 0, _card]] }) |
| | | |
| | | setCards(_cards) |
| | | |
| | | if (!group) { |
| | | handleList(_cards, null, null, _card) |
| | | } else { |
| | | handleList(_cards, group, null, _card) |
| | | } |
| | | } |
| | | |
| | | const [, drop] = useDrop({ |
| | |
| | | newcard.required = 'true' |
| | | newcard.focus = true |
| | | |
| | | let targetId = cards.length > 0 ? cards[cards.length - 1].uuid : 0 |
| | | if (target) { |
| | | targetId = target.uuid |
| | | let targetId = '0' |
| | | |
| | | if (item.dropTargetId) { |
| | | targetId = item.dropTargetId |
| | | } else if (cards.length > 0) { |
| | | targetId = cards[cards.length - 1].uuid |
| | | } |
| | | |
| | | const { index: overIndex } = findCard(`${targetId}`) |
| | | let targetIndex = overIndex |
| | | const { index: overIndex } = findCard(`${targetId}`) // cards为空时 overIndex 为 -1 |
| | | const _cards = update(cards, { $splice: [[overIndex + 1, 0, newcard]] }) |
| | | |
| | | targetIndex++ |
| | | |
| | | const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] }) |
| | | setCards(_cards) |
| | | |
| | | if (!group) { |
| | |
| | | } else { |
| | | handleList(_cards, group, null, newcard) |
| | | } |
| | | |
| | | target = null |
| | | } |
| | | }) |
| | | |
| | |
| | | |
| | | return ( |
| | | <div ref={drop} className="ant-row modal-fields-row"> |
| | | {cards.map(card => ( |
| | | <Col key={card.uuid} className={card.type === 'textarea' ? 'textarea' + setting.cols : ''} span={card.type !== 'textarea' ? _cols : 24}> |
| | | {cards.map(card => { |
| | | let isEntireLine = false |
| | | |
| | | if (card.entireLine === 'true' || ['textarea', 'hint', 'checkcard'].includes(card.type)) { |
| | | isEntireLine = true |
| | | } |
| | | |
| | | return <Col key={card.uuid} className={isEntireLine ? 'textarea' + setting.cols : ''} span={isEntireLine ? 24 : _cols}> |
| | | <Card |
| | | id={card.uuid} |
| | | cols={setting.cols} |
| | |
| | | closeCard={closeCard} |
| | | copyCard={copyCard} |
| | | findCard={findCard} |
| | | hasDrop={hasDrop} |
| | | /> |
| | | </Col> |
| | | ))} |
| | | })} |
| | | {cards.length === 0 && |
| | | <div className="modal-drawarea-placeholder"> |
| | | {placeholder} |
| | |
| | | dict: CommonDict, // 字典 |
| | | config: null, // 页面配置,包括模板类型、模态框设置、添加表名、表单列表 |
| | | visible: false, // 表单编辑模态框,显示控制 |
| | | modalType: null, // 表单编辑类型,编辑或复制 |
| | | tableVisible: false, // 数据表字段列表模态框,显示控制 |
| | | tableColumns: [], // 表格字段名列表 |
| | | fields: null, // 表单,可选字段(去重后) |
| | |
| | | * 2、保存编辑项-card |
| | | * 3、设置编辑参数项-formlist |
| | | */ |
| | | handleForm = (_card, type) => { |
| | | handleForm = (_card) => { |
| | | const {menu, tabConfig, subTabConfig} = this.props |
| | | let card = JSON.parse(JSON.stringify(_card)) |
| | | |
| | | if (type === 'copy') { |
| | | card.originUuid = card.uuid |
| | | card.uuid = Utils.getuuid() |
| | | card.focus = true |
| | | |
| | | // 复制到剪切板 |
| | | let oInput = document.createElement('input') |
| | | let val = JSON.parse(JSON.stringify(card)) |
| | | val.copyType = 'form' |
| | | val.uuid = Utils.getuuid() |
| | | |
| | | delete val.originUuid |
| | | |
| | | oInput.value = window.btoa(window.encodeURIComponent(JSON.stringify(val))) |
| | | document.body.appendChild(oInput) |
| | | oInput.select() |
| | | document.execCommand('Copy') |
| | | oInput.className = 'oInput' |
| | | oInput.style.display = 'none' |
| | | document.body.removeChild(oInput) |
| | | } |
| | | |
| | | const { config } = this.state |
| | | let _inputfields = [] |
| | | let _linkableFields = [] |
| | |
| | | |
| | | this.setState({ |
| | | visible: true, |
| | | modalType: type, |
| | | card: card, |
| | | formlist: getModalForm(card, _inputfields, _linkableFields, _linksupFields, !!this.props.editTab, roleList) |
| | | }) |
| | |
| | | * 3、通过loading刷新 |
| | | */ |
| | | handleSubmit = () => { |
| | | const { card, modalType } = this.state |
| | | |
| | | this.formRef.handleConfirm().then(res => { |
| | | let _config = JSON.parse(JSON.stringify(this.state.config)) |
| | | let fieldrepet = false // 字段重复 |
| | | let labelrepet = false // 提示文字重复 |
| | | |
| | | if (modalType === 'copy' && card.originUuid) { |
| | | if (_config.groups.length > 0) { |
| | | _config.groups = _config.groups.map(group => { |
| | | let _index = null |
| | | group.sublist.forEach((item, index) => { |
| | | if (item.uuid === card.originUuid) { |
| | | _index = index |
| | | } |
| | | |
| | | if (item.uuid !== res.uuid && item.field === res.field) { |
| | | fieldrepet = true |
| | | } else if (item.uuid !== res.uuid && item.label === res.label) { |
| | | labelrepet = true |
| | | } |
| | | }) |
| | | |
| | | if (_index !== null) { |
| | | group.sublist.splice(_index + 1, 0, res) |
| | | } |
| | | |
| | | return group |
| | | }) |
| | | } else { |
| | | let _index = null |
| | | _config.fields.forEach((item, index) => { |
| | | if (item.uuid === card.originUuid) { |
| | | _index = index |
| | | } |
| | | |
| | | if (item.uuid !== res.uuid && item.field === res.field) { |
| | | fieldrepet = true |
| | | } else if (item.uuid !== res.uuid && item.label === res.label) { |
| | | labelrepet = true |
| | | } |
| | | }) |
| | | |
| | | _config.fields.splice(_index + 1, 0, res) |
| | | } |
| | | } else { |
| | | if (_config.groups.length > 0) { |
| | | _config.groups.forEach(group => { |
| | | group.sublist = group.sublist.map(item => { |
| | | if (item.uuid !== res.uuid && item.field === res.field) { |
| | | fieldrepet = true |
| | | } else if (item.uuid !== res.uuid && item.label === res.label) { |
| | | labelrepet = true |
| | | } |
| | | |
| | | if (item.uuid === res.uuid) { |
| | | return res |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | }) |
| | | } else { |
| | | _config.fields = _config.fields.map(item => { |
| | | if (_config.groups.length > 0) { |
| | | _config.groups.forEach(group => { |
| | | group.sublist = group.sublist.map(item => { |
| | | if (item.uuid !== res.uuid && item.field === res.field) { |
| | | fieldrepet = true |
| | | } else if (item.uuid !== res.uuid && item.label === res.label) { |
| | |
| | | return item |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | } else { |
| | | _config.fields = _config.fields.map(item => { |
| | | if (item.uuid !== res.uuid && item.field === res.field) { |
| | | fieldrepet = true |
| | | } else if (item.uuid !== res.uuid && item.label === res.label) { |
| | | labelrepet = true |
| | | } |
| | | |
| | | if (item.uuid === res.uuid) { |
| | | return res |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (fieldrepet) { |
| | |
| | | this.setState({ |
| | | sqlVerifing: false, |
| | | config: _config, |
| | | modalType: null, |
| | | card: null, |
| | | visible: false |
| | | }) |
| | |
| | | } else { |
| | | this.setState({ |
| | | config: _config, |
| | | modalType: null, |
| | | card: null, |
| | | visible: false |
| | | }) |
| | |
| | | </div> |
| | | </DndProvider> |
| | | <Modal |
| | | title={this.state.modalType !== 'copy' ? this.state.dict['model.edit'] : this.state.dict['header.modal.form.copy']} |
| | | title={this.state.dict['model.edit']} |
| | | visible={this.state.visible} |
| | | width={800} |
| | | width={850} |
| | | maskClosable={false} |
| | | onCancel={this.editModalCancel} |
| | | onOk={this.handleSubmit} |
| | | confirmLoading={this.state.sqlVerifing} |
| | |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | label.required::before { |
| | | display: inline-block; |
| | | margin-right: 4px; |
| | | color: #f5222d; |
| | | font-size: 14px; |
| | | font-family: SimSun, sans-serif; |
| | | line-height: 1; |
| | | content: '*'; |
| | | } |
| | | .anticon-question-circle { |
| | | color: #c49f47; |
| | | margin-right: 3px; |
| | | line-height: 40px; |
| | | } |
| | | } |
| | | .ant-form-item-control-wrapper { |
| | | .ant-select { |
| | |
| | | }, |
| | | { |
| | | type: 'form', |
| | | label: '提示', |
| | | subType: 'hint', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'form', |
| | | label: CommonDict['model.form.color'], |
| | | subType: 'color', |
| | | url: '' |
| | |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title={'每行分为24份,树形比例可设置为2-12(最大50%)'}> |
| | | <Tooltip placement="topLeft" title={'栅格布局,每行等分为24列,树形比例可设置为2-12(最大50%)'}> |
| | | <Icon type="question-circle" /> |
| | | 宽度 |
| | | </Tooltip> |
| | |
| | | type: 'radio', |
| | | key: 'TryType', |
| | | label: '事务', |
| | | initval: 'N', |
| | | initval: 'Y', |
| | | required: true, |
| | | options: [{ |
| | | value: 'Y', |
| | |
| | | }).then(res => { |
| | | if (res === false) return res |
| | | |
| | | if (window.GLOB.mainSystemApi) { |
| | | _mainParam.rduri = window.GLOB.mainSystemApi |
| | | |
| | | return Api.getLocalConfig(_mainParam) |
| | | } |
| | | return 'success' |
| | | return Api.getCloudConfig(_mainParam) |
| | | }).then(res => { |
| | | if (res === false || res === 'success') return res |
| | | if (res === false) return res |
| | | |
| | | if (!res.status) { |
| | | notification.warning({ |
| | |
| | | min: 2, |
| | | max: 12, |
| | | label: '宽度', |
| | | tooltip: '每行分为24份,树形比例可设置为2-12(最大50%)', |
| | | tooltip: '栅格布局,每行等分为24列,树形比例可设置为2-12(最大50%)', |
| | | initVal: setting.width || 5, |
| | | required: true |
| | | }, |
| | |
| | | min: 1, |
| | | max: 24, |
| | | label: Formdict['header.form.ratio'], |
| | | tooltip: '每行分为24份,比例可设置为1-24', |
| | | tooltip: '栅格布局,每行等分为24列。', |
| | | initVal: card.ratio, |
| | | required: false |
| | | }, |
| | |
| | | max: 24, |
| | | decimal: 0, |
| | | label: '图表宽度', |
| | | tooltip: '每行等分为24列,24即为100%。', |
| | | tooltip: '栅格布局,每行等分为24列。', |
| | | initVal: card.width || 24, |
| | | required: true |
| | | }, |
| | |
| | | max: card.widthType === 'absolute' ? 1000 : 24, |
| | | decimal: 0, |
| | | label: '卡片宽度', |
| | | tooltip: '类型为比例时,范围1-24,24即为100%;类型为绝对值,范围50-1000。', |
| | | tooltip: '类型为比例时,栅格布局,每行等分为24列;类型为绝对值,范围50-1000。', |
| | | initVal: card.cardWidth || 6, |
| | | hidden: true, |
| | | required: true |
| | |
| | | }) |
| | | } |
| | | |
| | | if (card.type === 'textarea' || card.type === 'fileupload' || card.type === 'multiselect') { |
| | | if (card.type === 'textarea' || card.type === 'fileupload' || card.type === 'multiselect' || card.type === 'checkbox') { |
| | | _fieldlength = 512 |
| | | } |
| | | |
| | |
| | | value: 'textarea', |
| | | text: Formdict['model.form.textarea'] |
| | | }, { |
| | | value: 'hint', |
| | | text: '提示' |
| | | }, { |
| | | value: 'color', |
| | | text: Formdict['model.form.color'] |
| | | }, { |
| | |
| | | tooltip: '下拉多选与多选框,添加多个初始值请使用“,”号分隔。', |
| | | initVal: card.initval || '', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'textarea', |
| | | key: 'message', |
| | | label: '提示信息', |
| | | initVal: card.message || '', |
| | | required: true, |
| | | readonly: false |
| | | }, |
| | | { |
| | | type: 'text', |
| | |
| | | }] |
| | | }, |
| | | { |
| | | type: 'number', |
| | | key: 'width', |
| | | label: '卡片宽度', |
| | | initVal: card.width || 4, |
| | | tooltip: '栅格布局,每行等分为24列。', |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'cardValField', |
| | | label: Formdict['header.form.valueField'], |
| | | initVal: card.cardValField || 'Value', |
| | | required: true, |
| | | readonly: false |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'urlField', |
| | | label: '地址字段', |
| | | initVal: card.urlField || '', |
| | | required: true, |
| | | readonly: false |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'ratio', |
| | | label: '图片比例', |
| | | initVal: card.ratio || '1:1', |
| | | required: true, |
| | | options: [{ |
| | | value: '1:1', |
| | | text: '1:1' |
| | | }, { |
| | | value: '3:2', |
| | | text: '3:2' |
| | | }, { |
| | | value: '4:3', |
| | | text: '4:3' |
| | | }, { |
| | | value: '16:9', |
| | | text: '16:9' |
| | | }] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'setAll', |
| | | label: Formdict['header.form.setAll'], |
| | |
| | | }] |
| | | }, |
| | | { |
| | | type: 'textarea', |
| | | key: 'dataSource', |
| | | label: Formdict['header.form.datasource'], |
| | | initVal: card.dataSource || '', |
| | | type: 'fields', |
| | | key: 'fields', |
| | | label: '字段集', |
| | | initVal: card.fields || [], |
| | | required: true, |
| | | readonly: false |
| | | }, |
| | | { |
| | | type: 'options', |
| | | key: 'options', |
| | | label: '', |
| | | label: '选项', |
| | | initVal: card.options || [], |
| | | required: true, |
| | | readonly: false |
| | | }, |
| | | { |
| | | type: 'codemirror', |
| | | key: 'dataSource', |
| | | label: Formdict['header.form.datasource'], |
| | | initVal: card.dataSource || '', |
| | | required: true, |
| | | readonly: false |
| | | }, |
| | |
| | | }, { |
| | | value: 'desc', |
| | | text: Formdict['header.form.desc'] |
| | | }] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'multiple', |
| | | label: '可多选', |
| | | initVal: card.multiple || 'false', |
| | | required: true, |
| | | options: [{ |
| | | value: 'true', |
| | | text: '是' |
| | | }, { |
| | | value: 'false', |
| | | text: '否' |
| | | }] |
| | | }, |
| | | { |
| | |
| | | value: 'letter&number', |
| | | text: Formdict['header.form.letter&number'] |
| | | }] |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'supField', |
| | | label: '上级表单', |
| | | tooltip: '上级表单为下拉选择或联动菜单,设置上级表单后,该表单受控于上级菜单,注:受控关系在该表单隐藏时失效。', |
| | | initVal: card.supField || '', |
| | | required: false, |
| | | readonly: false, |
| | | options: linksupFields |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'supvalue', |
| | | label: '显示值', |
| | | tooltip: '选择上级表单后,填写显示值,只有上级表单值与显示值相同时,该表单才会显示,注:多个值用逗号分隔。', |
| | | initVal: card.supvalue || '', |
| | | required: true, |
| | | readonly: false |
| | | }, |
| | | { |
| | | type: 'select', |
| | |
| | | { |
| | | type: 'radio', |
| | | key: 'writein', |
| | | label: '写入', |
| | | label: '执行运算', |
| | | tooltip: '表单提交时,是否将该字段值写入默认sql语句中。', |
| | | initVal: card.writein || 'true', |
| | | options: [{ |
| | |
| | | }] |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'supField', |
| | | label: '上级表单', |
| | | tooltip: '上级表单为下拉选择、联动菜单、单选框及多选框,添加后该表单显示及隐藏将受上级表单控制,注:受控关系在该表单隐藏时失效。', |
| | | initVal: card.supField || '', |
| | | required: false, |
| | | readonly: false, |
| | | options: linksupFields |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'supvalue', |
| | | label: '显示值', |
| | | tooltip: '请填写显示值,只有上级表单值与显示值相同时,该表单才会显示,注:多个值用逗号分隔。', |
| | | initVal: card.supvalue || '', |
| | | required: true, |
| | | readonly: false |
| | | }, |
| | | { |
| | | type: 'multiselect', |
| | | key: 'linkSubField', |
| | | label: Formdict['model.form.linkform'], |
| | | tooltip: '在切换选项时会把信息自动填入关联的表单(文本或数字表单)中。', |
| | | initVal: card.linkSubField || [], |
| | | options: inputfields |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'tooltip', |
| | | label: '表单注释', |
| | | tooltip: '鼠标悬浮于提示文字上方时,显示注释。', |
| | | initVal: card.tooltip || '', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'multiselect', |
| | | key: 'blacklist', |
| | | label: Formdict['header.form.blacklist'], |
New file |
| | |
| | | import React, { Component } from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Table, Input, Popconfirm, Form, Icon, notification } from 'antd' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import FileUpload from '@/tabviews/zshare/fileupload' |
| | | import './index.scss' |
| | | |
| | | const EditableContext = React.createContext() |
| | | |
| | | class EditableCell extends Component { |
| | | getInput = (form) => { |
| | | const { inputType } = this.props |
| | | if (inputType === 'file') { |
| | | return <FileUpload maxFile={1} fileType="picture-card"/> |
| | | } else { |
| | | return <Input onPressEnter={() => this.getValue(form)} /> |
| | | } |
| | | } |
| | | |
| | | getValue = (form) => { |
| | | const { record } = this.props |
| | | form.validateFields((error, row) => { |
| | | if (error) { |
| | | return |
| | | } |
| | | |
| | | if (row.$url && Array.isArray(row.$url)) { |
| | | if (!row.$url[0]) { |
| | | row.$url = '' |
| | | } else if (row.$url[0].origin) { |
| | | row.$url = row.$url[0].url || '' |
| | | } else if (!row.$url[0].origin && row.$url[0].status === 'done' && row.$url[0].response) { |
| | | row.$url = row.$url[0].response |
| | | } |
| | | } |
| | | this.props.onSave({...record, ...row}) |
| | | }) |
| | | } |
| | | |
| | | renderCell = (form) => { |
| | | const { getFieldDecorator } = form |
| | | const { |
| | | editing, |
| | | dataIndex, |
| | | title, |
| | | record, |
| | | inputType, |
| | | index, |
| | | children, |
| | | onSave, |
| | | ...restProps |
| | | } = this.props; |
| | | |
| | | let _val = '' |
| | | |
| | | if (record && dataIndex) { |
| | | _val = record[dataIndex] |
| | | } |
| | | |
| | | if (dataIndex === '$url' && _val) { |
| | | _val = [{ |
| | | uid: `10086`, |
| | | name: _val.slice(_val.lastIndexOf('/') + 1), |
| | | status: 'done', |
| | | url: _val, |
| | | origin: true |
| | | }] |
| | | } else if (dataIndex === '$url') { |
| | | _val = [] |
| | | } |
| | | |
| | | return ( |
| | | <td {...restProps}> |
| | | {editing ? ( |
| | | <Form.Item style={{ margin: 0 }}> |
| | | {getFieldDecorator(dataIndex, { |
| | | rules: [ |
| | | { |
| | | required: dataIndex === '$value', |
| | | message: `Please Input ${title}!`, |
| | | }, |
| | | ], |
| | | initialValue: _val, |
| | | })(this.getInput(form))} |
| | | </Form.Item> |
| | | ) : ( |
| | | children |
| | | )} |
| | | </td> |
| | | ) |
| | | } |
| | | |
| | | render() { |
| | | return <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer> |
| | | } |
| | | } |
| | | |
| | | class EdiDataTable extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | type: PropTypes.object, // 数据类型,文本、图片 |
| | | fields: PropTypes.array, // 字段集 |
| | | onChange: PropTypes.func // 数据变化 |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | let data = this.props['data-__meta'].initialValue |
| | | |
| | | this.setState({ |
| | | data: data, |
| | | columns: this.getCloumns() |
| | | }) |
| | | } |
| | | |
| | | state = { |
| | | data: [], |
| | | editingKey: '', |
| | | columns: [] |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | if (!is(fromJS(this.props.fields), fromJS(nextProps.fields)) || !is(fromJS(this.props.type), fromJS(nextProps.type))) { |
| | | this.setState({editingKey: ''}, () => { |
| | | this.setState({ |
| | | columns: this.getCloumns() |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | getCloumns = () => { |
| | | const { type, fields } = this.props |
| | | let columns = [] |
| | | |
| | | if (type === 'picture') { |
| | | columns.push({ |
| | | title: 'url', |
| | | dataIndex: '$url', |
| | | inputType: 'file', |
| | | width: '40%', |
| | | editable: true, |
| | | render: (text) => { |
| | | if (!text) return '' |
| | | return <span style={{display: 'block', width: '70px', height: '70px'}}><img style={{width: '100%', height: '100%'}} src={text} alt="" /></span> |
| | | } |
| | | }) |
| | | } else { |
| | | columns = fields.map(item => ({ |
| | | title: item.field, |
| | | dataIndex: item.field, |
| | | editable: true, |
| | | })) |
| | | } |
| | | |
| | | columns.unshift({ |
| | | title: 'Value', |
| | | dataIndex: '$value', |
| | | editable: true, |
| | | }) |
| | | |
| | | columns.push({ |
| | | title: 'operation', |
| | | dataIndex: 'operation', |
| | | width: '18%', |
| | | render: (text, record) => { |
| | | const { editingKey } = this.state |
| | | const editable = this.isEditing(record) |
| | | return editable ? ( |
| | | <span> |
| | | <EditableContext.Consumer> |
| | | {form => ( |
| | | <span onClick={() => this.save(form, record.key)} style={{ marginRight: 8 , color: '#1890ff', cursor: 'pointer'}}> |
| | | 保存 |
| | | </span> |
| | | )} |
| | | </EditableContext.Consumer> |
| | | <span style={{ color: '#1890ff', cursor: 'pointer'}} onClick={() => this.cancel(record.key)}>取消</span> |
| | | </span> |
| | | ) : ( |
| | | <div className={'operation-btn' + (editingKey !== '' ? ' disabled' : '')}> |
| | | <span className="primary" onClick={() => {editingKey === '' && this.edit(record.key)}}><Icon type="edit" /></span> |
| | | <span className="primary" onClick={() => {editingKey === '' && this.handleUpDown(record.key, 'up')}}><Icon type="arrow-up" /></span> |
| | | <span className="danger" onClick={() => {editingKey === '' && this.handleUpDown(record.key, 'down')}}><Icon type="arrow-down" /></span> |
| | | {editingKey === '' ? <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | | title={this.props.dict['model.query.delete']} |
| | | onConfirm={() => this.handleDelete(record.key) |
| | | }> |
| | | <span className="danger"><Icon type="delete" /></span> |
| | | </Popconfirm> : null} |
| | | {editingKey !== '' ? <span className="danger"><Icon type="delete" /></span> : null} |
| | | </div> |
| | | ) |
| | | } |
| | | }) |
| | | |
| | | return columns |
| | | } |
| | | |
| | | isEditing = record => record.key === this.state.editingKey |
| | | |
| | | cancel = () => { |
| | | this.setState({ editingKey: '' }) |
| | | } |
| | | |
| | | onSave = (record) => { |
| | | const newData = [...this.state.data] |
| | | const index = newData.findIndex(item => record.key === item.key) |
| | | if (index > -1) { |
| | | newData.splice(index, 1, record) |
| | | this.setState({ data: newData, editingKey: '' }, () => { |
| | | this.props.onChange(newData) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | handleDelete = (key) => { |
| | | const { data } = this.state |
| | | let _data = data.filter(item => key !== item.key) |
| | | |
| | | this.setState({ |
| | | data: _data |
| | | }, () => { |
| | | this.props.onChange(_data) |
| | | }) |
| | | } |
| | | |
| | | handleUpDown = (key, direction) => { |
| | | let _data = fromJS(this.state.data).toJS() |
| | | const index = _data.findIndex(item => key === item.key) |
| | | |
| | | if ((index === 0 && direction === 'up') || (index === _data.length - 1 && direction === 'down')) { |
| | | return |
| | | } |
| | | |
| | | if (direction === 'up') { |
| | | _data.splice(index - 1, 0, ..._data.splice(index, 1)) |
| | | } else { |
| | | _data.splice(index + 1, 0, ..._data.splice(index, 1)) |
| | | } |
| | | |
| | | this.setState({ |
| | | data: _data |
| | | }, () => { |
| | | this.props.onChange(_data) |
| | | }) |
| | | } |
| | | |
| | | save(form, key) { |
| | | form.validateFields((error, row) => { |
| | | if (error) { |
| | | return; |
| | | } |
| | | |
| | | if (row.$url && Array.isArray(row.$url)) { |
| | | if (!row.$url[0]) { |
| | | row.$url = '' |
| | | } else if (row.$url[0].origin) { |
| | | row.$url = row.$url[0].url || '' |
| | | } else if (!row.$url[0].origin && row.$url[0].status === 'done' && row.$url[0].response) { |
| | | row.$url = row.$url[0].response |
| | | } |
| | | } |
| | | |
| | | const newData = [...this.state.data] |
| | | const index = newData.findIndex(item => key === item.key) |
| | | if (index > -1) { |
| | | const item = newData[index] |
| | | newData.splice(index, 1, { |
| | | ...item, |
| | | ...row, |
| | | }) |
| | | this.setState({ data: newData, editingKey: '' }, () => { |
| | | this.props.onChange(newData) |
| | | }) |
| | | } else { |
| | | newData.push(row); |
| | | this.setState({ data: newData, editingKey: '' }, () => { |
| | | this.props.onChange(newData) |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | handleAdd = () => { |
| | | const { fields, type } = this.props |
| | | if (this.state.editingKey) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请保存编辑中的元素!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let item = { key: Utils.getuuid(), $value: `${this.state.data.length + 1}` } |
| | | |
| | | if (type === 'picture') { |
| | | item.$url = '' |
| | | } else { |
| | | fields.forEach(f => { |
| | | item[f.field] = `${this.state.data.length + 1}` |
| | | }) |
| | | } |
| | | |
| | | let data = [...this.state.data, item] |
| | | |
| | | this.setState({ data }, () => { |
| | | this.props.onChange(data) |
| | | }) |
| | | } |
| | | |
| | | edit(key) { |
| | | this.setState({ editingKey: key }) |
| | | } |
| | | |
| | | render() { |
| | | const components = { |
| | | body: { |
| | | cell: EditableCell, |
| | | }, |
| | | } |
| | | |
| | | const columns = this.state.columns.map(col => { |
| | | if (!col.editable) { |
| | | return col |
| | | } |
| | | return { |
| | | ...col, |
| | | onCell: record => ({ |
| | | record, |
| | | dataIndex: col.dataIndex, |
| | | inputType: col.inputType, |
| | | title: col.title, |
| | | editing: this.isEditing(record), |
| | | onSave: this.onSave, |
| | | }), |
| | | } |
| | | }) |
| | | |
| | | let addable = false |
| | | if (this.props.type === 'picture') { |
| | | addable = true |
| | | } else if (this.props.fields && this.props.fields.length > 0) { |
| | | addable = true |
| | | } |
| | | |
| | | return ( |
| | | <EditableContext.Provider value={this.props.form}> |
| | | <div className="modal-card-data-table"> |
| | | {addable ? <Icon className="add-row" type="plus" onClick={this.handleAdd} /> : null} |
| | | <Table |
| | | components={components} |
| | | bordered |
| | | dataSource={this.state.data} |
| | | columns={columns} |
| | | rowClassName="editable-row" |
| | | pagination={false} |
| | | /> |
| | | </div> |
| | | </EditableContext.Provider> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(EdiDataTable) |
New file |
| | |
| | | .modal-card-data-table { |
| | | .add-row { |
| | | position: absolute; |
| | | z-index: 1; |
| | | right: 10px; |
| | | top: -30px; |
| | | padding: 5px; |
| | | font-size: 18px; |
| | | color: #26C281; |
| | | } |
| | | .editable-row { |
| | | .ant-form-explain { |
| | | position: absolute; |
| | | font-size: 12px; |
| | | margin-top: -4px; |
| | | } |
| | | .ant-form-item-control { |
| | | line-height: 1; |
| | | } |
| | | .fileupload-form-container .ant-upload-list-picture-card .ant-upload-list-item { |
| | | width: 70px; |
| | | height: 70px; |
| | | margin: 0; |
| | | padding: 2px; |
| | | .ant-upload-list-item-info > span { |
| | | height: 100%; |
| | | } |
| | | } |
| | | .fileupload-form-container .ant-upload.ant-upload-select-picture-card { |
| | | width: 70px; |
| | | height: 70px; |
| | | } |
| | | } |
| | | .operation-btn { |
| | | span { |
| | | margin-right: 7px; |
| | | cursor: pointer; |
| | | } |
| | | .primary { |
| | | color: #1890ff; |
| | | } |
| | | .danger { |
| | | color: #ff4d4f; |
| | | } |
| | | } |
| | | .operation-btn.disabled { |
| | | span { |
| | | cursor: default; |
| | | } |
| | | .primary { |
| | | color: rgba(0, 0, 0, .25); |
| | | } |
| | | .danger { |
| | | color: rgba(0, 0, 0, .25); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | import React, { Component } from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Table, Input, InputNumber, Popconfirm, Form, Icon, notification, Select } from 'antd' |
| | | |
| | | import ColorSketch from '@/mob/colorsketch' |
| | | import Utils from '@/utils/utils.js' |
| | | import './index.scss' |
| | | |
| | | const EditableContext = React.createContext() |
| | | |
| | | class EditableCell extends Component { |
| | | getInput = (form) => { |
| | | const { inputType } = this.props |
| | | if (inputType === 'number') { |
| | | return <InputNumber min={12} max={50} precision={0} onPressEnter={() => this.getValue(form)} /> |
| | | } else if (inputType === 'color') { |
| | | return <ColorSketch /> |
| | | } else if (inputType === 'select') { |
| | | return <Select> |
| | | <Select.Option key="left" value="left"> left </Select.Option> |
| | | <Select.Option key="center" value="center"> center </Select.Option> |
| | | <Select.Option key="right" value="right"> right </Select.Option> |
| | | <Select.Option key="justify" value="justify"> justify </Select.Option> |
| | | </Select> |
| | | } else { |
| | | return <Input onPressEnter={() => this.getValue(form)} /> |
| | | } |
| | | } |
| | | |
| | | getValue = (form) => { |
| | | const { record } = this.props |
| | | form.validateFields((error, row) => { |
| | | if (error) { |
| | | return |
| | | } |
| | | this.props.onSave({...record, ...row}) |
| | | }) |
| | | } |
| | | |
| | | renderCell = (form) => { |
| | | const { getFieldDecorator } = form |
| | | const { |
| | | editing, |
| | | dataIndex, |
| | | title, |
| | | inputType, |
| | | record, |
| | | index, |
| | | children, |
| | | onSave, |
| | | ...restProps |
| | | } = this.props; |
| | | return ( |
| | | <td {...restProps}> |
| | | {editing ? ( |
| | | <Form.Item style={{ margin: 0 }}> |
| | | {getFieldDecorator(dataIndex, { |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: `Please Input ${title}!`, |
| | | }, |
| | | ], |
| | | initialValue: record[dataIndex], |
| | | })(this.getInput(form))} |
| | | </Form.Item> |
| | | ) : ( |
| | | children |
| | | )} |
| | | </td> |
| | | ) |
| | | } |
| | | |
| | | render() { |
| | | return <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer> |
| | | } |
| | | } |
| | | |
| | | class EdiFieldsTable extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | onChange: PropTypes.func // 数据变化 |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | let data = this.props['data-__meta'].initialValue |
| | | |
| | | this.setState({ |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | state = { |
| | | data: [], |
| | | editingKey: '', |
| | | columns: [ |
| | | { |
| | | title: '字段名', |
| | | dataIndex: 'field', |
| | | inputType: 'input', |
| | | editable: true, |
| | | }, |
| | | { |
| | | title: '字体颜色', |
| | | dataIndex: 'color', |
| | | inputType: 'color', |
| | | editable: true, |
| | | render: (text, record) => { |
| | | return <span style={{color: text}}>示例</span> |
| | | } |
| | | }, |
| | | { |
| | | title: '字体大小', |
| | | dataIndex: 'fontSize', |
| | | inputType: 'number', |
| | | editable: true, |
| | | }, |
| | | { |
| | | title: '对齐方式', |
| | | dataIndex: 'align', |
| | | inputType: 'select', |
| | | editable: true, |
| | | }, |
| | | { |
| | | title: 'operation', |
| | | dataIndex: 'operation', |
| | | width: '18%', |
| | | render: (text, record) => { |
| | | const { editingKey } = this.state |
| | | const editable = this.isEditing(record) |
| | | return editable ? ( |
| | | <span> |
| | | <EditableContext.Consumer> |
| | | {form => ( |
| | | <span onClick={() => this.save(form, record.key)} style={{ marginRight: 8 , color: '#1890ff', cursor: 'pointer'}}> |
| | | 保存 |
| | | </span> |
| | | )} |
| | | </EditableContext.Consumer> |
| | | <span style={{ color: '#1890ff', cursor: 'pointer'}} onClick={() => this.cancel(record.key)}>取消</span> |
| | | </span> |
| | | ) : ( |
| | | <div className={'operation-btn' + (editingKey !== '' ? ' disabled' : '')}> |
| | | <span className="primary" onClick={() => {editingKey === '' && this.edit(record.key)}}><Icon type="edit" /></span> |
| | | <span className="primary" onClick={() => {editingKey === '' && this.handleUpDown(record.key, 'up')}}><Icon type="arrow-up" /></span> |
| | | <span className="danger" onClick={() => {editingKey === '' && this.handleUpDown(record.key, 'down')}}><Icon type="arrow-down" /></span> |
| | | {editingKey === '' ? <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | | title={this.props.dict['model.query.delete']} |
| | | onConfirm={() => this.handleDelete(record.key) |
| | | }> |
| | | <span className="danger"><Icon type="delete" /></span> |
| | | </Popconfirm> : null} |
| | | {editingKey !== '' ? <span className="danger"><Icon type="delete" /></span> : null} |
| | | </div> |
| | | ) |
| | | }, |
| | | }, |
| | | ] |
| | | } |
| | | |
| | | isEditing = record => record.key === this.state.editingKey |
| | | |
| | | cancel = () => { |
| | | this.setState({ editingKey: '' }) |
| | | } |
| | | |
| | | onSave = (record) => { |
| | | const newData = [...this.state.data] |
| | | const index = newData.findIndex(item => record.key === item.key) |
| | | if (index > -1) { |
| | | newData.splice(index, 1, record) |
| | | this.setState({ data: newData, editingKey: '' }, () => { |
| | | this.props.onChange(newData) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | handleDelete = (key) => { |
| | | const { data } = this.state |
| | | let _data = data.filter(item => key !== item.key) |
| | | |
| | | this.setState({ |
| | | data: _data |
| | | }, () => { |
| | | this.props.onChange(_data) |
| | | }) |
| | | } |
| | | |
| | | handleUpDown = (key, direction) => { |
| | | let _data = fromJS(this.state.data).toJS() |
| | | const index = _data.findIndex(item => key === item.key) |
| | | |
| | | if ((index === 0 && direction === 'up') || (index === _data.length - 1 && direction === 'down')) { |
| | | return |
| | | } |
| | | |
| | | if (direction === 'up') { |
| | | _data.splice(index - 1, 0, ..._data.splice(index, 1)) |
| | | } else { |
| | | _data.splice(index + 1, 0, ..._data.splice(index, 1)) |
| | | } |
| | | |
| | | this.setState({ |
| | | data: _data |
| | | }, () => { |
| | | this.props.onChange(_data) |
| | | }) |
| | | } |
| | | |
| | | save(form, key) { |
| | | form.validateFields((error, row) => { |
| | | if (error) { |
| | | return; |
| | | } |
| | | const newData = [...this.state.data] |
| | | const index = newData.findIndex(item => key === item.key) |
| | | if (index > -1) { |
| | | const item = newData[index] |
| | | newData.splice(index, 1, { |
| | | ...item, |
| | | ...row, |
| | | }) |
| | | this.setState({ data: newData, editingKey: '' }, () => { |
| | | this.props.onChange(newData) |
| | | }) |
| | | } else { |
| | | newData.push(row); |
| | | this.setState({ data: newData, editingKey: '' }, () => { |
| | | this.props.onChange(newData) |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | handleAdd = () => { |
| | | if (this.state.editingKey) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请保存编辑中的元素!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let item = { |
| | | key: Utils.getuuid(), |
| | | field: `field${this.state.data.length + 1}`, |
| | | color: 'rgba(0, 0, 0, 0.85)', |
| | | align: 'left', |
| | | fontSize: 14, |
| | | } |
| | | |
| | | let data = [...this.state.data, item] |
| | | |
| | | this.setState({ data }, () => { |
| | | this.props.onChange(data) |
| | | }) |
| | | } |
| | | |
| | | edit(key) { |
| | | this.setState({ editingKey: key }) |
| | | } |
| | | |
| | | render() { |
| | | const components = { |
| | | body: { |
| | | cell: EditableCell, |
| | | }, |
| | | } |
| | | |
| | | const columns = this.state.columns.map(col => { |
| | | if (!col.editable) { |
| | | return col |
| | | } |
| | | return { |
| | | ...col, |
| | | onCell: record => ({ |
| | | record, |
| | | inputType: col.inputType, |
| | | dataIndex: col.dataIndex, |
| | | title: col.title, |
| | | editing: this.isEditing(record), |
| | | onSave: this.onSave, |
| | | }), |
| | | } |
| | | }) |
| | | |
| | | return ( |
| | | <EditableContext.Provider value={this.props.form}> |
| | | <div className="modal-card-data-table"> |
| | | {this.state.data.length < 3 ? <Icon className="add-row" type="plus" onClick={this.handleAdd} /> : null} |
| | | <Table |
| | | components={components} |
| | | bordered |
| | | dataSource={this.state.data} |
| | | columns={columns} |
| | | rowClassName="editable-row" |
| | | pagination={false} |
| | | /> |
| | | </div> |
| | | </EditableContext.Provider> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(EdiFieldsTable) |
New file |
| | |
| | | .modal-card-data-table { |
| | | .add-row { |
| | | position: absolute; |
| | | z-index: 1; |
| | | right: 10px; |
| | | top: -30px; |
| | | padding: 5px; |
| | | font-size: 18px; |
| | | color: #26C281; |
| | | } |
| | | .editable-row { |
| | | .ant-form-explain { |
| | | position: absolute; |
| | | font-size: 12px; |
| | | margin-top: -4px; |
| | | } |
| | | .color-sketch-block { |
| | | width: 200px; |
| | | position: relative; |
| | | top: 2px; |
| | | } |
| | | .ant-select { |
| | | width: 80px; |
| | | } |
| | | } |
| | | .operation-btn { |
| | | span { |
| | | margin-right: 10px; |
| | | cursor: pointer; |
| | | } |
| | | .primary { |
| | | color: #1890ff; |
| | | } |
| | | .danger { |
| | | color: #ff4d4f; |
| | | } |
| | | } |
| | | .operation-btn.disabled { |
| | | span { |
| | | cursor: default; |
| | | } |
| | | .primary { |
| | | color: rgba(0, 0, 0, .25); |
| | | } |
| | | .danger { |
| | | color: rgba(0, 0, 0, .25); |
| | | } |
| | | } |
| | | .ant-empty { |
| | | margin: 0; |
| | | } |
| | | } |
| | |
| | | import { dateOptions } from '@/utils/option.js' |
| | | import Utils from '@/utils/utils.js' |
| | | import EditTable from './modaleditable' |
| | | import DataTable from './datatable' |
| | | import FieldsTable from './fieldtable' |
| | | import CodeMirror from '@/templates/zshare/codemirror' |
| | | import './index.scss' |
| | | |
| | | const { TextArea } = Input |
| | | |
| | | const modalTypeOptions = { |
| | | text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'entireLine'], |
| | | number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'entireLine'], |
| | | select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkSubField', 'entireLine'], |
| | | checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'entireLine'], |
| | | radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'entireLine'], |
| | | checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'display'], |
| | | multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'entireLine'], |
| | | link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkField', 'entireLine'], |
| | | fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'entireLine'], |
| | | switch: ['initval', 'openVal', 'closeVal', 'readonly', 'required', 'hidden', 'readin', 'entireLine'], |
| | | date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine'], |
| | | datemonth: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine'], |
| | | datetime: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine'], |
| | | textarea: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'maxRows', 'encryption', 'interception'], |
| | | color: ['readonly', 'required', 'hidden', 'readin', 'entireLine'], |
| | | funcvar: ['hidden'], |
| | | linkMain: ['readonly', 'required', 'hidden', 'fieldlength', 'entireLine'] |
| | | text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'entireLine', 'tooltip'], |
| | | number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'entireLine', 'tooltip'], |
| | | select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkSubField', 'entireLine', 'tooltip'], |
| | | checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'entireLine', 'tooltip'], |
| | | radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'entireLine', 'tooltip'], |
| | | checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'fieldlength', 'display', 'tooltip', 'width', 'multiple'], |
| | | multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'entireLine', 'tooltip'], |
| | | link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkField', 'entireLine', 'tooltip'], |
| | | fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'entireLine', 'tooltip'], |
| | | switch: ['initval', 'openVal', 'closeVal', 'readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'], |
| | | date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'], |
| | | datemonth: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'], |
| | | datetime: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'], |
| | | textarea: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'maxRows', 'encryption', 'interception', 'tooltip'], |
| | | color: ['readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'], |
| | | hint: ['label', 'type', 'blacklist', 'message'], |
| | | funcvar: [], |
| | | linkMain: ['readonly', 'required', 'hidden', 'fieldlength', 'entireLine', 'tooltip'] |
| | | } |
| | | |
| | | class MainSearch extends Component { |
| | |
| | | openType: null, |
| | | resourceType: null, |
| | | supField: '', |
| | | display: 'text', |
| | | cFields: [], |
| | | formlist: null, |
| | | linkSubFields: null |
| | | } |
| | |
| | | let type = '' |
| | | let resourceType = '' |
| | | let supField = '' |
| | | let display = '' |
| | | let cFields = [] |
| | | let linkSubFields = [] |
| | | |
| | | formlist.forEach(cell => { |
| | | if (cell.key === 'type') { |
| | | type = cell.initVal |
| | | } else if (cell.key === 'display') { |
| | | display = cell.initVal |
| | | } else if (cell.key === 'fields') { |
| | | cFields = cell.initVal |
| | | } else if (cell.key === 'resourceType') { |
| | | resourceType = cell.initVal |
| | | } else if (cell.key === 'linkSubField') { |
| | |
| | | } |
| | | }) |
| | | |
| | | let _options = this.getOptions(type, resourceType, supField) |
| | | let _options = this.getOptions(type, resourceType, supField, display) |
| | | |
| | | this.setState({ |
| | | openType: type, |
| | | supField: supField, |
| | | display: display, |
| | | cFields: cFields, |
| | | resourceType: resourceType, |
| | | linkSubFields: linkSubFields, |
| | | formlist: formlist.map(form => { |
| | |
| | | form.type = 'number' |
| | | form.initVal = form.initVal || 0 |
| | | form.required = true |
| | | } else if (form.key === 'label') { |
| | | form.required = true |
| | | if (type === 'hint') { |
| | | form.required = false |
| | | } |
| | | } |
| | | |
| | | form.show = _options.includes(form.key) |
| | |
| | | } |
| | | } |
| | | |
| | | getOptions = (type, resourceType, supField) => { |
| | | getOptions = (type, resourceType, supField, display) => { |
| | | let _options = ['label', 'field', 'type', 'blacklist', 'writein', ...fromJS(modalTypeOptions[type]).toJS()] |
| | | |
| | | if (['multiselect', 'select', 'link', 'radio', 'checkbox', 'checkcard'].includes(type)) { |
| | | if (type === 'hint') { |
| | | _options = fromJS(modalTypeOptions[type]).toJS() |
| | | } else if (['multiselect', 'select', 'link', 'radio', 'checkbox'].includes(type)) { |
| | | if (resourceType === '0') { // 自定义资源 |
| | | _options = [..._options, 'options'] |
| | | _options.push('options') |
| | | } else if (resourceType === '1') { // 数据源 |
| | | _options = [..._options, 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'database'] |
| | | _options.push('dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'database') |
| | | } |
| | | } else if (type === 'checkcard') { |
| | | if (display === 'picture') { |
| | | if (resourceType === '0') { // 自定义资源 |
| | | _options.push('options', 'ratio') |
| | | } else if (resourceType === '1') { // 数据源 |
| | | _options.push('dataSource', 'cardValField', 'urlField', 'orderBy', 'orderType', 'database', 'ratio') |
| | | } |
| | | } else { |
| | | if (resourceType === '0') { // 自定义资源 |
| | | _options.push('options', 'fields') |
| | | } else if (resourceType === '1') { // 数据源 |
| | | _options.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'database') |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | openTypeChange = (key, value) => { |
| | | if (key === 'type') { |
| | | let _options = this.getOptions(value, this.state.resourceType, this.state.supField) |
| | | let _options = this.getOptions(value, this.state.resourceType, this.state.supField, this.state.display) |
| | | let fieldValue = {} |
| | | |
| | | this.setState({ |
| | |
| | | if (form.show) { |
| | | fieldValue.linkSubField = form.initVal |
| | | } |
| | | } else if (form.key === 'label') { |
| | | form.required = true |
| | | if (value === 'hint') { |
| | | form.required = false |
| | | } |
| | | } |
| | | |
| | | return form |
| | | }) |
| | | }, () => { |
| | |
| | | const { openType } = this.state |
| | | let value = e.target.value |
| | | if (key === 'resourceType') { |
| | | let _options = this.getOptions(openType, value, this.state.supField) |
| | | let _options = this.getOptions(openType, value, this.state.supField, this.state.display) |
| | | |
| | | this.setState({ |
| | | resourceType: value, |
| | |
| | | return form |
| | | }) |
| | | }) |
| | | } else if (key === 'display') { |
| | | let _options = this.getOptions(openType, this.state.resourceType, this.state.supField, value) |
| | | |
| | | this.setState({ |
| | | display: value, |
| | | formlist: this.state.formlist.map(form => { |
| | | form.show = _options.includes(form.key) |
| | | return form |
| | | }) |
| | | }) |
| | | } else if (key === 'multiple') { |
| | | if (value === 'true') { |
| | | this.props.form.setFieldsValue({fieldlength: 512}) |
| | | } else { |
| | | this.props.form.setFieldsValue({fieldlength: 50}) |
| | | } |
| | | } |
| | | } |
| | | |
| | | changeField = (data) => { |
| | | this.setState({cFields: data}) |
| | | } |
| | | |
| | | handleSubmit = (e) => { |
| | |
| | | |
| | | getFields() { |
| | | const { getFieldDecorator } = this.props.form |
| | | const { openType } = this.state |
| | | const fields = [] |
| | | |
| | | this.state.formlist.forEach((item, index) => { |
| | |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.key === 'width') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | | { |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.input'] + item.label + '!' |
| | | } |
| | | ] |
| | | })(<InputNumber min={1} max={24} precision={0} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | |
| | | } else if (item.type === 'multiselect') { // 多选 |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.label}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal |
| | | })( |
| | |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'textarea') { |
| | | } else if (item.type === 'codemirror') { |
| | | fields.push( |
| | | <Col span={20} offset={4} key={index}> |
| | | <Form.Item className="text-area"> |
| | | <Col span={24} key={index}> |
| | | <Form.Item className="text-area" label={item.label}> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'options') { |
| | | } else if (item.type === 'textarea') { |
| | | fields.push( |
| | | <Col span={20} offset={4} key={index}> |
| | | <Form.Item className="text-area"> |
| | | <Col span={24} key={index}> |
| | | <Form.Item className="text-msg" label={item.label}> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal, |
| | | rules: [ |
| | | { |
| | | required: !!item.required, |
| | | message: this.props.dict['form.required.input'] + item.label + '!' |
| | | } |
| | | ] |
| | | })(<TextArea rows={4} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'options') { |
| | | if (openType !== 'checkcard') { |
| | | fields.push( |
| | | <Col span={24} key={index}> |
| | | <Form.Item label={item.label} className="text-area"> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal |
| | | })(<EditTable dict={this.props.dict} type={openType} linkSubFields={this.state.linkSubFields}/>)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else { |
| | | fields.push( |
| | | <Col span={24} key={index}> |
| | | <Form.Item label={item.label} className="text-area"> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal |
| | | })(<DataTable dict={this.props.dict} type={this.state.display} fields={this.state.cFields}/>)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } |
| | | } else if (item.type === 'fields') { |
| | | fields.push( |
| | | <Col span={24} key={index}> |
| | | <Form.Item label={item.label} className="text-area"> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal |
| | | })(<EditTable dict={this.props.dict} type={this.state.openType} linkSubFields={this.state.linkSubFields}/>)} |
| | | })(<FieldsTable dict={this.props.dict} onChange={this.changeField}/>)} |
| | | </Form.Item> |
| | | {/* <EditTable data={item.initVal} dict={this.props.dict} type={this.state.openType} linkSubFields={this.state.linkSubFields} ref="editTable"/> */} |
| | | </Col> |
| | | ) |
| | | } |
| | |
| | | } |
| | | } |
| | | return ( |
| | | <Form {...formItemLayout} className="ant-advanced-search-form modal-fields-form" id="modal-fields-form-box"> |
| | | <Form {...formItemLayout} className="modal-fields-form" id="modal-fields-form-box"> |
| | | <Row gutter={24}>{this.getFields()}</Row> |
| | | </Form> |
| | | ) |
| | |
| | | .ant-advanced-search-form.modal-fields-form { |
| | | .modal-fields-form { |
| | | min-height: 180px; |
| | | .ant-col-offset-4 { |
| | | padding-left: 6px!important; |
| | | padding-bottom: 20px; |
| | | } |
| | | .ant-form-item.text-area { |
| | | margin-bottom: 0px; |
| | | .ant-form-item-control-wrapper { |
| | | width: 100%; |
| | | >.ant-form-item-control-wrapper { |
| | | width: 84%; |
| | | .ant-table-tbody > tr > td { |
| | | padding: 16px 10px; |
| | | } |
| | | } |
| | | >.ant-form-item-label { |
| | | width: 16%; |
| | | } |
| | | .CodeMirror { |
| | | height: 150px; |
| | | } |
| | | } |
| | | .ant-form-item.text-msg { |
| | | >.ant-form-item-label { |
| | | width: 16%; |
| | | } |
| | | >.ant-form-item-control-wrapper { |
| | | width: 84%; |
| | | } |
| | | } |
| | | .ant-form-item-label .anticon-question-circle { |
| | | color: #c49f47; |
| | | margin-right: 3px; |
| | | } |
| | | .ant-radio-group { |
| | | white-space: nowrap; |
| | | } |
| | | .ant-input-number { |
| | | width: 100%; |
| | | } |
| | |
| | | data = [] |
| | | } |
| | | |
| | | let _width = '40%' |
| | | let fields = [] |
| | | let dataItem = data[0] || '' |
| | | |
| | | if (type === 'link') { |
| | | _width = '27%' |
| | | } else if (type === 'select') { |
| | | _width = Math.floor(80 / (linkSubFields.length + 2)) + '%' |
| | | if (type === 'select' || type === 'radio') { |
| | | fields = linkSubFields.map(cell => { |
| | | return { |
| | | title: cell.label, |
| | | dataIndex: cell.field, |
| | | width: _width, |
| | | editable: true, |
| | | datatype: dataItem && typeof(dataItem[cell.field]) === 'number' ? 'number' : 'string' |
| | | } |
| | | }) |
| | | } |
| | | |
| | | |
| | | |
| | | let columns = [ |
| | | { |
| | | title: 'Value', |
| | | dataIndex: 'Value', |
| | | width: _width, |
| | | editable: true, |
| | | datatype: dataItem && typeof(dataItem.Value) === 'number' ? 'number' : 'string' |
| | | }, |
| | | { |
| | | title: 'Text', |
| | | dataIndex: 'Text', |
| | | width: _width, |
| | | editable: true, |
| | | datatype: dataItem && typeof(dataItem.Text) === 'number' ? 'number' : 'string' |
| | | }, |
| | |
| | | { |
| | | title: '操作', |
| | | align: 'center', |
| | | width: '20%', |
| | | dataIndex: 'operation', |
| | | render: (text, record) => |
| | | this.state.dataSource.length >= 1 ? ( |
| | |
| | | columns.unshift({ |
| | | title: 'ParentID', |
| | | dataIndex: 'ParentID', |
| | | width: '27%', |
| | | editable: true, |
| | | datatype: dataItem && typeof(dataItem.ParentID) === 'number' ? 'number' : 'string' |
| | | }) |
| | |
| | | |
| | | resetColumn = (type, linkSubFields) => { |
| | | let dataSource = JSON.parse(JSON.stringify(this.state.dataSource)) |
| | | let _width = '40%' |
| | | let fields = [] |
| | | |
| | | if (type === 'select' && linkSubFields.length > this.state.linkSubFields) { |
| | | if ((type === 'select' || type === 'radio') && linkSubFields.length > this.state.linkSubFields) { |
| | | let addcol = linkSubFields[linkSubFields.length - 1] |
| | | dataSource = dataSource.map(data => { |
| | | data[addcol.field] = data.Text |
| | |
| | | |
| | | let dataItem = dataSource ? dataSource[0] : '' |
| | | |
| | | if (type === 'link') { |
| | | _width = '27%' |
| | | } else if (type === 'select') { |
| | | _width = Math.floor(80 / (linkSubFields.length + 2)) + '%' |
| | | if (type === 'select' || type === 'radio') { |
| | | fields = linkSubFields.map(field => { |
| | | return { |
| | | title: field.label, |
| | | dataIndex: field.field, |
| | | width: _width, |
| | | editable: true, |
| | | datatype: dataItem && typeof(dataItem[field.field]) === 'number' ? 'number' : 'string' |
| | | } |
| | |
| | | { |
| | | title: 'Value', |
| | | dataIndex: 'Value', |
| | | width: _width, |
| | | editable: true, |
| | | datatype: dataItem && typeof(dataItem.Value) === 'number' ? 'number' : 'string' |
| | | }, |
| | | { |
| | | title: 'Text', |
| | | dataIndex: 'Text', |
| | | width: _width, |
| | | editable: true, |
| | | datatype: dataItem && typeof(dataItem.Text) === 'number' ? 'number' : 'string' |
| | | }, |
| | |
| | | { |
| | | title: '操作', |
| | | align: 'center', |
| | | width: '20%', |
| | | dataIndex: 'operation', |
| | | render: (text, record) => |
| | | this.state.dataSource.length >= 1 ? ( |
| | |
| | | columns.unshift({ |
| | | title: 'ParentID', |
| | | dataIndex: 'ParentID', |
| | | width: '27%', |
| | | editable: true, |
| | | datatype: dataItem && typeof(dataItem.ParentID) === 'number' ? 'number' : 'string' |
| | | }) |
| | |
| | | .add-row { |
| | | position: absolute; |
| | | z-index: 1; |
| | | right: 20px; |
| | | right: 10px; |
| | | top: -30px; |
| | | padding: 5px; |
| | | font-size: 18px; |
| | |
| | | margin-right: 10px; |
| | | cursor: pointer; |
| | | } |
| | | .ant-form-explain { |
| | | .editable-row { |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | } |