StackConfigModal.tsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import React from 'react'
  2. import produce from 'immer'
  3. import { StackGroup, IStackConfig, IStackMetrics } from './types'
  4. import { EmptyStack } from './constants'
  5. import { Row, Col, Form, Button, Tooltip, Icon, Checkbox, Modal } from 'antd'
  6. const FormItem = Form.Item
  7. import { CheckboxChangeEvent } from 'antd/lib/checkbox'
  8. import { FormComponentProps } from 'antd/lib/form'
  9. import { FontSetting } from 'components/StyleSetting/Font'
  10. import StackContainer from './StackContainer'
  11. import Styles from './Stack.less'
  12. export interface IStackConfigModalProps {
  13. visible: boolean
  14. metrics: IStackMetrics
  15. stack: IStackConfig
  16. onCancel: () => void
  17. onSave: (stack: IStackConfig) => void
  18. }
  19. interface IStackConfigModalStates {
  20. validStack: IStackConfig
  21. }
  22. class StackConfigModal extends React.PureComponent<
  23. IStackConfigModalProps & FormComponentProps<IStackConfig>,
  24. IStackConfigModalStates
  25. > {
  26. constructor (
  27. props: IStackConfigModalProps & FormComponentProps<IStackConfig>
  28. ) {
  29. super(props)
  30. const { stack, metrics } = props
  31. this.state = { validStack: this.getValidStack(stack, metrics) }
  32. }
  33. public componentDidUpdate (
  34. prevProps: IStackConfigModalProps & FormComponentProps<IStackConfig>
  35. ) {
  36. const { metrics, stack } = this.props
  37. if (metrics !== prevProps.metrics || stack !== prevProps.stack) {
  38. const validStack = this.getValidStack(stack, metrics)
  39. this.setState({ validStack })
  40. }
  41. }
  42. private getValidStack = (
  43. stackConfig: IStackConfig,
  44. metrics: IStackMetrics
  45. ) => {
  46. const validStack = produce(stackConfig, (draft) => {
  47. if (!draft) {
  48. draft = { ...EmptyStack }
  49. return draft
  50. }
  51. const validStackGroup = draft.group.reduce<StackGroup>(
  52. (acc, stackItem) => {
  53. const validStackItem = stackItem.filter(
  54. (metricId) => !!metrics[metricId]
  55. )
  56. if (!validStackItem.length) {
  57. return acc
  58. }
  59. acc.push(validStackItem)
  60. return acc
  61. },
  62. []
  63. )
  64. draft.group = validStackGroup
  65. })
  66. return validStack
  67. }
  68. private stackGroupChange = (group: StackGroup) => {
  69. const { validStack } = this.state
  70. this.setState({ validStack: { ...validStack, group } })
  71. }
  72. private save = () => {
  73. const { form } = this.props
  74. form.validateFieldsAndScroll((err, values) => {
  75. if (err) {
  76. return
  77. }
  78. const { group } = this.state.validStack
  79. const stackConfig: IStackConfig = { ...values, group }
  80. this.props.onSave(stackConfig)
  81. })
  82. }
  83. private sumShowChange = (e: CheckboxChangeEvent) => {
  84. const show = e.target.checked
  85. const validStack = produce(this.state.validStack, (draft) => {
  86. draft.sum.show = show
  87. })
  88. this.setState({ validStack })
  89. }
  90. private modalTitle = (
  91. <>
  92. 堆叠设置
  93. <Tooltip title="拖拽指标至分组中以进行堆叠设置">
  94. <Icon className={Styles.stackInfo} type="info-circle" />
  95. </Tooltip>
  96. </>
  97. )
  98. private modalFooter = [(
  99. <Button key="cancel" size="large" onClick={this.props.onCancel}>
  100. 取 消
  101. </Button>
  102. ), (
  103. <Button key="submit" size="large" type="primary" onClick={this.save}>
  104. 保 存
  105. </Button>
  106. )]
  107. public render () {
  108. const { validStack } = this.state
  109. if (!validStack) {
  110. return null
  111. }
  112. const { form, visible, onCancel, metrics } = this.props
  113. const { getFieldDecorator } = form
  114. const { group, on, percentage, sum } = validStack
  115. return (
  116. <Modal
  117. title={this.modalTitle}
  118. wrapClassName="ant-modal-medium"
  119. footer={this.modalFooter}
  120. visible={visible}
  121. onCancel={onCancel}
  122. onOk={this.save}
  123. >
  124. <Form layout="inline">
  125. <Row>
  126. <FormItem>
  127. {getFieldDecorator<IStackConfig>('on', {
  128. initialValue: on,
  129. valuePropName: 'checked'
  130. })(<Checkbox>开启堆叠</Checkbox>)}
  131. </FormItem>
  132. </Row>
  133. <FormItem>
  134. {getFieldDecorator<IStackConfig>('percentage', {
  135. initialValue: percentage,
  136. valuePropName: 'checked'
  137. })(<Checkbox>百分比堆积</Checkbox>)}
  138. </FormItem>
  139. <FormItem>
  140. {getFieldDecorator('sum.show', {
  141. initialValue: sum.show,
  142. valuePropName: 'checked'
  143. })(<Checkbox onChange={this.sumShowChange}>显示总计</Checkbox>)}
  144. </FormItem>
  145. {sum.show && (
  146. <FormItem>
  147. {getFieldDecorator('sum.font', { initialValue: sum.font })(
  148. <FontSetting size="small" />
  149. )}
  150. </FormItem>
  151. )}
  152. </Form>
  153. <Row>
  154. <Col span={24}>
  155. <StackContainer
  156. metrics={metrics}
  157. group={group}
  158. onStackGroupChange={this.stackGroupChange}
  159. />
  160. </Col>
  161. </Row>
  162. </Modal>
  163. )
  164. }
  165. }
  166. export default Form.create<
  167. IStackConfigModalProps & FormComponentProps<IStackConfig>
  168. >()(StackConfigModal)