index.tsx 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * <<
  3. * Davinci
  4. * ==
  5. * Copyright (C) 2016 - 2017 EDP
  6. * ==
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. * >>
  19. */
  20. import React, {
  21. PureComponent,
  22. GetDerivedStateFromProps,
  23. ChangeEvent
  24. } from 'react'
  25. import { produce } from 'immer'
  26. import LineForm from './LineForm'
  27. import BandForm from './BandForm'
  28. import { Form, Row, Col, Radio, message } from 'antd'
  29. import { FormComponentProps } from 'antd/lib/form/Form'
  30. import { ReferenceType } from '../constants'
  31. import { IReference, IReferenceLineData, IReferenceBandData } from '../types'
  32. import { IDataParamSource } from '../../Dropbox'
  33. import { RadioChangeEvent } from 'antd/lib/radio'
  34. import {
  35. getDefaultReferenceLineData,
  36. getDefaultReferenceBandData
  37. } from '../util'
  38. const FormItem = Form.Item
  39. const RadioGroup = Radio.Group
  40. const RadioButton = Radio.Button
  41. import styles from '../Reference.less'
  42. interface IReferenceFormProps {
  43. reference: IReference
  44. metrics: IDataParamSource[]
  45. }
  46. interface IReferenceFormStates {
  47. prevReference: IReference
  48. editingReference: IReference
  49. formValuesToBeSet: Partial<IReference>
  50. }
  51. class ReferenceForm extends PureComponent<
  52. IReferenceFormProps & FormComponentProps,
  53. IReferenceFormStates
  54. > {
  55. public state: IReferenceFormStates = {
  56. prevReference: null,
  57. editingReference: null,
  58. formValuesToBeSet: null
  59. }
  60. public static getDerivedStateFromProps: GetDerivedStateFromProps<
  61. IReferenceFormProps & FormComponentProps,
  62. IReferenceFormStates
  63. > = (props, state) => {
  64. const { reference } = props
  65. if (reference !== state.prevReference) {
  66. let editingReference = null
  67. try {
  68. editingReference = JSON.parse(JSON.stringify(reference))
  69. } catch (error) {
  70. message.error('参考线配置解析失败')
  71. throw error
  72. }
  73. return {
  74. prevReference: reference,
  75. editingReference
  76. }
  77. }
  78. return null
  79. }
  80. public componentDidMount() {
  81. const { reference, form } = this.props
  82. if (reference) {
  83. const { key, name, ...rest } = reference
  84. form.setFieldsValue(rest)
  85. }
  86. }
  87. public componentDidUpdate(prevProps) {
  88. const { reference, form } = this.props
  89. const { formValuesToBeSet } = this.state
  90. if (reference !== prevProps.reference) {
  91. const { key, name, ...rest } = reference
  92. form.setFieldsValue(rest)
  93. }
  94. if (formValuesToBeSet) {
  95. form.setFieldsValue(formValuesToBeSet)
  96. this.setState({
  97. formValuesToBeSet: null
  98. })
  99. }
  100. }
  101. private formConditionChange = (propPath: string, value) => {
  102. const propPathArr = propPath.split('.')
  103. const mergedEditingReference = produce(
  104. this.state.editingReference,
  105. (draft) => {
  106. propPathArr.reduce((changedProp, path, index) => {
  107. if (index === propPathArr.length - 1) {
  108. changedProp[path] = value
  109. }
  110. return changedProp[path]
  111. }, draft)
  112. }
  113. )
  114. let extraChangedValues
  115. switch (propPath) {
  116. case 'type':
  117. extraChangedValues =
  118. value === ReferenceType.Line
  119. ? getDefaultReferenceLineData()
  120. : getDefaultReferenceBandData()
  121. break
  122. }
  123. this.setState({
  124. editingReference: {
  125. ...mergedEditingReference,
  126. ...extraChangedValues
  127. },
  128. formValuesToBeSet: extraChangedValues
  129. })
  130. }
  131. private change = (name) => {
  132. return (value) => {
  133. this.formConditionChange(name, value)
  134. }
  135. }
  136. private inputChange = (name) => {
  137. return (e: ChangeEvent<HTMLInputElement> | RadioChangeEvent) => {
  138. this.formConditionChange(name, e.target.value)
  139. }
  140. }
  141. private renderFormContent(type: ReferenceType) {
  142. const { form, metrics } = this.props
  143. const { editingReference } = this.state
  144. const { data } = editingReference
  145. switch (type) {
  146. case ReferenceType.Line:
  147. return (
  148. <LineForm
  149. form={form}
  150. data={data as IReferenceLineData}
  151. metrics={metrics}
  152. onDataTypeChange={this.change}
  153. />
  154. )
  155. case ReferenceType.Band:
  156. return (
  157. <BandForm
  158. form={form}
  159. data={data as IReferenceBandData}
  160. metrics={metrics}
  161. onDataTypeChange={this.change}
  162. />
  163. )
  164. }
  165. }
  166. public render() {
  167. const { form } = this.props
  168. const { editingReference } = this.state
  169. const { getFieldDecorator } = form
  170. const { type } = editingReference
  171. return (
  172. <Form className={styles.form}>
  173. <Row gutter={8}>
  174. <Col span={8}>
  175. <FormItem label="">
  176. {getFieldDecorator(
  177. 'type',
  178. {}
  179. )(
  180. <RadioGroup onChange={this.inputChange('type')}>
  181. <RadioButton value={ReferenceType.Line}>参考线</RadioButton>
  182. <RadioButton value={ReferenceType.Band}>参考区间</RadioButton>
  183. </RadioGroup>
  184. )}
  185. </FormItem>
  186. </Col>
  187. </Row>
  188. {this.renderFormContent(type)}
  189. </Form>
  190. )
  191. }
  192. }
  193. export default Form.create<IReferenceFormProps & FormComponentProps>()(
  194. ReferenceForm
  195. )