| | |
| | | border-color: $color2; |
| | | } |
| | | } |
| | | .mk-time-line-wrap.system { |
| | | .mk-timeline-item-tail { |
| | | border-color: $color2; |
| | | } |
| | | } |
| | | .custom-tab-form-box .mk-normal-form-title.mkbtn { |
| | | .form-title { |
| | | color: $color6; |
| | |
| | | |
| | | class EditableCell extends Component { |
| | | getInput = (form) => { |
| | | const { inputType, options, min, max, unlimit } = this.props |
| | | const { inputType, options, min, max, unlimit, allowClear } = this.props |
| | | |
| | | if (inputType === 'number' && unlimit) { |
| | | return <InputNumber onPressEnter={() => this.getValue(form)} /> |
| | | } else if (inputType === 'number') { |
| | | return <InputNumber min={min} max={max} precision={0} onPressEnter={() => this.getValue(form)} /> |
| | | } else if (inputType === 'color') { |
| | | return <ColorSketch /> |
| | | return <ColorSketch allowClear={allowClear}/> |
| | | } else if (inputType === 'icon') { |
| | | return <MkEditIcon allowClear/> |
| | | } else if (inputType === 'select') { |
| | |
| | | unlimit: col.unlimit, |
| | | required: col.required !== false ? true : false, |
| | | title: col.title, |
| | | allowClear: col.allowClear === true, |
| | | editing: this.isEditing(record), |
| | | onSave: this.execSave, |
| | | }), |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Form, Select } from 'antd' |
| | | import { Form, Select, Input } from 'antd' |
| | | |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import './index.scss' |
| | |
| | | } |
| | | |
| | | state = { |
| | | background: '', |
| | | backgroundColor: '', |
| | | backgroundImage: '', |
| | | backgroundSize: '', |
| | |
| | | } |
| | | |
| | | this.setState({ |
| | | background: config.style.background || '', |
| | | backgroundColor: config.style.backgroundColor, |
| | | backgroundImage: bgImg, |
| | | backgroundSize: config.style.backgroundSize || '100%', |
| | |
| | | this.props.updateConfig(config) |
| | | } |
| | | |
| | | changeBackground = (val) => { |
| | | this.setState({ |
| | | background: val, |
| | | }) |
| | | |
| | | if (!val || /(^linear-gradient|^radial-gradient)\(.*\)$/.test(val)) { |
| | | let config = fromJS(this.props.config).toJS() |
| | | config.style.background = val |
| | | |
| | | delete config.style.backgroundColor |
| | | delete config.style.backgroundImage |
| | | |
| | | if (!val) { |
| | | delete config.style.background |
| | | } |
| | | |
| | | this.setState({ |
| | | backgroundImage: '', |
| | | backgroundColor: '' |
| | | }) |
| | | |
| | | this.props.updateConfig(config) |
| | | } |
| | | } |
| | | |
| | | render () { |
| | | const { backgroundColor, backgroundImage, backgroundSize, backgroundRepeat } = this.state |
| | | const { backgroundColor, backgroundImage, backgroundSize, backgroundRepeat, background } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | |
| | | <Form.Item className="color-control" colon={false} label="颜色"> |
| | | <ColorSketch value={backgroundColor} onChange={this.changeBackgroundColor} /> |
| | | </Form.Item> |
| | | {window.develop === true ? <Form.Item colon={false} label="颜色"> |
| | | <Input value={background} onChange={(e) => this.changeBackground(e.target.value)} /> |
| | | </Form.Item> : null} |
| | | <Form.Item colon={false} label="图片"> |
| | | <SourceComponent value={backgroundImage} type="" placement="right" onChange={this.imgChange}/> |
| | | </Form.Item> |
| | |
| | | title="节点组" |
| | | wrapClassName="nodes-field-modal" |
| | | visible={visible} |
| | | width={900} |
| | | width={950} |
| | | maskClosable={false} |
| | | onOk={this.submit} |
| | | onCancel={() => { this.setState({ visible: false })}} |
| | |
| | | <Col span={8}> |
| | | <Form.Item label="颜色"> |
| | | {getFieldDecorator('color', { |
| | | initialValue: '', |
| | | initialValue: '#e8e8e8', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | |
| | | editable: true, |
| | | unique: true, |
| | | required: false, |
| | | width: '35%' |
| | | width: '25%' |
| | | }, |
| | | { |
| | | title: '颜色', |
| | |
| | | inputType: 'color', |
| | | editable: true, |
| | | required: true, |
| | | width: '35%' |
| | | width: '25%', |
| | | render: (text, record) => <span style={{display: 'inline-block', width: '40px', height: '25px', background: text}}></span> |
| | | }, |
| | | { |
| | | title: '图标', |
| | |
| | | inputType: 'icon', |
| | | editable: true, |
| | | required: false, |
| | | width: '35%', |
| | | width: '25%', |
| | | render: (text, record) => record.icon ? <MkIcon type={record.icon}/> : '' |
| | | } |
| | | }, |
| | | { |
| | | title: '连接线', |
| | | dataIndex: 'linecolor', |
| | | inputType: 'color', |
| | | editable: true, |
| | | required: false, |
| | | allowClear: true, |
| | | width: '25%', |
| | | render: (text, record) => text ? <span style={{display: 'inline-block', width: '40px', height: '25px', background: text}}></span> : null |
| | | }, |
| | | ] |
| | | } |
| | | |
| | |
| | | return ( |
| | | <div style={{minHeight: '250px'}}> |
| | | <ColumnForm menus={menus} columnChange={this.columnChange}/> |
| | | <p style={{position: 'absolute', fontSize: '12px', transform: 'translate(0px, -20px)'}}>连接线在横向时间轴中有效</p> |
| | | <EditTable actions={['edit', 'move', 'copy', 'del']} type={'timenodes'} data={menus} columns={columns} onChange={this.changeColumns}/> |
| | | </div> |
| | | ) |
| | |
| | | name: card.name, |
| | | subtype: card.subtype, |
| | | setting: { interType: 'system' }, |
| | | wrap: { title: '', name: card.name, width: card.width || 24, color: '#1890ff', mode: 'left' }, |
| | | wrap: { title: '', name: card.name, direction: 'vertical', width: card.width || 24, color: '#1890ff', mode: 'left' }, |
| | | style: { marginLeft: '0px', marginRight: '0px', marginTop: '0px', marginBottom: '0px' }, |
| | | subcards: [{ |
| | | uuid: Utils.getuuid(), |
| | |
| | | |
| | | updateWrap = (res) => { |
| | | delete res.quick |
| | | |
| | | if (res.hmode) { |
| | | res.mode = res.hmode |
| | | delete res.hmode |
| | | } |
| | | |
| | | this.updateComponent({...this.state.card, wrap: res}) |
| | | } |
| | | |
| | |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'direction', |
| | | label: '轴线方向', |
| | | initval: wrap.direction || 'vertical', |
| | | required: false, |
| | | options: [ |
| | | {value: 'vertical', label: '纵向'}, |
| | | {value: 'horizontal', label: '横向'}, |
| | | ], |
| | | controlFields: [ |
| | | {field: 'mode', values: ['vertical']}, |
| | | {field: 'hmode', values: ['horizontal']}, |
| | | {field: 'label', values: ['vertical']}, |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'mode', |
| | | label: '轴线位置', |
| | | initval: wrap.mode || 'left', |
| | | initval: ['left', 'alternate', 'right'].includes(wrap.mode) ? wrap.mode : 'left', |
| | | required: false, |
| | | options: [ |
| | | {value: 'left', label: '左侧'}, |
| | |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'reverse', |
| | | label: '排序', |
| | | initval: wrap.reverse || 'false', |
| | | field: 'hmode', |
| | | label: '轴线位置', |
| | | initval: ['up', 'down'].includes(wrap.mode) ? wrap.mode : 'up', |
| | | required: false, |
| | | options: [ |
| | | {value: 'false', label: '正序'}, |
| | | {value: 'true', label: '倒序'}, |
| | | {value: 'up', label: '上侧'}, |
| | | {value: 'down', label: '下侧'} |
| | | ] |
| | | }, |
| | | // { |
| | | // type: 'radio', |
| | | // field: 'reverse', |
| | | // label: '排序', |
| | | // initval: wrap.reverse || 'false', |
| | | // required: false, |
| | | // options: [ |
| | | // {value: 'false', label: '正序'}, |
| | | // {value: 'true', label: '倒序'}, |
| | | // ] |
| | | // }, |
| | | { |
| | | type: 'color', |
| | | field: 'color', |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Collapse, Form, Col, InputNumber, Select, Radio, Drawer, Button } from 'antd' |
| | | import { Collapse, Form, Col, InputNumber, Input, Select, Radio, Drawer, Button } from 'antd' |
| | | import { |
| | | ColumnHeightOutlined, |
| | | FontSizeOutlined, |
| | |
| | | */ |
| | | changeBackgroundColor = (val) => { |
| | | this.updateStyle({backgroundColor: val}) |
| | | } |
| | | |
| | | changeBackground = (val) => { |
| | | const { comIds, card } = this.state |
| | | |
| | | let _style = { ...card } |
| | | |
| | | _style.background = val |
| | | |
| | | delete _style.backgroundColor |
| | | delete _style.backgroundImage |
| | | |
| | | if (!val) { |
| | | delete _style.background |
| | | } |
| | | |
| | | this.setState({ |
| | | card: _style, |
| | | }) |
| | | |
| | | if (!val || /(^linear-gradient|^radial-gradient)\(.*\)$/.test(val)) { |
| | | MKEmitter.emit('submitStyle', comIds, _style) |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | <ColorSketch value={card.backgroundColor || '#ffffff'} onChange={this.changeBackgroundColor} /> |
| | | </Form.Item> |
| | | </Col> |
| | | {window.develop === true ? <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<BgColorsOutlined title="背景颜色"/>} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | <Input value={card.background || ''} onChange={(e) => this.changeBackground(e.target.value)} /> |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {!options.includes('backgroundColor') ? <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | |
| | | margin-bottom: 0; |
| | | } |
| | | } |
| | | .am-tab-bar-tab.tab-zoomIn { |
| | | .am-tab-bar-tab-icon { |
| | | padding: 10px; |
| | | display: inline-block; |
| | | background: #1890ff; |
| | | color: #ffffff; |
| | | border-radius: 40px; |
| | | width: 42px; |
| | | height: 42px; |
| | | font-size: 15px; |
| | | transform: translate(0px, -25px); |
| | | } |
| | | .am-tab-bar-tab-title { |
| | | font-size: 1.2em; |
| | | color: #1890ff; |
| | | transform: translate(0px, -22px); |
| | | } |
| | | } |
| | | } |
| | | |
| | | .anticon-tool { |
| | |
| | | <CloseOutlined className="close" title="删除" onClick={() => delCard(id)} /> |
| | | </div> |
| | | } trigger="hover"> |
| | | <div ref={node => drag(drop(node))} className="am-tab-bar-tab" style={{opacity: isDragging ? 0 : 1}} onDoubleClick={doubleClickCard}> |
| | | <div ref={node => drag(drop(node))} className={'am-tab-bar-tab tab-' + (card.class || 'default')} style={{opacity: isDragging ? 0 : 1}} onDoubleClick={doubleClickCard}> |
| | | {card.icon ? <div className="am-tab-bar-tab-icon"> |
| | | <span className="am-badge am-tab-bar-tab-badge tab-badge"> |
| | | <MkIcon type={card.icon} /> |
| | |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | {property === 'menu' || property === 'linkmenu' ? <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="替换当前页面或打开新页面,在H5或小程序中有效。"> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | 打开方式 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('open', { |
| | | initialValue: menu.open || 'self' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="self">标签页</Radio> |
| | | <Radio value="blank">新页面</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {property === 'link' ? <Col span={24}> |
| | | <Form.Item label="链接地址" className="textarea"> |
| | | {getFieldDecorator('link', { |
| | |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="在H5或小程序中有效。"> |
| | | <QuestionCircleOutlined className="mk-form-tip" /> |
| | | 菜单样式 |
| | | </Tooltip> |
| | | }> |
| | | {getFieldDecorator('class', { |
| | | initialValue: menu.class || 'default' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="default">默认</Radio> |
| | | <Radio value="zoomIn">放大</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | ) |
| | |
| | | </Timeline.Item>) |
| | | } |
| | | |
| | | getMknodes = (data) => { |
| | | const { config, card } = this.state |
| | | |
| | | let color = config.wrap.color |
| | | let dot = '' |
| | | let linebg = {} |
| | | if (config.wrap.node && card.nodes && card.nodes.length > 0) { |
| | | let sign = data[config.wrap.node] |
| | | card.nodes.some(item => { |
| | | if (sign === item.sign) { |
| | | color = item.color |
| | | |
| | | if (item.icon) { |
| | | dot = <MkIcon type={item.icon}/> |
| | | } |
| | | |
| | | if (item.linecolor) { |
| | | linebg = {borderColor: item.linecolor} |
| | | } |
| | | return true |
| | | } |
| | | return false |
| | | }) |
| | | } |
| | | |
| | | if (config.wrap.mode === 'down') { |
| | | return (<div className="mk-time-line-item" key={data.$Index}> |
| | | <div className="mk-timeline-item-content"> |
| | | <div className="card-item-box" style={card.style}> |
| | | <CardCellComponent data={data} cards={config} cardCell={card} elements={card.elements}/> |
| | | </div> |
| | | </div> |
| | | <div className="mk-timeline-item-head"> |
| | | <div className="mk-timeline-item-tail" style={linebg}></div> |
| | | <div className={'mk-dot ' + (dot ? 'mk-dot-icon' : '')} style={{background: color}}> |
| | | {dot} |
| | | </div> |
| | | </div> |
| | | </div>) |
| | | } else { |
| | | return (<div className="mk-time-line-item" key={data.$Index}> |
| | | <div className="mk-timeline-item-head"> |
| | | <div className="mk-timeline-item-tail" style={linebg}></div> |
| | | <div className={'mk-dot ' + (dot ? 'mk-dot-icon' : '')} style={{background: color}}> |
| | | {dot} |
| | | </div> |
| | | </div> |
| | | <div className="mk-timeline-item-content"> |
| | | <div className="card-item-box" style={card.style}> |
| | | <CardCellComponent data={data} cards={config} cardCell={card} elements={card.elements}/> |
| | | </div> |
| | | </div> |
| | | </div>) |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { config, loading, data } = this.state |
| | | |
| | |
| | | </div> : null |
| | | } |
| | | <NormalHeader config={config} /> |
| | | {data && data.length > 0 ? <Timeline mode={config.wrap.mode} reverse={config.wrap.reverse === 'true'} className={'card-row-list ' + (config.wrap.line || '')} style={{height: config.wrap.contentHeight}}> |
| | | {config.wrap.direction !== 'horizontal' && data && data.length > 0 ? <Timeline mode={config.wrap.mode} className={'card-row-list ' + (config.wrap.line || '')} style={{height: config.wrap.contentHeight}}> |
| | | {data.map(item => this.getnodes(item))} |
| | | </Timeline> : null} |
| | | {config.wrap.direction === 'horizontal' && data && data.length > 0 ? <div className={'mk-time-line-wrap card-row-list ' + (config.wrap.line || '')} style={{height: config.wrap.contentHeight}}> |
| | | {data.map(item => this.getMknodes(item))} |
| | | </div> : null} |
| | | {data && data.length === 0 ? <div className="card-row-list" style={{height: config.wrap.contentHeight}}> |
| | | <Empty description={false}/> |
| | | </div> : null} |
| | |
| | | |
| | | .card-row-list { |
| | | overflow-y: auto; |
| | | padding: 20px; |
| | | padding: 15px; |
| | | .card-item-box { |
| | | text-align: left; |
| | | overflow: hidden; |
| | |
| | | background: #ffffff; |
| | | } |
| | | } |
| | | |
| | | .mk-time-line-wrap { |
| | | display: flex; |
| | | overflow-x: hidden; |
| | | .mk-time-line-item { |
| | | position: relative; |
| | | width: 5%; |
| | | flex: 1; |
| | | } |
| | | .mk-time-line-item:last-child { |
| | | .mk-timeline-item-tail { |
| | | display: none; |
| | | } |
| | | } |
| | | .mk-timeline-item-head { |
| | | position: relative; |
| | | height: 20px; |
| | | text-align: center; |
| | | .mk-dot { |
| | | position: absolute; |
| | | background: #e8e8e8; |
| | | padding: 5px; |
| | | display: inline-block; |
| | | border-radius: 20px; |
| | | z-index: 1; |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%); |
| | | |
| | | .anticon { |
| | | font-size: 14px; |
| | | color: #ffffff; |
| | | width: 16px; |
| | | height: 16px; |
| | | vertical-align: top; |
| | | } |
| | | } |
| | | .mk-dot-icon { |
| | | width: 24px; |
| | | height: 24px; |
| | | padding: 4px; |
| | | } |
| | | } |
| | | .mk-timeline-item-tail { |
| | | position: absolute; |
| | | top: 10px; |
| | | left: 0px; |
| | | width: 100%; |
| | | transform: translate(50%, -1px); |
| | | border-top: 2px solid #e8e8e8; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .normal-timeline-box::after { |
| | |
| | | |
| | | class EditableCell extends Component { |
| | | getInput = (form) => { |
| | | const { inputType, options, min, max, unlimit } = this.props |
| | | const { inputType, options, min, max, unlimit, allowClear } = this.props |
| | | |
| | | if (inputType === 'number' && unlimit) { |
| | | return <InputNumber onPressEnter={() => this.getValue(form)} /> |
| | | } else if (inputType === 'number') { |
| | | return <InputNumber min={min} max={max} precision={0} onPressEnter={() => this.getValue(form)} /> |
| | | } else if (inputType === 'color') { |
| | | return <ColorSketch /> |
| | | return <ColorSketch allowClear={allowClear} /> |
| | | } else if (inputType === 'icon') { |
| | | return <MkEditIcon allowClear/> |
| | | } else if (inputType === 'switch') { |
| | |
| | | max: col.max || 500, |
| | | unlimit: col.unlimit, |
| | | required: col.required !== false ? true : false, |
| | | allowClear: col.allowClear === true, |
| | | title: col.title, |
| | | editing: this.isEditing(record), |
| | | onSave: this.onSave, |