From 432b788acf901b0720184b8ee8bc81a2e6fa47e0 Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期二, 28 九月 2021 18:22:02 +0800 Subject: [PATCH] 2021-09-28 --- src/pc/transfer/index.jsx | 1 src/tabviews/zshare/mutilform/mkRadio/index.jsx | 2 src/templates/zshare/modalform/index.jsx | 4 src/tabviews/zshare/mutilform/mkSwitch/index.jsx | 2 src/tabviews/zshare/topSearch/index.jsx | 27 src/tabviews/zshare/topSearch/mkSelect/index.jsx | 2 src/tabviews/zshare/mutilform/mkSelect/index.jsx | 2 src/menu/components/table/edit-table/options.jsx | 204 +++++ src/menu/components/table/edit-table/columns/editColumn/index.scss | 27 src/pc/quotecomponent/settingform/index.scss | 11 src/menu/menushell/card.jsx | 3 src/components/paste/index.jsx | 1 src/menu/components/table/edit-table/columns/editColumn/index.jsx | 388 +++++++++ src/menu/components/table/edit-table/index.jsx | 422 ++++++++++ src/menu/modulesource/option.jsx | 2 src/components/normalform/modalform/mkSelect/index.jsx | 1 src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx | 394 +++++++++ src/menu/components/table/edit-table/index.scss | 80 ++ src/templates/zshare/formconfig.jsx | 28 src/pc/quotecomponent/settingform/index.jsx | 2 src/pc/menushell/card.jsx | 3 src/components/normalform/modalform/mkRadio/index.jsx | 1 src/menu/components/group/groupcomponents/card.jsx | 3 src/tabviews/zshare/mutilform/index.jsx | 2 src/components/normalform/modalform/mkCheckbox/index.jsx | 2 src/components/normalform/index.jsx | 1 src/menu/components/table/edit-table/columns/index.scss | 124 +++ src/tabviews/zshare/mutilform/mkTextArea/index.jsx | 1 src/tabviews/zshare/mutilform/mkCheckbox/index.jsx | 2 src/tabviews/zshare/topSearch/mkDatePicker/index.jsx | 2 src/menu/components/tabs/tabcomponents/card.jsx | 3 src/tabviews/zshare/mutilform/mkDatePicker/index.jsx | 2 src/menu/components/table/edit-table/columns/index.jsx | 601 +++++++++++++++ src/templates/sharecomponent/searchcomponent/searchform/index.jsx | 4 34 files changed, 2,301 insertions(+), 53 deletions(-) diff --git a/src/components/normalform/index.jsx b/src/components/normalform/index.jsx index de675fb..5ef4c9d 100644 --- a/src/components/normalform/index.jsx +++ b/src/components/normalform/index.jsx @@ -6,7 +6,6 @@ import zhCN from '@/locales/zh-CN/model.js' import enUS from '@/locales/en-US/model.js' import ModalForm from './modalform' -import './index.scss' class NormalFormComponent extends Component { static propTpyes = { diff --git a/src/components/normalform/modalform/mkCheckbox/index.jsx b/src/components/normalform/modalform/mkCheckbox/index.jsx index 934eece..e8d95c8 100644 --- a/src/components/normalform/modalform/mkCheckbox/index.jsx +++ b/src/components/normalform/modalform/mkCheckbox/index.jsx @@ -3,8 +3,6 @@ import { is, fromJS } from 'immutable' import { Checkbox } from 'antd' -import './index.scss' - class MKCheckbox extends Component { static propTpyes = { config: PropTypes.object, diff --git a/src/components/normalform/modalform/mkRadio/index.jsx b/src/components/normalform/modalform/mkRadio/index.jsx index c14b111..212df13 100644 --- a/src/components/normalform/modalform/mkRadio/index.jsx +++ b/src/components/normalform/modalform/mkRadio/index.jsx @@ -4,7 +4,6 @@ import { Radio } from 'antd' import MKEmitter from '@/utils/events.js' -import './index.scss' class MKRadio extends Component { static propTpyes = { diff --git a/src/components/normalform/modalform/mkSelect/index.jsx b/src/components/normalform/modalform/mkSelect/index.jsx index c5c6ad4..25c5984 100644 --- a/src/components/normalform/modalform/mkSelect/index.jsx +++ b/src/components/normalform/modalform/mkSelect/index.jsx @@ -3,7 +3,6 @@ import { Select } from 'antd' import MKEmitter from '@/utils/events.js' -import './index.scss' class MKSelect extends Component { constructor(props) { diff --git a/src/components/paste/index.jsx b/src/components/paste/index.jsx index 4760c22..5efc6b6 100644 --- a/src/components/paste/index.jsx +++ b/src/components/paste/index.jsx @@ -3,7 +3,6 @@ import { Icon, Modal, notification } from 'antd' import asyncComponent from '@/utils/asyncComponent' -import './index.scss' const PasteForm = asyncComponent(() => import('@/templates/zshare/pasteform')) diff --git a/src/menu/components/group/groupcomponents/card.jsx b/src/menu/components/group/groupcomponents/card.jsx index 4f58886..cec20ff 100644 --- a/src/menu/components/group/groupcomponents/card.jsx +++ b/src/menu/components/group/groupcomponents/card.jsx @@ -11,6 +11,7 @@ const TableCard = asyncComponent(() => import('@/menu/components/card/table-card')) const NormalTree = asyncComponent(() => import('@/menu/components/tree/antd-tree')) const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table')) +const EditTable = asyncComponent(() => import('@/menu/components/table/edit-table')) const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor')) const AntvScatter = asyncComponent(() => import('@/menu/components/chart/antv-scatter')) const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form')) @@ -77,6 +78,8 @@ return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'table' && card.subtype === 'normaltable') { return (<NormalTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'table' && card.subtype === 'editable') { + return (<EditTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'carousel' && card.subtype === 'datacard') { return (<CarouselDataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'carousel' && card.subtype === 'propcard') { diff --git a/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx b/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx new file mode 100644 index 0000000..e2b4ae1 --- /dev/null +++ b/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx @@ -0,0 +1,394 @@ +import zhCN from '@/locales/zh-CN/model.js' +import enUS from '@/locales/en-US/model.js' + +const Formdict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS + +/** + * @description 鑾峰彇鏄剧ず鍒楄〃鍗曢厤缃俊鎭� + * @param {object} card // 鎼滅储鏉′欢瀵硅薄 + */ +export function getColumnForm (card, fields = []) { + let appType = sessionStorage.getItem('appType') + let roleList = sessionStorage.getItem('sysRoles') + if (roleList) { + try { + roleList = JSON.parse(roleList) + } catch (e) { + roleList = [] + } + } else { + roleList = [] + } + + let menulist = [] + + if (appType === 'pc') { + menulist = sessionStorage.getItem('appMenus') + } else if (!appType) { + menulist = sessionStorage.getItem('fstMenuList') + } + + if (menulist) { + try { + menulist = JSON.parse(menulist) + } catch (e) { + menulist = [] + } + } else { + menulist = [] + } + + let options = [{ + value: 'text', + text: Formdict['model.form.text'] + }, { + value: 'number', + text: Formdict['model.form.number'] + }, { + value: 'picture', + text: Formdict['model.form.picture'] + }, { + value: 'link', + text: Formdict['model.form.href'] + }, { + value: 'textarea', + text: Formdict['model.form.textarea'] + }, { + value: 'custom', + text: '鑷畾涔夊垪' + }, { + value: 'colspan', + text: '鍚堝苟鍒�' + }, { + value: 'index', + text: '搴忓彿' + }] + + if (!card.isSub) { + options.push({ + value: 'action', + text: '鎿嶄綔' + }) + } + + if (!card.linkurl && (!card.linkmenu || card.linkmenu.length === 0)) { + card.perspective = '' + } + + return [ + { + type: 'text', + key: 'label', + label: '鍒楀ご鏂囧瓧', + initVal: card.label, + required: true + }, + { + type: 'select', + key: 'type', + label: Formdict['model.form.type'], + initVal: card.type, + required: true, + options: options + }, + { + type: 'select', + key: 'field', + label: Formdict['model.form.field'], + initVal: card.field, + required: true, + options: fields + }, + { + type: 'select', + key: 'nameField', + label: Formdict['model.name'] + Formdict['model.form.field'], + initVal: card.nameField || '', + required: false, + options: [{uuid: 'empty', field: '', label: '绌�'}, ...fields] + }, + { + type: 'number', + key: 'Width', + min: 20, + max: 1000, + decimal: 0, + label: Formdict['model.form.columnWidth'], + initVal: card.Width || 120, + required: true + }, + { + type: 'radio', + key: 'joint', + label: Formdict['model.form.paramJoint'], + initVal: card.joint || 'true', + required: true, + options: [{ + value: 'true', + text: Formdict['model.true'] + }, { + value: 'false', + text: Formdict['model.false'] + }] + }, + { + type: 'radio', + key: 'Hide', + label: Formdict['model.hidden'], + initVal: card.Hide || 'false', + required: true, + options: [{ + value: 'true', + text: Formdict['model.true'] + }, { + value: 'false', + text: Formdict['model.false'] + }] + }, + { + type: 'radio', + key: 'IsSort', + label: Formdict['model.sort'], + initVal: card.IsSort || 'true', + required: true, + forbidden: card.isSub, + options: [{ + value: 'true', + text: Formdict['model.true'] + }, { + value: 'false', + text: Formdict['model.false'] + }] + }, + { + type: 'radio', + key: 'Align', + label: Formdict['model.form.align'], + initVal: card.Align || 'left', + required: true, + options: [{ + value: 'left', + text: Formdict['model.form.alignLeft'] + }, { + value: 'center', + text: Formdict['model.form.alignCenter'] + }, { + value: 'right', + text: Formdict['model.form.alignRight'] + }] + }, + { + type: 'radio', + key: 'rowspan', + label: '琛屽悎骞�', + initVal: card.rowspan || 'false', + tooltip: '鐩搁偦琛屼俊鎭浉鍚屾椂锛屽崟鍏冩牸鍚堝苟銆�', + required: false, + options: [{ + value: 'true', + text: Formdict['model.true'] + }, { + value: 'false', + text: Formdict['model.false'] + }] + }, + { + type: 'radio', + key: 'sum', + label: '鏄剧ず鍚堣', + initVal: card.sum || 'false', + tooltip: '鍚堣淇℃伅鍙湪浣跨敤绯荤粺鏁版嵁婧愭椂鏈夋晥銆�', + required: false, + options: [{ + value: 'true', + text: Formdict['model.true'] + }, { + value: 'false', + text: Formdict['model.false'] + }] + }, + { + type: 'number', + key: 'decimal', + min: 0, + max: 18, + decimal: 0, + label: Formdict['header.form.decimal'], + initVal: card.decimal || 0, + required: true + }, + { + type: 'select', + key: 'format', + label: Formdict['header.form.format'], + initVal: card.format || 'none', + options: [{ + value: 'none', + text: Formdict['model.empty'] + }, { + value: 'thdSeparator', + text: Formdict['header.form.thdSeparator'] + }, { + value: 'percent', + text: '鐧惧垎姣�' + }], + required: false + }, + { + type: 'select', + key: 'textFormat', + label: Formdict['header.form.format'], + initVal: card.textFormat || 'none', + options: [{ + value: 'none', + text: Formdict['model.empty'] + }, { + value: 'YYYY-MM-DD', + text: 'YYYY-MM-DD' + }, { + value: 'YYYY-MM-DD HH:mm:ss', + text: 'YYYY-MM-DD HH:mm:ss' + }], + required: false + }, + { + type: 'text', + key: 'prefix', + label: Formdict['header.form.prefix'], + initVal: card.prefix || '', + required: false, + readonly: false + }, + { + type: 'text', + key: 'postfix', + label: Formdict['header.form.postfix'], + initVal: card.postfix || '', + required: false, + readonly: false + }, + { + type: 'select', + key: 'lenWidRadio', + label: '闀垮姣�', + initVal: card.lenWidRadio || '1:1', + required: true, + options: [ + { value: '1:1', text: '1:1' }, + { value: '4:3', text: '4:3' }, + { value: '3:2', text: '3:2' }, + { value: '16:9', text: '16:9' }, + { value: '2:1', text: '2:1' }, + { value: '3:1', text: '3:1' }, + { value: '4:1', text: '4:1' }, + { value: '5:1', text: '5:1' }, + { value: '6:1', text: '6:1' }, + { value: '7:1', text: '7:1' }, + { value: '8:1', text: '8:1' }, + { value: '9:1', text: '9:1' }, + { value: '10:1', text: '10:1' }, + { value: '3:4', text: '3:4' }, + { value: '2:3', text: '2:3' }, + { value: '9:16', text: '9:16' }, + ] + }, + { + type: 'radio', + key: 'picSort', + label: '鍥剧墖鎺掑垪', + initVal: card.picSort || '1', + tooltip: '鍚屼竴鍗曞厓鏍煎唴锛屽惈鏈夊寮犲浘鐗囨椂鐨勫垪鏁般��', + required: false, + options: [{ + value: '1', + text: '1' + }, { + value: '2', + text: '2' + }, { + value: '3', + text: '3' + }, { + value: '4', + text: '4' + }] + }, + { + type: 'radio', + key: 'scale', + label: Formdict['header.form.clickscale'], + initVal: card.scale || 'false', + required: false, + options: [{ + value: 'true', + text: Formdict['model.true'] + }, { + value: 'false', + text: Formdict['model.false'] + }] + }, + { + type: 'radio', + key: 'perspective', + label: '瀛楁閫忚', + initVal: card.perspective || '', + options: [{ + value: '', + text: '鏃�' + }, { + value: 'linkmenu', + text: '鑿滃崟' + }, { + value: 'linkurl', + text: '閾炬帴' + }], + forbidden: appType === 'mob' + }, + { + type: appType === 'pc' ? 'select' : 'cascader', + key: 'linkmenu', + label: Formdict['model.menu'], + initVal: card.linkmenu || (appType === 'pc' ? '' : []), + required: true, + options: menulist, + forbidden: appType === 'mob' + }, + { + type: 'textarea', + key: 'linkurl', + label: '閾炬帴鍦板潃', + initVal: card.linkurl || '', + required: true, + forbidden: appType === 'mob' + }, + { + type: 'multiselect', + key: 'linkfields', + label: '鍏宠仈瀛楁', + initVal: card.linkfields || [], + required: false, + options: fields, + forbidden: appType === 'mob' + }, + { + type: 'radio', + key: 'open', + label: '鎵撳紑鏂瑰紡', + initVal: card.open || 'blank', + required: false, + forbid: appType !== 'pc', + options: [ + { value: 'blank', text: '鏂扮獥鍙�' }, + { value: 'self', text: '褰撳墠绐楀彛' } + ] + }, + { + type: 'multiselect', + key: 'blacklist', + label: Formdict['header.form.blacklist'], + initVal: card.blacklist || [], + required: false, + options: roleList + } + ] +} diff --git a/src/menu/components/table/edit-table/columns/editColumn/index.jsx b/src/menu/components/table/edit-table/columns/editColumn/index.jsx new file mode 100644 index 0000000..81aed8a --- /dev/null +++ b/src/menu/components/table/edit-table/columns/editColumn/index.jsx @@ -0,0 +1,388 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Form, Row, Col, Input, Select, InputNumber, Radio, Tooltip, Icon, Cascader, Modal } from 'antd' + +import { getColumnForm } from './formconfig' +import { formRule } from '@/utils/option.js' +import './index.scss' + +const { TextArea } = Input +const columnTypeOptions = { + text: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'textFormat', 'blacklist', 'perspective', 'rowspan'], + number: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'decimal', 'format', 'prefix', 'postfix', 'blacklist', 'perspective', 'sum', 'rowspan'], + link: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'joint', 'Width', 'blacklist', 'nameField'], + textarea: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'blacklist'], + picture: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'blacklist', 'scale', 'lenWidRadio', 'picSort'], + colspan: ['label', 'type', 'Align', 'Hide', 'blacklist'], + custom: ['label', 'type', 'Align', 'Hide', 'Width', 'blacklist'], + action: ['label', 'type', 'Align', 'Width'], + index: ['label', 'type', 'Align', 'Width'] +} + +class MainSearch extends Component { + static propTpyes = { + dict: PropTypes.object, // 瀛楀吀椤� + visible: PropTypes.bool, + column: PropTypes.object, + fields: PropTypes.array, + submitCol: PropTypes.func, // 鎻愪氦浜嬩欢 + cancelCol: PropTypes.func // 鍙栨秷鏃跺垹闄や簨浠� + } + + state = { + visible: false, + formlist: null + } + + UNSAFE_componentWillReceiveProps (nextProps) { + if (nextProps.column && !is(fromJS(this.props.column), fromJS(nextProps.column))) { + this.editColumn(nextProps.column) + } + } + + editColumn = (column) => { + let formlist = getColumnForm(column, this.props.fields) + let _options = fromJS(columnTypeOptions[column.type]).toJS() + if (column.type === 'text' || column.type === 'number') { + if (column.perspective === 'linkmenu') { + _options.push('linkmenu', 'linkfields', 'open') + } else if (column.perspective === 'linkurl') { + _options.push('linkurl', 'linkfields', 'open') + } + } + + this.setState({ + visible: true, + type: column.type, + formlist: formlist.map(item => { + item.hidden = !_options.includes(item.key) + + return item + }) + }, () => { + if (column.focus) { + try { + let _form = document.getElementById('label') + _form && _form.select() + } catch (e) { + console.warn('琛ㄥ崟focus澶辫触锛�') + } + } + }) + } + + typeChange = (key, value, option) => { + if (key === 'type') { + let _options = fromJS(columnTypeOptions[value]).toJS() + + this.setState({ + type: value, + formlist: this.state.formlist.map(item => { + item.hidden = !_options.includes(item.key) + + return item + }) + }, () => { + if (value === 'link' || value === 'textarea' || value === 'picture') { + this.props.form.setFieldsValue({IsSort: 'false'}) + } else if (value === 'text' || value === 'number') { + this.props.form.setFieldsValue({perspective: ''}) + } else if (value === 'action' || value === 'colspan') { + this.props.form.setFieldsValue({Align: 'center'}) + } + }) + } else if (key === 'field') { + let values = {label: option.props.children} + if (/Decimal|int/ig.test(option.props.datatype)) { + let decimal = 0 + if (/Decimal/ig.test(option.props.datatype)) { + decimal = +option.props.datatype.replace(/Decimal\(18,/ig, '').replace(')', '') + } + values.type = 'number' + values.decimal = decimal + } else { + values.type = 'text' + } + + if (values.type !== this.state.type) { + values.perspective = '' + let _options = fromJS(columnTypeOptions[values.type]).toJS() + + this.setState({ + type: values.type, + formlist: this.state.formlist.map(item => { + item.hidden = !_options.includes(item.key) + + return item + }) + }, () => { + this.props.form.setFieldsValue(values) + }) + } else { + this.props.form.setFieldsValue(values) + } + } else if (key === 'format' && value === 'percent') { + this.props.form.setFieldsValue({postfix: '%'}) + } + } + + changeRadio = (key, value) => { + if (key === 'perspective') { + let _options = fromJS(columnTypeOptions[this.state.type]).toJS() + + if (value === 'linkmenu') { + _options.push('linkmenu', 'linkfields', 'open') + } else if (value === 'linkurl') { + _options.push('linkurl', 'linkfields', 'open') + } + + this.setState({ + formlist: this.state.formlist.map(item => { + item.hidden = !_options.includes(item.key) + + return item + }) + }) + } + } + + getFields() { + const { getFieldDecorator } = this.props.form + const { formlist } = this.state + const fields = [] + + if (!formlist) return null + + formlist.forEach((item, index) => { + if (item.hidden || item.forbidden) return + + if (item.type === 'text') { // 鏂囨湰鎼滅储 + let rules = [] + if (item.key !== 'linkurl') { + rules = [{ + max: formRule.input.max, + message: formRule.input.message + }] + } + fields.push( + <Col span={12} key={index}> + <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 || '', + rules: [ + { + required: !!item.required, + message: this.props.dict['form.required.input'] + item.label + '!' + }, + ...rules + ] + })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.handleSubmit} />)} + </Form.Item> + </Col> + ) + } else if (item.type === 'number') { + fields.push( + <Col span={12} key={index}> + <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, + rules: [ + { + required: !!item.required, + message: this.props.dict['form.required.input'] + item.label + '!' + } + ] + })(item.unlimit ? <InputNumber onPressEnter={this.handleSubmit}/> : + <InputNumber min={item.min} max={item.max} precision={item.decimal} onPressEnter={this.handleSubmit}/>)} + </Form.Item> + </Col> + ) + } else if (item.type === 'select') { + fields.push( + <Col span={12} key={index}> + <Form.Item label={item.label}> + {getFieldDecorator(item.key, { + initialValue: item.initVal || '', + rules: [ + { + required: !!item.required, + message: this.props.dict['form.required.select'] + item.label + '!' + } + ] + })( + <Select + showSearch + filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} + onChange={(value, option) => {this.typeChange(item.key, value, option)}} + getPopupContainer={() => document.getElementById('columnwinter')} + > + {item.options.map((option, index) => + <Select.Option key={index} datatype={option.datatype || ''} value={(option.value || option.field || option.MenuID)}> + {(option.text || option.label || option.MenuName)} + </Select.Option> + )} + </Select> + )} + </Form.Item> + </Col> + ) + } else if (item.type === 'radio') { + fields.push( + <Col span={12} key={index}> + <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, + rules: [ + { + required: !!item.required, + message: this.props.dict['form.required.select'] + item.label + '!' + } + ] + })( + <Radio.Group onChange={(e) => {this.changeRadio(item.key, e.target.value)}}> + { + item.options.map(option => { + return ( + <Radio key={option.value} value={option.value}>{option.text}</Radio> + ) + }) + } + </Radio.Group> + )} + </Form.Item> + </Col> + ) + } else if (item.type === 'multiselect') { // 澶氶�� + fields.push( + <Col span={12} key={index}> + <Form.Item label={item.label}> + {getFieldDecorator(item.key, { + initialValue: item.initVal || [] + })( + <Select + showSearch + mode="multiple" + filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} + > + {item.options.map((option, i) => + <Select.Option id={i} key={i} value={option.value || option.field}>{option.text || option.label}</Select.Option> + )} + </Select> + )} + </Form.Item> + </Col> + ) + } else if (item.type === 'cascader') { // 澶氶�� + fields.push( + <Col span={12} key={index}> + <Form.Item label={item.label}> + {getFieldDecorator(item.key, { + initialValue: item.initVal || [], + rules: [ + { + required: !!item.required, + message: this.props.dict['form.required.select'] + item.label + '!' + } + ] + })( + <Cascader + options={item.options} + placeholder="" + getPopupContainer={() => document.getElementById('columnwinter')} + /> + )} + </Form.Item> + </Col> + ) + } else if (item.type === 'textarea') { // 鏂囨湰鎼滅储 + fields.push( + <Col span={24} key={index} className="textarea"> + <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 || '', + rules: [ + { + required: !!item.required, + message: this.props.dict['form.required.input'] + item.label + '!' + } + ] + })(<TextArea rows={2} disabled={item.readonly} onPressEnter={this.handleSubmit} />)} + </Form.Item> + </Col> + ) + } + }) + return fields + } + + handleSubmit = () => { + // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭� + this.props.form.validateFieldsAndScroll((err, values) => { + if (!err) { + this.setState({visible: false, formlist: null}) + this.props.submitCol(values) + } + }) + } + + editModalCancel = () => { + this.setState({visible: false, formlist: null}) + + this.props.cancelCol() + } + + render() { + const { visible } = this.state + const formItemLayout = { + labelCol: { + xs: { span: 24 }, + sm: { span: 6 } + }, + wrapperCol: { + xs: { span: 24 }, + sm: { span: 18 } + } + } + + return ( + <div style={{display: 'inline-block'}}> + <Modal + title="鏄剧ず鍒楃紪杈�" + visible={visible} + width={800} + maskClosable={false} + onOk={this.handleSubmit} + onCancel={this.editModalCancel} + destroyOnClose + > + <Form {...formItemLayout} className="commontable-column-form" id="columnwinter"> + <Row gutter={24}>{this.getFields()}</Row> + </Form> + </Modal> + </div> + ) + } +} + +export default Form.create()(MainSearch) \ No newline at end of file diff --git a/src/menu/components/table/edit-table/columns/editColumn/index.scss b/src/menu/components/table/edit-table/columns/editColumn/index.scss new file mode 100644 index 0000000..e450762 --- /dev/null +++ b/src/menu/components/table/edit-table/columns/editColumn/index.scss @@ -0,0 +1,27 @@ +.commontable-column-form { + min-height: 190px; + .ant-form-item { + .ant-input-number { + width: 100%; + } + } + .anticon-question-circle { + color: #c49f47; + position: relative; + left: -3px; + } + .ant-cascader-menus { + padding: 5px 0px; + .ant-cascader-menu:last-child { + padding-right: 3px; + } + } + .textarea { + .ant-form-item-label { + width: 12%; + } + .ant-form-item-control-wrapper { + width: 88%; + } + } +} diff --git a/src/menu/components/table/edit-table/columns/index.jsx b/src/menu/components/table/edit-table/columns/index.jsx new file mode 100644 index 0000000..c347313 --- /dev/null +++ b/src/menu/components/table/edit-table/columns/index.jsx @@ -0,0 +1,601 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { DndProvider, DragSource, DropTarget } from 'react-dnd' +import { Table, Popover, Icon, Modal, message } from 'antd' + +import asyncComponent from '@/utils/asyncComponent' +import asyncIconComponent from '@/utils/asyncIconComponent' +import Utils from '@/utils/utils.js' +import zhCN from '@/locales/zh-CN/model.js' +import enUS from '@/locales/en-US/model.js' +import MKEmitter from '@/utils/events.js' +import './index.scss' + +const { confirm } = Modal +const EditColumn = asyncIconComponent(() => import('./editColumn')) +const MarkColumn = asyncIconComponent(() => import('@/menu/components/share/markcomponent')) +const CardCellComponent = asyncComponent(() => import('@/menu/components/card/cardcellcomponent')) + +class HeaderCol extends Component { + deleteCol = () => { + const _this = this + + confirm({ + content: '纭畾鍒犻櫎鏄剧ず鍒楀悧锛�', + onOk() { + _this.props.deleteCol(_this.props.column) + }, + onCancel() {} + }) + } + + updateMarks = (vals) => { + const { column } = this.props + this.props.updateCol({...column, marks: vals}) + } + + shouldComponentUpdate (nextProps, nextState) { + + if (this.props.rowSpan !== nextProps.rowSpan || this.props.colSpan !== nextProps.colSpan) { + return true + } + + if (!nextProps.column) return false + + return !is(fromJS(this.props.column), fromJS(nextProps.column)) || + !is(fromJS(this.props.fields), fromJS(nextProps.fields)) || + this.props.index !== nextProps.index + } + + render() { + const { connectDragSource, connectDropTarget, moveCol, addElement, updateCol, editColumn, changeStyle, deleteCol, index, column, align, fields, children, ...restProps } = this.props + + if (index !== undefined) { + return connectDragSource( + connectDropTarget(<th {...restProps} index={index} style={{ cursor: 'move', textAlign: align }} onDoubleClick={() => column && this.props.editColumn(column)}> + <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ + <div className="mk-popover-control"> + {column && ['custom', 'colspan', 'action'].includes(column.type) ? + <Icon className="plus" title="娣诲姞" type="plus" onClick={() => this.props.addElement(column)} /> : null + } + <Icon className="edit" title="缂栬緫" type="edit" onClick={() => this.props.editColumn(column)} /> + {column && column.type === 'custom' ? <Icon className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)} type="font-colors" /> : null} + <Icon className="close" title="鍒犻櫎" type="delete" onClick={this.deleteCol} /> + {column && ['text', 'number'].includes(column.type) ? <MarkColumn columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null } + </div> + } trigger="hover"> + {children} + </Popover> + </th>), + ) + } else if (column) { + return ( + <th {...restProps} key={column.uuid} onDoubleClick={() => this.props.editColumn(column)}> + <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ + <div className="mk-popover-control"> + {column && ['custom', 'colspan'].includes(column.type) ? + <Icon className="plus" title="娣诲姞" type="plus" onClick={() => this.props.addElement(column)} /> : null + } + <Icon className="edit" title="缂栬緫" type="edit" onClick={() => this.props.editColumn(column)} /> + <Icon className="close" title="鍒犻櫎" type="delete" onClick={this.deleteCol} /> + {column && ['text', 'number'].includes(column.type) ? <MarkColumn columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null } + </div> + } trigger="hover"> + {children} + </Popover> + </th> + ) + } else { + return (<th {...restProps}>{children}</th>) + } + } +} + +const rowSource = { + beginDrag(props) { + return { + index: props.index, + } + } +} + +const ColTarget = { + drop(props, monitor) { + const dragIndex = monitor.getItem().index + const hoverIndex = props.index + + if (dragIndex === undefined || hoverIndex === undefined || dragIndex === hoverIndex) { + return + } + + props.moveCol(dragIndex, hoverIndex) + monitor.getItem().index = hoverIndex + }, +} + +const DragableHeaderCol = DropTarget('col', ColTarget, connect => ({ + connectDropTarget: connect.dropTarget() +}))( + DragSource('col', rowSource, connect => ({ + connectDragSource: connect.dragSource(), + }))(HeaderCol), +) + +class EditableColumnCell extends Component { + updateCard = (vals, btn) => { + const { column } = this.props + this.props.upComponent({...column, elements: vals}, btn) + } + + shouldComponentUpdate (nextProps, nextState) { + const { config, column } = this.props + + if (!nextProps.column) return true + + return !is(fromJS(column), fromJS(nextProps.column)) || + !is(fromJS(config.columns), fromJS(nextProps.config.columns)) || + !is(fromJS(config.action), fromJS(nextProps.config.action)) || + !is(fromJS(config.search), fromJS(nextProps.config.search)) + } + + render() { + const { column, config, children, className, style } = this.props + + if (column && column.type === 'custom') { + return ( + <td style={{padding: 0, minWidth: column.Width || 100, ...(column.style || {})}} className={className}> + <CardCellComponent cards={config} cardCell={column} elements={column.elements} updateElement={this.updateCard}/> + </td> + ) + } else if (column && column.type === 'action') { + return ( + <td style={{padding: '0 5px', textAlign: column.Align, minWidth: column.Width || 100}} className={'action-column ' + className}> + <CardCellComponent cards={config} cardCell={column} elements={column.elements} updateElement={this.updateCard}/> + </td> + ) + } else if (column) { + return ( + <td style={{...style, minWidth: column.Width || 100}} className={className}> + {column.field || (column.type === 'index' ? '$Index' : '')} + {column.Hide === 'true' ? <Icon style={{marginLeft: '5px', color: 'orange', fontSize: '12px'}} type="close-circle" /> : null} + {column.marks && column.marks.length ? <Icon className="profile" type="ant-design"/> : null} + </td> + ) + } else { + return ( + <td style={style} className={className}> + {children} + </td> + ) + } + } +} + +class NormalTableColumns extends Component { + static propTpyes = { + config: PropTypes.object, // 閰嶇疆淇℃伅 + updatecolumn: PropTypes.func // 鏁版嵁鍙樺寲 + } + + state = { + dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, + appType: sessionStorage.getItem('appType'), + tableId: '', + data: [{uuid: Utils.getuuid()}], + refresh: false, // 寮哄埗鍒锋柊 + columns: [], + fields: [], + editStyleCard: null, + lineMarks: [] + } + + UNSAFE_componentWillMount () { + const { config } = this.props + + let tableId = (() => { + let uuid = [] + let _options = 'abcdefghigklmnopqrstuv' + for (let i = 0; i < 19; i++) { + uuid.push(_options.substr(Math.floor(Math.random() * 0x20), 1)) + } + return uuid.join('') + }) () + + if (config.wrap && config.wrap.borderColor) { // 杈规棰滆壊 + let style = `#${tableId} table, #${tableId} tr, #${tableId} th, #${tableId} td {border-color: ${config.wrap.borderColor}}` + let ele = document.createElement('style') + ele.innerHTML = style + document.getElementsByTagName('head')[0].appendChild(ele) + } + + this.setState({ + tableId, + columns: fromJS(config.cols).toJS(), + fields: fromJS(config.columns).toJS(), + lineMarks: config.lineMarks ? fromJS(config.lineMarks).toJS() : [] + }) + } + + UNSAFE_componentWillReceiveProps (nextProps) { + if (!is(fromJS(this.state.columns), fromJS(nextProps.config.cols))) { + let _columns = fromJS(nextProps.config.cols).toJS() + this.setState({columns: _columns}) + let lastcol = _columns.slice(-1)[0] + if (lastcol && lastcol.focus) { + this.editColumn(lastcol) + } + } else if (!is(fromJS(this.state.fields), fromJS(nextProps.config.columns))) { + this.setState({fields: fromJS(nextProps.config.columns).toJS()}) + } else if (this.props.config.wrap.borderColor !== nextProps.config.wrap.borderColor) { + let style = `#${this.state.tableId} table, #${this.state.tableId} tr, #${this.state.tableId} th, #${this.state.tableId} td {border-color: ${nextProps.config.wrap.borderColor}}` + let ele = document.createElement('style') + ele.innerHTML = style + document.getElementsByTagName('head')[0].appendChild(ele) + } + } + + shouldComponentUpdate (nextProps, nextState) { + const { config } = this.props + + return !is(fromJS(this.state), fromJS(nextState)) || + !is(fromJS(config.wrap), fromJS(nextProps.config.wrap)) || + !is(fromJS(config.search), fromJS(nextProps.config.search)) || + !is(fromJS(config.action), fromJS(nextProps.config.action)) || + config.setting.laypage !== nextProps.config.setting.laypage + } + + moveCol = (dragIndex, hoverIndex) => { + let _columns = fromJS(this.state.columns).toJS() + + _columns.splice(hoverIndex, 0, ..._columns.splice(dragIndex, 1)) + + this.setState({ + columns: _columns + }, () => { + this.props.updatecolumn({...this.props.config, cols: _columns}) + }) + } + + loopCol = (columns, col) => { + return columns.map(column => { + if (column.type === 'colspan') { + column.subcols = this.loopCol(column.subcols, col) + } + if (column.uuid === col.uuid) { + return col + } + return column + }) + } + + updateCol = (col, btn) => { + let _columns = fromJS(this.state.columns).toJS() + _columns = this.loopCol(_columns, col) + + this.setState({ + columns: _columns, + }, () => { + let config = {...this.props.config, cols: _columns} + if (btn) { + config.action = config.action.filter(item => item.uuid !== btn.uuid) + } + + this.props.updatecolumn(config) + }) + } + + editColumn = (col) => { + this.setState({ + card: fromJS(col).toJS() + }) + } + + addElement = (col) => { + const { config } = this.props + let column = fromJS(col).toJS() + + if (column.type === 'colspan') { + column.subcols = column.subcols || [] + let subcol = { isSub: true, focus: true, uuid: Utils.getuuid(), label: 'label', field: '', type: 'text' } + column.subcols.push(subcol) + + this.setState({ + card: subcol + }) + this.updateCol(column) + } else if (column.type === 'custom') { + let newcard = {uuid: Utils.getuuid(), focus: true, eleType: 'text', datatype: 'dynamic', style: {paddingLeft: '4px'}} + + // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌 + MKEmitter.emit('cardAddElement', [config.uuid, column.uuid], newcard) + } else if (column.type === 'action') { + let newcard = { + uuid: Utils.getuuid(), + focus: true, + eleType: 'button', + label: 'button', + OpenType: 'prompt', + class: 'primary', + intertype: 'system', + execSuccess: 'grid', + execError: 'never', + show: 'link', + $type: 'tableButton' + } + + // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌 + MKEmitter.emit('cardAddElement', [config.uuid, column.uuid], newcard) + } + } + + submitCol = (col) => { + const { card } = this.state + + col.uuid = card.uuid + col.isSub = card.isSub === true + col.marks = card.marks || [] + + if (col.type === 'colspan') { + col.subcols = card.subcols || [] + } else if (col.type === 'custom') { + col.elements = card.type === 'custom' ? (card.elements || []) : [] + } else if (col.type === 'action') { + col.elements = card.type === 'action' ? (card.elements || []) : [] + } + + this.setState({card: null}) + this.updateCol(col) + } + + changeStyle = (col) => { + this.setState({ + editStyleCard: fromJS(col).toJS() + }) + + MKEmitter.emit('changeStyle', [col.uuid], ['font', 'padding'], col.style || {}) + } + + getStyle = (comIds, style) => { + const { editStyleCard } = this.state + + if (!editStyleCard || comIds[0] !== editStyleCard.uuid || comIds.length !== 1) return + + let _card = {...editStyleCard, style} + + this.updateCol(_card) + } + + cancelCol = () => { + const { card } = this.state + + if (card.focus) { + this.deleteCol(card) + } + + this.setState({card: null}) + } + + loopDelCol = (columns, col) => { + return columns.filter(column => { + if (column.type === 'colspan') { + column.subcols = this.loopDelCol(column.subcols, col) + } + return column.uuid !== col.uuid + }) + } + + deleteCol = (col) => { + const { appType } = this.state + let _columns = fromJS(this.state.columns).toJS() + + _columns = this.loopDelCol(_columns, col) + + this.setState({ + columns: _columns + }, () => { + this.props.updatecolumn({...this.props.config, cols: _columns}) + }) + + if (col.type !== 'action' || appType === 'mob') return + + let uuids = [] + col.elements && col.elements.forEach(c => { + if (appType === 'pc' && c.OpenType !== 'popview') return + + uuids.push(c.uuid) + }) + + if (uuids.length === 0) return + + MKEmitter.emit('delButtons', uuids) + } + + updateLineMarks = (vals) => { + this.setState({ + lineMarks: vals + }, () => { + this.props.updatecolumn({...this.props.config, lineMarks: vals}) + }) + } + + /** + * @description 鏄剧ず鍒楀鍒� + */ + copycolumn = () => { + const { columns } = this.state + + let oInput = document.createElement('input') + let val = { + copyType: 'cols', + cols: columns.filter(col => !col.origin) + } + + 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' + + message.success('澶嶅埗鎴愬姛銆�') + + document.body.removeChild(oInput) + } + + handlecolumns = (columns, fields, config, isSub) => { + return columns.map((col, index) => { + return { + title: col.label, + dataIndex: col.uuid, + align: col.Align, + sorter: !isSub && col.IsSort === 'true', + onCell: () => ({ + column: col, + width: col.Width, + config: config, + upComponent: this.updateCol + }), + onHeaderCell: () => ({ + index: isSub ? undefined : index, + column: col, + fields: fields, + align: col.Align, + moveCol: this.moveCol, + updateCol: this.updateCol, + addElement: this.addElement, + editColumn: this.editColumn, + changeStyle: this.changeStyle, + deleteCol: this.deleteCol, + }), + children: col.subcols && col.subcols.length ? this.handlecolumns(col.subcols, fields, config, true) : null, + } + }) + } + + syncfield = () => { + const { fields } = this.state + let columns = fromJS(this.state.columns).toJS() + + columns = columns.filter(c => !c.origin) + + let keys = columns.map(col => col.field) + + fields.forEach(item => { + if (keys.includes(item.field)) return + + let cell = { uuid: Utils.getuuid(), label: item.label, field: item.field, Align: 'left', Hide: 'false', IsSort: 'true', Width: 120, blacklist: [], postfix: '', prefix: '', linkmenu: [], marks: [], perspective: 'linkmenu' } + + if (/Nvarchar/ig.test(item.datatype)) { + cell.type = 'text' + cell.rowspan = 'false' + cell.textFormat = 'none' + } else { + cell.type = 'number' + cell.format = 'none' + cell.sum = 'false' + cell.decimal = item.decimal || 0 + } + + columns.push(cell) + }) + + const _this = this + + confirm({ + content: '纭畾鍚屾瀛楁闆嗗悧锛�', + onOk() { + _this.setState({columns}, () => { + _this.props.updatecolumn({..._this.props.config, cols: columns}) + }) + }, + onCancel() {} + }) + } + + clear = () => { + const _this = this + + confirm({ + content: '纭畾娓呯┖鏄剧ず鍒楀悧锛�', + onOk() { + _this.setState({columns: []}, () => { + _this.props.updatecolumn({..._this.props.config, cols: []}) + }) + }, + onCancel() {} + }) + } + + componentDidMount () { + MKEmitter.addListener('submitStyle', this.getStyle) + } + + /** + * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆 + */ + componentWillUnmount () { + this.setState = () => { + return + } + MKEmitter.removeListener('submitStyle', this.getStyle) + } + + render() { + const { config } = this.props + const { fields, card, lineMarks, dict, tableId } = this.state + const components = { + header: { + cell: DragableHeaderCol + }, + body: { + cell: EditableColumnCell + } + } + + const columns = this.handlecolumns(this.state.columns, fields, config) + + let style = {} + if (config.wrap.color) { + style.color = config.wrap.color + } + if (config.wrap.fontSize) { + style.fontSize = config.wrap.fontSize + } + + return ( + <div className={`normal-table-columns ${config.setting.laypage} ${config.wrap.tableType} ${config.wrap.mode || ''}`} id={tableId}> + <div className="col-control"> + <Icon title="澶嶅埗鏄剧ず鍒�" type="copy" onClick={this.copycolumn} /> + <MarkColumn columns={fields} type="line" marks={lineMarks} onSubmit={this.updateLineMarks} /> + <Icon title="鍚屾瀛楁闆�" type="file-sync" onClick={this.syncfield} /> + <Icon title="娓呯┖鏄剧ず鍒�" type="delete" onClick={this.clear}/> + </div> + <DndProvider> + <Table + rowKey="uuid" + size={config.wrap.size || 'middle'} + rowClassName="editable-row" + style={style} + bordered={config.wrap.bordered !== 'false'} + components={components} + dataSource={this.state.data} + rowSelection={config.wrap.tableType ? { type: 'radio' } : null} + columns={columns} + pagination={{ + current: 1, + pageSize: 10, + pageSizeOptions: ['10', '25', '50', '100', '500', '1000'], + showSizeChanger: true, + total: 58, + showTotal: (total, range) => `${range[0]}-${range[1]} 鍏� ${total} 鏉 + }} + /> + </DndProvider> + <EditColumn column={card} dict={dict} fields={fields} submitCol={this.submitCol} cancelCol={this.cancelCol}/> + </div> + ) + } +} + +export default NormalTableColumns \ No newline at end of file diff --git a/src/menu/components/table/edit-table/columns/index.scss b/src/menu/components/table/edit-table/columns/index.scss new file mode 100644 index 0000000..f376b55 --- /dev/null +++ b/src/menu/components/table/edit-table/columns/index.scss @@ -0,0 +1,124 @@ +.normal-table-columns { + position: relative; + .ant-table { + color: inherit; + font-size: inherit; + } + .ant-table-body { + overflow-x: auto; + tr { + td { + background: #ffffff; + } + td:not(.ant-table-selection-column) { + position: relative; + padding: 12px 8px; + >.profile { + position: absolute; + top: 2px; + right: 2px; + color: purple; + font-size: 12px; + } + } + } + .action-column { + .card-detail-row:empty { + min-height: 40px; + } + } + tr:hover td { + background: #ffffff!important; + } + } + + .ant-table-thead { + th { + position: relative; + .ant-table-column-sorter::before { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + content: ''; + } + } + > tr > th { + padding: 12px 8px; + .ant-table-column-sorter .ant-table-column-sorter-inner { + .ant-table-column-sorter-up.on, .ant-table-column-sorter-down.on { + color: unset; + } + } + } + } + .col-control { + position: absolute; + z-index: 2; + right: 0; + top: -25px; + >i, >div > i { + font-size: 16px; + margin-right: 10px; + cursor: pointer; + } + >.anticon-copy { + color: #26C281; + } + >.anticon-delete { + color: #ff4d4f; + } + >.anticon-file-sync { + color: #1890ff; + } + >div >.profile { + color: purple; + } + } + .ant-table-small > .ant-table-content > .ant-table-body { + margin: 0; + } +} +.normal-table-columns.false { + .ant-pagination { + display: none; + } +} +.normal-table-columns.checkbox { + .ant-radio-inner { + border-radius: 0; + } + .ant-radio-inner::after { + border-radius: 0; + } + .ant-radio-checked::after { + border-radius: 0; + } +} + +.normal-table-columns.ghost { + .ant-table-thead > tr { + > th { + color: inherit; + background: transparent; + .ant-table-column-sorter .ant-table-column-sorter-inner { + color: inherit; + } + } + > th:hover { + background: transparent; + } + } + .ant-table-body { + overflow-x: auto; + tr { + td { + background: transparent; + } + } + tr:hover td { + background: transparent!important; + } + } +} diff --git a/src/menu/components/table/edit-table/index.jsx b/src/menu/components/table/edit-table/index.jsx new file mode 100644 index 0000000..00d7aac --- /dev/null +++ b/src/menu/components/table/edit-table/index.jsx @@ -0,0 +1,422 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Icon, Popover, notification } from 'antd' + +import asyncComponent from '@/utils/asyncComponent' +import asyncIconComponent from '@/utils/asyncIconComponent' +import { resetStyle } from '@/utils/utils-custom.js' +import MKEmitter from '@/utils/events.js' +import getWrapForm from './options' +import Utils from '@/utils/utils.js' +import zhCN from '@/locales/zh-CN/model.js' +import enUS from '@/locales/en-US/model.js' + +import './index.scss' + +const SettingComponent = asyncIconComponent(() => import('@/menu/datasource')) +const NormalForm = asyncIconComponent(() => import('@/components/normalform')) +const SearchComponent = asyncComponent(() => import('@/templates/sharecomponent/searchcomponent')) +const ActionComponent = asyncComponent(() => import('@/menu/components/share/actioncomponent')) +const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader')) +const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent')) +const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent')) +const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent')) +const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent')) +const ColumnComponent = asyncComponent(() => import('./columns')) + +class TableCardEditComponent extends Component { + static propTpyes = { + card: PropTypes.object, + deletecomponent: PropTypes.func, + updateConfig: PropTypes.func, + } + + state = { + dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, + appType: sessionStorage.getItem('appType'), + card: null, + back: false + } + + UNSAFE_componentWillMount () { + const { card } = this.props + + if (card.isNew) { + let _card = { + uuid: card.uuid, + type: card.type, + floor: card.floor, + tabId: card.tabId || '', + parentId: card.parentId || '', + format: 'array', // 缁勪欢灞炴�� - 鏁版嵁鏍煎紡 + pageable: true, // 缁勪欢灞炴�� - 鏄惁鍙垎椤� + switchable: true, // 缁勪欢灞炴�� - 鏁版嵁鏄惁鍙垏鎹� + dataName: card.dataName || '', + width: card.width || 24, + search: [], + action: [], + name: card.name, + subtype: card.subtype, + setting: { interType: 'system' }, + wrap: { name: card.name, width: card.width || 24, bordered: 'true', tableType: 'checkbox', show: 'true' }, + style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' }, + headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' }, + columns: [], + cols: [ + { origin: true, uuid: Utils.getuuid(), Align: 'left', label: 'label1', field: '', Hide: 'false', type: 'text', Width: 120 }, + { origin: true, uuid: Utils.getuuid(), Align: 'left', label: 'label2', field: '', Hide: 'false', IsSort: 'true', type: 'text', Width: 120 }, + { origin: true, uuid: Utils.getuuid(), Align: 'left', label: 'label3', field: '', Hide: 'false', IsSort: 'true', type: 'text', Width: 120 }, + ], + scripts: [], + btnlog: [], + isNew: true + } + + if (card.config) { + let config = fromJS(card.config).toJS() + + _card.wrap = config.wrap + _card.wrap.name = card.name + _card.style = config.style + _card.headerStyle = config.headerStyle + + let oriUids = {} + _card.action = config.action.map(item => { + let _uuid = Utils.getuuid() + oriUids[item.uuid] = _uuid + item.uuid = _uuid + return item + }) + _card.search = config.search.map(item => { + item.uuid = Utils.getuuid() + return item + }) + _card.cols = config.cols.map(col => { + col.uuid = Utils.getuuid() + if (col.type === 'colspan' && col.subcols) { + col = this.loopCol(col) + } else if (col.type === 'custom' && col.elements) { + col.elements = col.elements.map(cell => { + cell.uuid = Utils.getuuid() + return cell + }) + } else if (col.type === 'action' && col.elements) { + col.elements = col.elements.map(cell => { + cell.uuid = Utils.getuuid() + return cell + }) + } + return col + }) + + if (_card.wrap.doubleClick) { + _card.wrap.doubleClick = oriUids[_card.wrap.doubleClick] || '' + } + } + + this.setState({ + card: _card + }) + + this.filterOrigin(_card) + } else { + this.setState({ + card: fromJS(card).toJS() + }) + } + } + + componentDidMount () { + MKEmitter.addListener('submitStyle', this.getStyle) + MKEmitter.addListener('submitModal', this.handleSave) + MKEmitter.addListener('logButton', this.logButton) + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + /** + * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆 + */ + componentWillUnmount () { + this.setState = () => { + return + } + MKEmitter.removeListener('submitStyle', this.getStyle) + MKEmitter.removeListener('submitModal', this.handleSave) + MKEmitter.removeListener('logButton', this.logButton) + } + + loopCol = (col) => { + col.subcols = col.subcols.map(c => { + c.uuid = Utils.getuuid() + if (c.type === 'colspan' && c.subcols) { + c = this.loopCol(c) + } else if (c.type === 'custom' && c.elements) { + c.elements = c.elements.map(cell => { + cell.uuid = Utils.getuuid() + return cell + }) + } + return c + }) + + return col + } + + filterOrigin = (component) => { + if (component.isNew) { + let item = fromJS(component).toJS() + item.search = item.search.filter(a => !a.origin) + item.action = item.action.filter(a => !a.origin) + item.cols = item.cols.filter(a => !a.origin) + + delete item.isNew + + this.props.updateConfig(item) + } else { + this.props.updateConfig(component) + } + } + + /** + * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級 + */ + updateComponent = (component) => { + this.setState({ + card: component + }) + + component.width = component.wrap.width + component.name = component.wrap.name + + this.filterOrigin(component) + } + + logButton = (id, item) => { + const { card } = this.state + + if (id !== card.uuid) return + + let btnlog = card.btnlog || [] + btnlog.push(item) + + this.setState({ + card: {...card, btnlog} + }) + this.filterOrigin({...card, btnlog}) + } + + changeStyle = () => { + const { card } = this.state + + MKEmitter.emit('changeStyle', [card.uuid], ['background', 'border', 'padding', 'margin', 'shadow'], card.style) + } + + getStyle = (comIds, style) => { + const { card } = this.state + + if (comIds[0] !== card.uuid) return + + let _card = {} + if (comIds.length === 1) { + _card = {...card, style} + } else { + return + } + + this.setState({ + card: _card + }) + + this.filterOrigin(_card) + } + + addColumns = () => { + let card = fromJS(this.state.card).toJS() + + card.cols.push({ focus: true, uuid: Utils.getuuid(), label: 'label', field: '', type: 'text' }) + + this.setState({card}) + } + + addSearch = () => { + let card = fromJS(this.state.card).toJS() + + card.search.push({uuid: Utils.getuuid(), focus: true, label: 'label', type: 'text', match: '='}) + + this.setState({card}) + } + + addButton = () => { + const { card } = this.state + + let newcard = {} + newcard.uuid = Utils.getuuid() + newcard.focus = true + + newcard.label = 'label' + newcard.sqlType = '' + newcard.Ot = 'requiredSgl' + newcard.OpenType = 'pop' + newcard.icon = '' + newcard.class = 'green' + newcard.intertype = card.setting.interType || 'system' + newcard.innerFunc = card.setting.innerFunc || '' + newcard.sysInterface = card.setting.sysInterface || '' + newcard.outerFunc = card.setting.outerFunc || '' + newcard.interface = card.setting.interface || '' + newcard.execSuccess = 'grid' + newcard.execError = 'never' + newcard.verify = null + newcard.show = 'button' + newcard.style = {marginRight: '15px'} + + // 娉ㄥ唽浜嬩欢-娣诲姞鎸夐挳 + MKEmitter.emit('addButton', card.uuid, newcard) + } + + /** + * @description 鏇存柊鎼滅储鏉′欢閰嶇疆淇℃伅 + */ + updateconfig = (config) => { + this.setState({ + card: config + }) + this.filterOrigin(config) + } + + setSubConfig = (item) => { + const { card, appType } = this.state + let btn = fromJS(item).toJS() + + if (btn.OpenType === 'pop' || btn.execMode === 'pop') { + if (!btn.modal) { + btn.modal = { + setting: { title: btn.label, width: appType === 'mob' ? 100 : 60, cols: '2', container: 'view', focus: '', finish: 'close', clickouter: 'unclose', display: 'modal' }, + tables: [], + groups: [], + fields: [] + } + } + MKEmitter.emit('changeModal', card, btn) + } else if (btn.OpenType === 'popview') { + MKEmitter.emit('changePopview', card, btn) + } + } + + handleSave = (_cards, btn, modal) => { + let card = fromJS(this.state.card).toJS() + + if (card.uuid !== _cards.uuid) return + + let _index = card.action.findIndex(cell => cell.uuid === btn.uuid) + + if (_index === -1) return + + card.action = card.action.map(cell => { + if (cell.uuid === btn.uuid) { + cell.modal = modal + } + + return cell + }) + + this.setState({card}) + this.filterOrigin(card) + } + + handleLog = (type, logs, item) => { + let card = fromJS(this.state.card).toJS() + + if (type === 'revert') { + let done = false + if (item.$parentId) { + card.cols.forEach(col => { + if (col.type !== 'action') return + if (item.$parentId === col.uuid) { + col.elements = col.elements ? [...col.elements, item] : [item] + done = true + } + }) + } + + if (!done) { + card.action = card.action ? [...card.action, item] : [item] + } + + card.btnlog = logs + + this.setState({ card }) + this.filterOrigin(card) + notification.success({ + top: 92, + message: '鎭㈠鎴愬姛锛�', + duration: 2 + }) + } else { + card.btnlog = logs + this.setState({ card }) + this.filterOrigin(card) + notification.success({ + top: 92, + message: '娓呴櫎鎴愬姛锛�', + duration: 2 + }) + } + } + + getWrapForms = () => { + const { wrap, action } = this.state.card + + return getWrapForm(wrap, action) + } + + updateWrap = (res) => { + this.updateComponent({...this.state.card, wrap: res}) + } + + clickComponent = (e) => { + if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') { + e.stopPropagation() + MKEmitter.emit('clickComponent', this.state.card) + } + } + + render() { + const { card, appType } = this.state + let _style = resetStyle(card.style) + + return ( + <div className="menu-normal-table-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}> + <NormalHeader defaultshow="hidden" hideSearch="true" config={card} updateComponent={this.updateComponent}/> + <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ + <div className="mk-popover-control"> + <Icon className="plus" title="娣诲姞鍒�" onClick={this.addColumns} type="plus" /> + {appType !== 'mob' ? <Icon className="plus" title="娣诲姞鎼滅储" onClick={this.addSearch} type="plus-circle" /> : null} + <Icon className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton} type="plus-square" /> + <NormalForm title="琛ㄦ牸璁剧疆" width={800} update={this.updateWrap} getForms={this.getWrapForms}> + <Icon type="edit" style={{color: '#1890ff'}} title="缂栬緫"/> + </NormalForm> + <CopyComponent type="normaltable" card={card}/> + <PasteComponent config={card} options={['action', 'search', 'form', 'cols']} updateConfig={this.updateComponent} /> + <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" /> + <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} /> + <UserComponent config={card}/> + <Icon className="close" title="鍒犻櫎缁勪欢" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} /> + <SettingComponent config={card} updateConfig={this.updateComponent} /> + </div> + } trigger="hover"> + <Icon type="tool" /> + </Popover> + <SearchComponent config={card} updatesearch={this.updateconfig}/> + <ActionComponent config={card} setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/> + <ColumnComponent config={card} updatecolumn={this.updateconfig}/> + </div> + ) + } +} + +export default TableCardEditComponent \ No newline at end of file diff --git a/src/menu/components/table/edit-table/index.scss b/src/menu/components/table/edit-table/index.scss new file mode 100644 index 0000000..f933a19 --- /dev/null +++ b/src/menu/components/table/edit-table/index.scss @@ -0,0 +1,80 @@ +.menu-normal-table-edit-box { + position: relative; + box-sizing: border-box; + background: #ffffff; + background-position: center center; + background-repeat: no-repeat; + background-size: cover; + min-height: 100px; + + .model-table-search-list { + padding: 10px 0px 15px; + min-height: 65px; + border-bottom: 1px solid #f0f0f0; + >.anticon-question-circle { + display: none; + } + .page-card { + background: transparent; + } + .quickly-add { + display: inline-block; + position: absolute; + z-index: 3; + right: 70px; + bottom: 5px; + .ant-btn-block { + background-color: transparent; + color: #1890ff; + border: none; + box-shadow: none !important; + height: 18px; + padding: 0 10px; + } + } + } + .model-table-search-list.length0 { + display: none; + } + .anticon-tool { + position: absolute; + z-index: 2; + font-size: 16px; + right: 1px; + top: 1px; + cursor: pointer; + padding: 5px; + background: rgba(255, 255, 255, 0.55); + } + .model-menu-action-list { + line-height: 55px; + padding: 0px; + min-height: 55px; + >.ant-row { + min-height: 30px; + } + } + .card-add-button { + text-align: right; + clear: left; + .anticon-plus { + font-size: 20px; + color: #26C281; + padding: 5px; + margin-right: 10px; + } + } + + .ant-btn.mk-link { + padding: 0; + } +} +.menu-normal-table-edit-box::after { + display: block; + content: ' '; + clear: both; +} +.menu-normal-table-edit-box:hover { + z-index: 1; + box-shadow: 0px 0px 4px #1890ff; +} diff --git a/src/menu/components/table/edit-table/options.jsx b/src/menu/components/table/edit-table/options.jsx new file mode 100644 index 0000000..acfc1be --- /dev/null +++ b/src/menu/components/table/edit-table/options.jsx @@ -0,0 +1,204 @@ +/** + * @description Wrap琛ㄥ崟閰嶇疆淇℃伅 + */ +export default function (wrap, action = []) { + let roleList = sessionStorage.getItem('sysRoles') + let appType = sessionStorage.getItem('appType') + + if (roleList) { + try { + roleList = JSON.parse(roleList) + } catch (e) { + roleList = [] + } + } else { + roleList = [] + } + + const wrapForm = [ + { + type: 'text', + field: 'title', + label: '鏍囬', + initval: wrap.title || '', + required: false + }, + { + type: 'text', + field: 'name', + label: '缁勪欢鍚嶇О', + initval: wrap.name || '', + tooltip: '鐢ㄤ簬缁勪欢闂寸殑鍖哄垎銆�', + required: true + }, + { + type: 'radio', + field: 'tableType', + label: '琛ㄦ牸灞炴��', + initval: wrap.tableType, + required: false, + options: [ + {value: '', label: '涓嶅彲閫�'}, + {value: 'radio', label: '鍗曢��'}, + {value: 'checkbox', label: '澶氶��'}, + ], + controlFields: [ + {field: 'selected', values: ['radio', 'checkbox']}, + ] + }, + { + type: 'radio', + field: 'bordered', + label: '杈规', + initval: wrap.bordered || 'true', + required: false, + options: [ + {value: 'true', label: '鏈�'}, + {value: 'false', label: '鏃�'}, + ] + }, + { + type: 'radio', + field: 'tableHeader', + label: '琛ㄥご', + initval: wrap.tableHeader || 'show', + required: false, + options: [ + {value: 'show', label: '鏄剧ず'}, + {value: 'hidden', label: '闅愯棌'}, + ] + }, + { + type: 'radio', + field: 'size', + label: '琛ㄦ牸澶у皬', + initval: wrap.size || 'middle', + tooltip: '琛ㄦ牸鐨勫唴杈硅窛锛屼粠澶у埌灏忎緷娆¢�掑噺銆�', + required: false, + options: [ + {value: 'default', label: '澶�'}, + {value: 'middle', label: '涓�'}, + {value: 'small', label: '灏�'}, + // {value: 'mini', label: '寰�'}, + ] + }, + { + type: 'radio', + field: 'mode', + label: '妯″紡', + initval: wrap.mode || 'default', + required: false, + options: [ + {value: 'default', label: '甯歌'}, + {value: 'ghost', label: '閫忔槑'}, + ] + }, + { + type: 'radio', + field: 'selected', + label: '棣栬閫変腑', + initval: wrap.selected || 'false', + required: false, + options: [ + {value: 'false', label: '鏃�'}, + {value: 'init', label: '鍒濆鍖�'}, + {value: 'always', label: '鏁版嵁鍔犺浇'}, + ] + }, + { + type: 'radio', + field: 'show', + label: '鎼滅储鎸夐挳', + initval: wrap.show || 'true', + tooltip: '鎼滅储鏉′欢瀛樺湪鏃讹紝鍙�夋嫨鏄惁鏄剧ず鎼滅储鎸夐挳銆�', + required: false, + options: [ + {value: 'true', label: '鏄剧ず'}, + {value: 'false', label: '闅愯棌'}, + ] + }, + { + type: 'color', + field: 'borderColor', + label: '杈规棰滆壊', + initval: wrap.borderColor || '#e8e8e8', + tooltip: '榛樿鍊� #e8e8e8銆�', + required: false + }, + { + type: 'color', + field: 'color', + label: '瀛椾綋棰滆壊', + initval: wrap.color || 'rgba(0, 0, 0, 0.65)', + tooltip: '榛樿鍊� rgba(0, 0, 0, 0.65)銆�', + required: false + }, + { + type: 'number', + field: 'width', + label: '瀹藉害', + initval: wrap.width || 24, + tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��', + min: 1, + max: 24, + precision: 0, + required: true + }, + { + type: 'number', + field: 'fontSize', + label: '瀛椾綋澶у皬', + initval: wrap.fontSize || 14, + min: 12, + max: 30, + precision: 0, + required: false + }, + { + type: 'number', + field: 'height', + label: '楂樺害', + initval: wrap.height || '', + tooltip: '琛ㄦ牸楂樺害锛岀┖鍊兼椂楂樺害鑷�傚簲銆�', + min: 10, + max: 3000, + precision: 0, + required: false, + forbid: appType === 'mob' + }, + { + type: 'number', + field: 'advanceWidth', + label: '楂樼骇鎼滅储', + initval: wrap.advanceWidth || 1000, + tooltip: '楂樼骇鎼滅储寮圭獥鐨勫搴︼紝娉細褰撳搴﹀�煎皬浜�100鏃惰〃绀哄崰绐楀彛鐨勭櫨鍒嗘瘮锛屽ぇ浜�100鏃惰〃绀哄搴︾殑缁濆鍊笺��', + min: 10, + max: 3000, + precision: 0, + required: false, + forbid: appType === 'mob' + }, + { + type: 'select', + field: 'doubleClick', + label: '鍙屽嚮浜嬩欢', + initval: wrap.doubleClick || '', + tooltip: '鍙屽嚮琛ㄦ牸涓锛岃Е鍙戠殑鎸夐挳銆�', + required: false, + allowClear: true, + options: action.map(item => ({value: item.uuid, label: item.label})), + forbid: appType === 'mob' + }, + { + type: 'multiselect', + field: 'blacklist', + label: '榛戝悕鍗�', + initval: wrap.blacklist || [], + required: false, + options: roleList, + forbid: !!appType + }, + ] + + return wrapForm +} \ No newline at end of file diff --git a/src/menu/components/tabs/tabcomponents/card.jsx b/src/menu/components/tabs/tabcomponents/card.jsx index bfc1471..e80787f 100644 --- a/src/menu/components/tabs/tabcomponents/card.jsx +++ b/src/menu/components/tabs/tabcomponents/card.jsx @@ -20,6 +20,7 @@ const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form')) const TabForm = asyncComponent(() => import('@/menu/components/form/tab-form')) const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table')) +const EditTable = asyncComponent(() => import('@/menu/components/table/edit-table')) const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group')) const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor')) const CodeSandbox = asyncComponent(() => import('@/menu/components/code/sandbox')) @@ -88,6 +89,8 @@ return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'table' && card.subtype === 'normaltable') { return (<NormalTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'table' && card.subtype === 'editable') { + return (<EditTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'group' && card.subtype === 'normalgroup') { return (<NormalGroup group={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'editor') { diff --git a/src/menu/menushell/card.jsx b/src/menu/menushell/card.jsx index 327482c..8195ed1 100644 --- a/src/menu/menushell/card.jsx +++ b/src/menu/menushell/card.jsx @@ -18,6 +18,7 @@ const CarouselPropCard = asyncComponent(() => import('@/menu/components/carousel/prop-card')) const TableCard = asyncComponent(() => import('@/menu/components/card/table-card')) const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table')) +const EditTable = asyncComponent(() => import('@/menu/components/table/edit-table')) const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form')) const TabForm = asyncComponent(() => import('@/menu/components/form/tab-form')) const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group')) @@ -88,6 +89,8 @@ return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'table' && card.subtype === 'normaltable') { return (<NormalTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'table' && card.subtype === 'editable') { + return (<EditTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'group' && card.subtype === 'normalgroup') { return (<NormalGroup group={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'editor') { diff --git a/src/menu/modulesource/option.jsx b/src/menu/modulesource/option.jsx index dfdb100..55bebce 100644 --- a/src/menu/modulesource/option.jsx +++ b/src/menu/modulesource/option.jsx @@ -36,7 +36,7 @@ { type: 'menu', url: Carousel, component: 'carousel', subtype: 'datacard', title: '杞挱-鍔ㄦ�佹暟鎹�', width: 24, forbid: ['billPrint'] }, { type: 'menu', url: Carousel1, component: 'carousel', subtype: 'propcard', title: '杞挱-闈欐�佹暟鎹�', width: 24, forbid: ['billPrint'] }, { type: 'menu', url: NormalTable, component: 'table', subtype: 'normaltable', title: '甯哥敤琛�', width: 24 }, - // { type: 'menu', url: NormalTable, component: 'table', subtype: 'normaltable', title: '甯哥敤琛�', width: 24 }, + // { type: 'menu', url: NormalTable, component: 'table', subtype: 'editable', title: '琛ㄦ牸锛堝彲缂栬緫锛�', width: 24 }, { type: 'menu', url: TableCard, component: 'table', subtype: 'tablecard', title: '琛ㄦ牸锛堝崱鐗囷級', width: 12 }, { type: 'menu', url: tree, component: 'tree', subtype: 'normaltree', title: '鏍戝舰鍒楄〃', width: 12 }, { type: 'menu', url: line, component: 'line', subtype: 'line', title: '鎶樼嚎鍥�', width: 24 }, diff --git a/src/pc/menushell/card.jsx b/src/pc/menushell/card.jsx index 6e114c7..45a2108 100644 --- a/src/pc/menushell/card.jsx +++ b/src/pc/menushell/card.jsx @@ -15,6 +15,7 @@ const NormalTree = asyncComponent(() => import('@/menu/components/tree/antd-tree')) const TableCard = asyncComponent(() => import('@/menu/components/card/table-card')) const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table')) +const EditTable = asyncComponent(() => import('@/menu/components/table/edit-table')) const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group')) const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form')) const TabForm = asyncComponent(() => import('@/menu/components/form/tab-form')) @@ -108,6 +109,8 @@ return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'table' && card.subtype === 'normaltable') { return (<NormalTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'table' && card.subtype === 'editable') { + return (<EditTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'group' && card.subtype === 'normalgroup') { return (<NormalGroup group={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'editor') { diff --git a/src/pc/quotecomponent/settingform/index.jsx b/src/pc/quotecomponent/settingform/index.jsx index e575e0d..96a871f 100644 --- a/src/pc/quotecomponent/settingform/index.jsx +++ b/src/pc/quotecomponent/settingform/index.jsx @@ -2,8 +2,6 @@ import PropTypes from 'prop-types' import { Form, Row, Col, Select } from 'antd' -import './index.scss' - class SettingForm extends Component { static propTpyes = { dict: PropTypes.object, // 瀛楀吀椤� diff --git a/src/pc/quotecomponent/settingform/index.scss b/src/pc/quotecomponent/settingform/index.scss index 159130b..e69de29 100644 --- a/src/pc/quotecomponent/settingform/index.scss +++ b/src/pc/quotecomponent/settingform/index.scss @@ -1,11 +0,0 @@ -.model-menu-setting-form { - position: relative; - - .anticon-question-circle { - color: #c49f47; - margin-right: 3px; - } - .ant-input-number { - width: 100%; - } -} \ No newline at end of file diff --git a/src/pc/transfer/index.jsx b/src/pc/transfer/index.jsx index d2fb44e..655e0a9 100644 --- a/src/pc/transfer/index.jsx +++ b/src/pc/transfer/index.jsx @@ -7,7 +7,6 @@ import enUS from '@/locales/en-US/model.js' import SettingForm from './settingform' import Api from '@/api' -import './index.scss' class TransferWrap extends Component { static propTpyes = { diff --git a/src/tabviews/zshare/mutilform/index.jsx b/src/tabviews/zshare/mutilform/index.jsx index 2525408..184bddf 100644 --- a/src/tabviews/zshare/mutilform/index.jsx +++ b/src/tabviews/zshare/mutilform/index.jsx @@ -535,7 +535,7 @@ } resetFormList = (result) => { - let _formlist = this.state.formlist.map(item => { + let _formlist = fromJS(this.state.formlist).toJS().map(item => { if (['select', 'link', 'radio', 'checkbox', 'checkcard', 'multiselect'].includes(item.type) && result[item.field] && result[item.field].length > 0) { let options = [] result[item.field].forEach(cell => { diff --git a/src/tabviews/zshare/mutilform/mkCheckbox/index.jsx b/src/tabviews/zshare/mutilform/mkCheckbox/index.jsx index 12091c4..5742e0b 100644 --- a/src/tabviews/zshare/mutilform/mkCheckbox/index.jsx +++ b/src/tabviews/zshare/mutilform/mkCheckbox/index.jsx @@ -2,8 +2,6 @@ import PropTypes from 'prop-types' import { Checkbox } from 'antd' -import './index.scss' - class MKCheckbox extends Component { static propTpyes = { config: PropTypes.object, diff --git a/src/tabviews/zshare/mutilform/mkDatePicker/index.jsx b/src/tabviews/zshare/mutilform/mkDatePicker/index.jsx index ad7558d..3d4377b 100644 --- a/src/tabviews/zshare/mutilform/mkDatePicker/index.jsx +++ b/src/tabviews/zshare/mutilform/mkDatePicker/index.jsx @@ -3,8 +3,6 @@ import { DatePicker } from 'antd' import moment from 'moment' -import './index.scss' - const { MonthPicker } = DatePicker /** diff --git a/src/tabviews/zshare/mutilform/mkRadio/index.jsx b/src/tabviews/zshare/mutilform/mkRadio/index.jsx index 05efa5d..6ce1ef3 100644 --- a/src/tabviews/zshare/mutilform/mkRadio/index.jsx +++ b/src/tabviews/zshare/mutilform/mkRadio/index.jsx @@ -2,8 +2,6 @@ import PropTypes from 'prop-types' import { Radio } from 'antd' -import './index.scss' - class MKRadio extends Component { static propTpyes = { config: PropTypes.object, diff --git a/src/tabviews/zshare/mutilform/mkSelect/index.jsx b/src/tabviews/zshare/mutilform/mkSelect/index.jsx index 1caeb6f..3e73927 100644 --- a/src/tabviews/zshare/mutilform/mkSelect/index.jsx +++ b/src/tabviews/zshare/mutilform/mkSelect/index.jsx @@ -3,7 +3,6 @@ import { Select } from 'antd' import MKEmitter from '@/utils/events.js' -import './index.scss' class MKSelect extends Component { constructor(props) { @@ -160,6 +159,7 @@ allowClear id={config.uuid} value={value} + dropdownMatchSelectWidth={config.dropdown !== 'false'} filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} onSelect={this.selectChange} onChange={(val) => val === undefined && this.selectChange('')} diff --git a/src/tabviews/zshare/mutilform/mkSwitch/index.jsx b/src/tabviews/zshare/mutilform/mkSwitch/index.jsx index b3eff86..6d3d178 100644 --- a/src/tabviews/zshare/mutilform/mkSwitch/index.jsx +++ b/src/tabviews/zshare/mutilform/mkSwitch/index.jsx @@ -2,8 +2,6 @@ import PropTypes from 'prop-types' import { Switch } from 'antd' -import './index.scss' - class MKSwitch extends Component { static propTpyes = { config: PropTypes.object, diff --git a/src/tabviews/zshare/mutilform/mkTextArea/index.jsx b/src/tabviews/zshare/mutilform/mkTextArea/index.jsx index 04886c9..444d185 100644 --- a/src/tabviews/zshare/mutilform/mkTextArea/index.jsx +++ b/src/tabviews/zshare/mutilform/mkTextArea/index.jsx @@ -3,7 +3,6 @@ import { Input } from 'antd' import MKEmitter from '@/utils/events.js' -import './index.scss' const { TextArea } = Input diff --git a/src/tabviews/zshare/topSearch/index.jsx b/src/tabviews/zshare/topSearch/index.jsx index d2c6e39..c2cf4ad 100644 --- a/src/tabviews/zshare/topSearch/index.jsx +++ b/src/tabviews/zshare/topSearch/index.jsx @@ -366,7 +366,7 @@ } resetSearch = (result) => { - let _searchlist = this.state.searchlist.map(item => { + let _searchlist = fromJS(this.state.searchlist).toJS().map(item => { if (['select', 'link', 'multiselect', 'checkcard'].includes(item.type) && result[item.field] && result[item.field].length > 0) { let options = [] result[item.field].forEach(cell => { @@ -394,23 +394,22 @@ item.oriOptions = [...item.oriOptions, ...options] } + + if (item.type === 'link') { + if (item.supInitVal) { + item.options = item.oriOptions.filter(option => option.ParentID === item.supInitVal || option.Value === '') + } else { + item.options = item.oriOptions + } + } else if (item.type === 'select' || item.type === 'multiselect' || item.type === 'checkcard') { + item.options = item.oriOptions + } + return item }) this.setState({ - searchlist: _searchlist.map(item => { - if (item.type === 'link') { - if (item.supInitVal) { - item.options = item.oriOptions.filter(option => option.ParentID === item.supInitVal || option.Value === '') - } else { - item.options = item.oriOptions - } - } else if (item.type === 'select' || item.type === 'multiselect' || item.type === 'checkcard') { - item.options = item.oriOptions - } - - return item - }) + searchlist: _searchlist }) } diff --git a/src/tabviews/zshare/topSearch/mkDatePicker/index.jsx b/src/tabviews/zshare/topSearch/mkDatePicker/index.jsx index 036049b..4ebc9b2 100644 --- a/src/tabviews/zshare/topSearch/mkDatePicker/index.jsx +++ b/src/tabviews/zshare/topSearch/mkDatePicker/index.jsx @@ -3,8 +3,6 @@ import { DatePicker } from 'antd' import moment from 'moment' -import './index.scss' - const { MonthPicker, WeekPicker, RangePicker } = DatePicker /** diff --git a/src/tabviews/zshare/topSearch/mkSelect/index.jsx b/src/tabviews/zshare/topSearch/mkSelect/index.jsx index 53d6385..a090007 100644 --- a/src/tabviews/zshare/topSearch/mkSelect/index.jsx +++ b/src/tabviews/zshare/topSearch/mkSelect/index.jsx @@ -3,7 +3,6 @@ import { Select } from 'antd' import MKEmitter from '@/utils/events.js' -import './index.scss' class MKSearchSelect extends Component { constructor(props) { @@ -106,6 +105,7 @@ <Select showSearch mode={config.type === 'multiselect' ? 'multiple' : ''} + dropdownMatchSelectWidth={config.dropdown !== 'false'} value={value} filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} onChange={this.selectChange} diff --git a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx index 377235b..e8faf2e 100644 --- a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx +++ b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx @@ -88,9 +88,9 @@ const searchTypeOptions = { text: ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide', 'labelShow', 'inputType', 'advanced'], - select: ['label', 'field', 'resourceType', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide', 'labelShow', 'advanced', 'setAll'], + select: ['label', 'field', 'resourceType', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide', 'labelShow', 'advanced', 'setAll', 'dropdown'], multiselect: ['label', 'field', 'resourceType', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide', 'labelShow', 'advanced'], - link: ['label', 'field', 'resourceType', 'initval', 'type', 'linkField', 'match', 'ratio', 'blacklist', 'required', 'Hide', 'labelShow', 'advanced', 'setAll'], + link: ['label', 'field', 'resourceType', 'initval', 'type', 'linkField', 'match', 'ratio', 'blacklist', 'required', 'Hide', 'labelShow', 'advanced', 'setAll', 'dropdown'], date: ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide', 'labelShow', 'advanced'], checkcard: ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'resourceType', 'display', 'width', 'multiple', 'borderColor', 'required', 'Hide', 'labelShow', 'advanced'], dateweek: ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide', 'labelShow', 'advanced'], diff --git a/src/templates/zshare/formconfig.jsx b/src/templates/zshare/formconfig.jsx index e143d8b..c9c8963 100644 --- a/src/templates/zshare/formconfig.jsx +++ b/src/templates/zshare/formconfig.jsx @@ -746,6 +746,20 @@ }, { type: 'radio', + key: 'dropdown', + label: '涓嬫媺妗�', + initVal: card.dropdown || 'true', + forbid: appType === 'mob', + options: [{ + value: 'true', + text: '瀹氬' + }, { + value: 'false', + text: '鑷�傚簲' + }] + }, + { + type: 'radio', key: 'inputType', label: '杈撳叆鏍峰紡', initVal: card.inputType || 'input', @@ -2783,6 +2797,20 @@ }, { type: 'radio', + key: 'dropdown', + label: '涓嬫媺妗�', + initVal: card.dropdown || 'true', + forbid: appType === 'mob', + options: [{ + value: 'true', + text: '瀹氬' + }, { + value: 'false', + text: '鑷�傚簲' + }] + }, + { + type: 'radio', key: 'hidelabel', label: '闅愯棌鍚嶇О', initVal: card.hidelabel || 'false', diff --git a/src/templates/zshare/modalform/index.jsx b/src/templates/zshare/modalform/index.jsx index aae44be..1e0b392 100644 --- a/src/templates/zshare/modalform/index.jsx +++ b/src/templates/zshare/modalform/index.jsx @@ -18,12 +18,12 @@ const modalTypeOptions = { text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'cursor', 'scan', 'splitline', 'placeholder'], number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'cursor', 'splitline'], - select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline'], + select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline', 'dropdown'], checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'arrange'], radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'setAll', 'emptyText', 'splitline', 'arrange'], checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'fieldlength', 'span', 'labelwidth', 'display', 'tooltip', 'extra', 'width', 'multiple', 'borderColor', 'splitline'], multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra'], - link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkField', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline'], + link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkField', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline', 'dropdown'], fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'span', 'labelwidth', 'tooltip', 'extra', 'compress', 'splitline'], switch: ['initval', 'openVal', 'closeVal', 'openText', 'closeText', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline'], date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'declareType', 'mode', 'splitline'], -- Gitblit v1.8.0