GlobalControlRelatedViewForm.tsx 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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, { FC, memo, useCallback } from 'react'
  21. import classnames from 'classnames'
  22. import { Form, Row, Col, Select, Radio, Empty } from 'antd'
  23. import { WrappedFormUtils } from 'antd/lib/form/Form'
  24. import { RadioChangeEvent } from 'antd/lib/radio'
  25. import { IViewModelProps } from 'app/containers/View/types'
  26. import { ControlFieldTypes, ControlTypes, IS_RANGE_TYPE } from '../../constants'
  27. import { IFlatRelatedView } from './types'
  28. import { filterSelectOption } from 'app/utils/util'
  29. import styles from '../../Control.less'
  30. const FormItem = Form.Item
  31. const Option = Select.Option
  32. const RadioButton = Radio.Button
  33. const RadioGroup = Radio.Group
  34. interface IGlobalControlRelatedViewFormProps {
  35. form: WrappedFormUtils
  36. relatedViews: IFlatRelatedView[]
  37. controlType: ControlTypes
  38. optionWithVariable: boolean
  39. onFieldTypeChange: (id: number) => (e: RadioChangeEvent) => void
  40. }
  41. const GlobalControlRelatedViewForm: FC<IGlobalControlRelatedViewFormProps> = ({
  42. form,
  43. relatedViews,
  44. controlType,
  45. optionWithVariable,
  46. onFieldTypeChange
  47. }) => {
  48. const { getFieldDecorator } = form
  49. const viewsClass = classnames({
  50. [styles.views]: true,
  51. [styles.empty]: !relatedViews.length
  52. })
  53. const columnValidator = useCallback(
  54. (rule, value, callback) => {
  55. if (
  56. (Array.isArray(value) && !!value.length) ||
  57. (!Array.isArray(value) && value !== void 0)
  58. ) {
  59. const { field } = rule
  60. const viewId = field.substring(
  61. field.indexOf('[') + 1,
  62. field.indexOf(']')
  63. )
  64. const { fieldType, models, variables } = relatedViews.find(
  65. (v) => v.id === Number(viewId)
  66. )
  67. const selectedModel =
  68. fieldType === ControlFieldTypes.Column
  69. ? models.find((m) => m.name === value)
  70. : Array.isArray(value)
  71. ? value.every((v) => variables.find((vr) => vr.name === v))
  72. : variables.find((vr) => vr.name === value)
  73. if (!selectedModel) {
  74. callback('数据模型已变化,请重新选择')
  75. } else {
  76. callback()
  77. }
  78. } else {
  79. callback()
  80. }
  81. },
  82. [form, relatedViews]
  83. )
  84. return (
  85. <div className={styles.viewContainer}>
  86. <div className={styles.title}>
  87. <h2>关联数据视图</h2>
  88. </div>
  89. <div className={viewsClass}>
  90. {relatedViews.length ? (
  91. relatedViews.map(({ id, name, fieldType, models, variables }) => {
  92. const isMultiple =
  93. IS_RANGE_TYPE[controlType] &&
  94. fieldType === ControlFieldTypes.Variable
  95. const fieldValues =
  96. form.getFieldValue(`relatedViews[${id}].fields`) || []
  97. return (
  98. <div key={id} className={styles.relatedView}>
  99. <div className={styles.name}>
  100. <h4>{name}</h4>
  101. {getFieldDecorator(
  102. `relatedViews[${id}].fieldType`,
  103. {}
  104. )(
  105. <RadioGroup
  106. size="small"
  107. className={styles.fieldType}
  108. disabled={optionWithVariable}
  109. onChange={onFieldTypeChange(id)}
  110. >
  111. <RadioButton value={ControlFieldTypes.Column}>
  112. 字段
  113. </RadioButton>
  114. <RadioButton value={ControlFieldTypes.Variable}>
  115. 变量
  116. </RadioButton>
  117. </RadioGroup>
  118. )}
  119. </div>
  120. <Row gutter={8}>
  121. <Col span={24}>
  122. <FormItem>
  123. {getFieldDecorator(`relatedViews[${id}].fields`, {
  124. rules: [
  125. {
  126. required: true,
  127. message: `关联${
  128. fieldType === ControlFieldTypes.Column
  129. ? '字段'
  130. : '变量'
  131. }不能为空`
  132. },
  133. { validator: columnValidator }
  134. ]
  135. })(
  136. <Select
  137. showSearch
  138. placeholder="请选择"
  139. filterOption={filterSelectOption}
  140. {...(isMultiple && { mode: 'multiple' })}
  141. disabled={optionWithVariable}
  142. >
  143. {fieldType === ControlFieldTypes.Column
  144. ? models.map((m: IViewModelProps) => (
  145. <Option key={m.name} value={m.name}>
  146. {m.name}
  147. </Option>
  148. ))
  149. : variables.map((v) => (
  150. <Option
  151. key={v.name}
  152. value={v.name}
  153. disabled={
  154. isMultiple &&
  155. fieldValues.length === 2 &&
  156. !fieldValues.includes(v.name)
  157. }
  158. >
  159. {v.name}
  160. </Option>
  161. ))}
  162. </Select>
  163. )}
  164. </FormItem>
  165. </Col>
  166. </Row>
  167. </div>
  168. )
  169. })
  170. ) : (
  171. <Empty key="empty" image={Empty.PRESENTED_IMAGE_SIMPLE} />
  172. )}
  173. </div>
  174. </div>
  175. )
  176. }
  177. export default memo(GlobalControlRelatedViewForm)