ConditionStyleConfigModal.tsx 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. import React from 'react'
  2. import { fromJS } from 'immutable'
  3. import { Icon, Row, Col, Modal, InputNumber, Button, Radio, Select } from 'antd'
  4. const RadioGroup = Radio.Group
  5. const Option = Select.Option
  6. import ColorPicker from 'components/ColorPicker'
  7. import ConditionValuesControl from 'components/ConditionValuesControl'
  8. import { OperatorTypesLocale, TableCellConditionOperatorTypes } from 'utils/operatorTypes'
  9. import { ITableConditionStyle } from './types'
  10. import { TableConditionStyleTypes, AvailableTableConditionStyleTypes, TableConditionStyleTypesSetting } from './constants'
  11. import styles from './styles.less'
  12. import stylesConfig from '../styles.less'
  13. interface IConditionStyleConfigModalProps {
  14. visible: boolean
  15. visualType: string
  16. style: ITableConditionStyle
  17. onCancel: () => void
  18. onSave: (style: ITableConditionStyle) => void
  19. }
  20. interface IConditionStyleConfigModalStates {
  21. localStyle: ITableConditionStyle
  22. }
  23. class ConditionStyleConfigModal extends React.PureComponent<IConditionStyleConfigModalProps, IConditionStyleConfigModalStates> {
  24. public constructor (props) {
  25. super(props)
  26. this.state = {
  27. localStyle: null
  28. }
  29. }
  30. public componentWillReceiveProps (props) {
  31. const { style } = props
  32. const localStyle: ITableConditionStyle = style && fromJS(style).toJS()
  33. this.setState({
  34. localStyle
  35. })
  36. }
  37. private propChange = (propName: string, propPath?: 'colors' | 'bar') => (e) => {
  38. const value = e.target ? e.target.value : e
  39. this.setState(({ localStyle }) => {
  40. if (!propPath) {
  41. return {
  42. localStyle: { ...localStyle, [propName]: value }
  43. }
  44. } else {
  45. const subProp = localStyle[propPath]
  46. return {
  47. localStyle: {
  48. ...localStyle,
  49. [propPath]: { ...subProp, [propName]: value }
  50. }
  51. }
  52. }
  53. })
  54. }
  55. private getOperatorTypeOptions (visualType: string) {
  56. const options = Object.entries(TableCellConditionOperatorTypes)
  57. .filter(([_, values]) => ~values.indexOf(visualType))
  58. .map(([type]) => (
  59. <Option key={type} value={type}>{OperatorTypesLocale[type]}</Option>
  60. ))
  61. return options
  62. }
  63. private renderConfigItems = () => {
  64. const { localStyle } = this.state
  65. const { type } = localStyle
  66. switch (type) {
  67. case TableConditionStyleTypes.BackgroundColor:
  68. return this.renderBackgroundColor()
  69. case TableConditionStyleTypes.TextColor:
  70. return this.renderTextColor()
  71. case TableConditionStyleTypes.NumericBar:
  72. return this.renderNumericBar()
  73. case TableConditionStyleTypes.Custom:
  74. return this.renderCustom()
  75. default:
  76. return null
  77. }
  78. }
  79. private renderBackgroundColor = () => {
  80. const { localStyle } = this.state
  81. const { colors } = localStyle
  82. const { background, fore } = colors
  83. return (
  84. <Row gutter={8} type="flex" align="middle" className={stylesConfig.rowBlock}>
  85. <Col span={8}>颜色:</Col>
  86. <Col span={4} className={styles.colColor}>
  87. <ColorPicker
  88. className={stylesConfig.color}
  89. value={background}
  90. onChange={this.propChange('background', 'colors')}
  91. /><label>背景</label>
  92. </Col>
  93. <Col span={4} className={styles.colColor}>
  94. <ColorPicker
  95. className={stylesConfig.color}
  96. value={fore}
  97. onChange={this.propChange('fore', 'colors')}
  98. /><label>文字</label>
  99. </Col>
  100. </Row>
  101. )
  102. }
  103. private renderTextColor = () => {
  104. const { localStyle } = this.state
  105. const { colors } = localStyle
  106. const { fore } = colors
  107. return (
  108. <Row gutter={8} type="flex" align="middle" className={stylesConfig.rowBlock}>
  109. <Col span={8}>颜色:</Col>
  110. <Col span={4} className={styles.colColor}>
  111. <ColorPicker
  112. className={stylesConfig.color}
  113. value={fore}
  114. onChange={this.propChange('fore', 'colors')}
  115. /><label>文字</label>
  116. </Col>
  117. </Row>
  118. )
  119. }
  120. private zeroPositionOptions = [{ label: '自动', value: 'auto' }, { label: '中部', value: 'center' }]
  121. private barModeOptions = [{ label: '自动', value: 'auto' }, { label: '指定值', value: 'fixed' }]
  122. private renderNumericBar = () => {
  123. const { localStyle } = this.state
  124. const { zeroPosition, colors, bar } = localStyle
  125. const { positive, negative, fore } = colors
  126. const { mode: barMode, max: barMax, min: barMin } = bar
  127. return (
  128. <>
  129. <Row key="zeroPosition" gutter={8} type="flex" align="middle" className={stylesConfig.rowBlock}>
  130. <Col span={8}>坐标轴位置:</Col>
  131. <Col span={16}>
  132. <RadioGroup options={this.zeroPositionOptions} onChange={this.propChange('zeroPosition')} value={zeroPosition} />
  133. </Col>
  134. </Row>
  135. <Row key="zeroPositionValues" gutter={8} type="flex" align="middle" className={stylesConfig.rowBlock}>
  136. <Col span={8}>颜色:</Col>
  137. <Col span={4} className={styles.colColor}>
  138. <ColorPicker
  139. className={stylesConfig.color}
  140. value={positive}
  141. onChange={this.propChange('positive', 'colors')}
  142. /><label>正值</label>
  143. </Col>
  144. <Col span={4} className={styles.colColor}>
  145. <ColorPicker
  146. className={stylesConfig.color}
  147. value={negative}
  148. onChange={this.propChange('negative', 'colors')}
  149. /><label>负值</label>
  150. </Col>
  151. <Col span={4} className={styles.colColor}>
  152. <ColorPicker
  153. className={stylesConfig.color}
  154. value={fore}
  155. onChange={this.propChange('fore', 'colors')}
  156. /><label>文字</label>
  157. </Col>
  158. </Row>
  159. <Row gutter={8} type="flex" align="middle" className={stylesConfig.rowBlock}>
  160. <Col span={8}>最大(小)值:</Col>
  161. <Col span={16}>
  162. <RadioGroup options={this.barModeOptions} onChange={this.propChange('mode', 'bar')} value={barMode} />
  163. </Col>
  164. </Row>
  165. {barMode === 'fixed' && (
  166. <>
  167. <Row gutter={8} type="flex" align="middle" className={stylesConfig.rowBlock}>
  168. <Col offset={13} span={4}>最小值:</Col>
  169. <Col span={7}><InputNumber size="small" className={stylesConfig.colControl} value={barMin} onChange={this.propChange('min', 'bar')} /></Col>
  170. </Row>
  171. <Row gutter={8} type="flex" align="middle" className={stylesConfig.rowBlock}>
  172. <Col offset={13} span={4}>最大值:</Col>
  173. <Col span={7}><InputNumber size="small" className={stylesConfig.colControl} value={barMax} onChange={this.propChange('max', 'bar')} /></Col>
  174. </Row>
  175. </>
  176. )}
  177. </>
  178. )
  179. }
  180. private renderCustom = () => {
  181. return (
  182. <Row gutter={8} type="flex" align="middle" className={stylesConfig.rowBlock}>
  183. <Col span={6}>编辑文本:</Col>
  184. <Col span={3}>
  185. <Icon type="edit" />
  186. </Col>
  187. </Row>
  188. )
  189. }
  190. private cancel = () => {
  191. this.props.onCancel()
  192. }
  193. private save = () => {
  194. this.props.onSave(this.state.localStyle)
  195. }
  196. private modalFooter = [(
  197. <Button
  198. key="cancel"
  199. size="large"
  200. onClick={this.cancel}
  201. >
  202. 取 消
  203. </Button>
  204. ), (
  205. <Button
  206. key="submit"
  207. size="large"
  208. type="primary"
  209. onClick={this.save}
  210. >
  211. 保 存
  212. </Button>
  213. )]
  214. private getConditionTypeOptions (visualType: string) {
  215. const options = Object.entries(AvailableTableConditionStyleTypes)
  216. .filter(([type]) => ~TableConditionStyleTypesSetting[type].indexOf(visualType))
  217. .map(([type, name]) => (
  218. <Option key={type} value={type}>{name}</Option>
  219. ))
  220. return options
  221. }
  222. private conditionValuesChange = (values) => {
  223. this.setState({
  224. localStyle: {
  225. ...this.state.localStyle,
  226. conditionValues: values
  227. }
  228. })
  229. }
  230. public render () {
  231. const { visible, visualType } = this.props
  232. const { localStyle } = this.state
  233. if (!localStyle) { return (<div />) }
  234. const { type, operatorType, conditionValues } = localStyle
  235. return (
  236. <Modal
  237. title="条件格式"
  238. width={500}
  239. maskClosable={false}
  240. footer={this.modalFooter}
  241. visible={visible}
  242. onCancel={this.cancel}
  243. onOk={this.save}
  244. >
  245. <div className={stylesConfig.rows}>
  246. <Row gutter={8} type="flex" align="middle" className={stylesConfig.rowBlock}>
  247. <Col span={8}>样式类型:</Col>
  248. <Col span={16}>
  249. <Select
  250. size="small"
  251. className={stylesConfig.colControl}
  252. value={type}
  253. onChange={this.propChange('type')}
  254. >
  255. {this.getConditionTypeOptions(visualType)}
  256. </Select>
  257. </Col>
  258. </Row>
  259. <Row key="operatorType" gutter={8} type="flex" align="middle" className={stylesConfig.rowBlock}>
  260. <Col span={8}>关系:</Col>
  261. <Col span={16}>
  262. <Select
  263. size="small"
  264. className={stylesConfig.colControl}
  265. value={operatorType}
  266. onChange={this.propChange('operatorType')}
  267. >
  268. {this.getOperatorTypeOptions(visualType)}
  269. </Select>
  270. </Col>
  271. </Row>
  272. <Row key="valueControls" gutter={8} type="flex" align="middle" className={stylesConfig.rowBlock}>
  273. <Col span={8}>值:</Col>
  274. <Col span={16}>
  275. <ConditionValuesControl
  276. size="small"
  277. visualType={visualType}
  278. operatorType={operatorType}
  279. conditionValues={conditionValues}
  280. onChange={this.conditionValuesChange}
  281. />
  282. </Col>
  283. </Row>
  284. {this.renderConfigItems()}
  285. </div>
  286. </Modal>
  287. )
  288. }
  289. }
  290. export default ConditionStyleConfigModal