BlockConConItem.jsx 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. import React from 'react'
  2. import cls from 'classnames'
  3. import { Menu, Dropdown } from 'antd'
  4. import i18n from 'i18next'
  5. import newEventActions from 'actions/newEvent'
  6. import treeStores from 'stores/tree'
  7. import { getEventBlockByBid, layerWidth } from 'stores/funcs/newEvent'
  8. import { conOptions } from 'const/enum'
  9. import { is } from 'immutable'
  10. import ConItem from '../ConItem'
  11. import FormulaEditor from 'src/components/common/formulaEditor/EventFormulaEditor'
  12. const MenuItem = Menu.Item
  13. export default class BlockConConItem extends ConItem {
  14. constructor(props) {
  15. super(props)
  16. this.state.option = this.getConOption(props.bid)
  17. this.state.conOptions = conOptions
  18. this.onChangeConOption = this.onChangeConOption.bind(this)
  19. this.isSelectedOption = this.isSelectedOption.bind(this)
  20. this.getValueWidth = this.getValueWidth.bind(this)
  21. this.getConOption = this.getConOption.bind(this)
  22. this.getConOptionName = this.getConOptionName.bind(this)
  23. }
  24. componentDidUpdate(preProps) {
  25. let obj = {}
  26. let conItem = this.getConItem()
  27. if (!is(this.state.conItem, conItem) || preProps.bid !== this.props.bid) {
  28. obj.conItem = conItem
  29. if (preProps.bid !== this.props.bid) {
  30. let option = this.getConOption()
  31. if (this.state.option !== option) {
  32. obj.option = option
  33. }
  34. }
  35. }
  36. if (Object.keys(obj).length > 0) {
  37. this.setState(obj)
  38. }
  39. }
  40. onEventChange(status) {
  41. let obj = {}
  42. if (status && status.types) {
  43. if (
  44. status.types.includes('updateBlockProp') &&
  45. this.props.bid === status.data.affectBlockId &&
  46. status.data.prop === 'op'
  47. ) {
  48. let option = this.getConOption()
  49. if (this.state.option !== option) {
  50. obj.option = option
  51. }
  52. }
  53. if (
  54. status.types.includes('updateBlockProp') &&
  55. this.props.bid === status.data.affectBlockId &&
  56. status.data.prop === 'cons'
  57. ) {
  58. this.forceUpdate()
  59. }
  60. }
  61. if (Object.keys(obj).length > 0) {
  62. this.setState(obj)
  63. }
  64. }
  65. onChangeConOption(option) {
  66. if (option && option.key) {
  67. let value = option.key
  68. this.setState(
  69. {
  70. option: value
  71. },
  72. () => {
  73. newEventActions.updateBlockProp({
  74. blockId: this.props.bid,
  75. prop: 'op',
  76. value: value
  77. })
  78. }
  79. )
  80. }
  81. }
  82. isSelectedOption(option) {
  83. return this.state.option === option
  84. }
  85. getValueWidth() {
  86. const groupLayer = this.props.groupLayer > 0 ? this.props.groupLayer : 0
  87. const nestingLayer =
  88. this.props.nestGroupLayer > 0 ? this.props.nestGroupLayer - 1 : 0
  89. const extraGapGroupLayer =
  90. this.props.extraGapGroupLayer > 0
  91. ? (this.props.extraGapGroupLayer - 1) * 2
  92. : 0
  93. let originWidth =
  94. 304 - ((groupLayer + nestingLayer) * 2) / 2 - extraGapGroupLayer / 2
  95. let width = layerWidth({
  96. originWidth: originWidth + this.state.widthDelta / 2,
  97. decreaseFactor: 10.5,
  98. layer: this.props.layer
  99. })
  100. return {
  101. width: width + 'px'
  102. }
  103. }
  104. getConOption(bid) {
  105. let _bid = bid || this.props.bid
  106. let nodeId = this.props.eventNodeId || treeStores.curEventNodeId
  107. let curBlock = getEventBlockByBid(_bid, nodeId)
  108. if (curBlock) {
  109. return curBlock.op || ''
  110. }
  111. return ''
  112. }
  113. getConOptionName() {
  114. let option = this.state.option
  115. if (option) {
  116. return i18n.t('EventView.jenga_cons.' + option)
  117. }
  118. return ''
  119. }
  120. render() {
  121. let conOptionsMenu = () => {
  122. return (
  123. <Menu
  124. className="con-con-flag-select-menu"
  125. onClick={this.onChangeConOption}
  126. >
  127. {this.state.conOptions.map(option => {
  128. return (
  129. <MenuItem
  130. key={option}
  131. className={cls({
  132. selected: this.isSelectedOption(option)
  133. })}
  134. >
  135. {this.getOptionName(option)}
  136. </MenuItem>
  137. )
  138. })}
  139. </Menu>
  140. )
  141. }
  142. let conFlagsMenu = () => {
  143. return (
  144. <Menu className="con-con-flag-select-menu" onClick={this.onChangeFlag}>
  145. {this.state.conFlags.map(option => {
  146. return (
  147. <MenuItem
  148. key={option}
  149. className={cls({
  150. selected: this.isSelectedFlag(option)
  151. })}
  152. >
  153. {this.getOptionName(option)}
  154. </MenuItem>
  155. )
  156. })}
  157. </Menu>
  158. )
  159. }
  160. let conOperatorsMenu = () => {
  161. return (
  162. <Menu
  163. className="con-con-operator-select-menu"
  164. onClick={this.onChangeOperator}
  165. >
  166. {this.state.conOperatorOptions.map(option => {
  167. return (
  168. <MenuItem
  169. key={option}
  170. className={cls({
  171. selected: this.isSelectedOperator(option)
  172. })}
  173. >
  174. {option}
  175. </MenuItem>
  176. )
  177. })}
  178. </Menu>
  179. )
  180. }
  181. return (
  182. <div className="con-item f--hlc">
  183. {this.props.index === 0 ? (
  184. <React.Fragment>
  185. <div className="item-enable" />
  186. <Dropdown
  187. trigger={['click']}
  188. getPopupContainer={triggerNode => triggerNode.parentNode}
  189. overlayClassName={'con-con-flag-dropdown'}
  190. overlay={conOptionsMenu()}
  191. >
  192. <div className="con-con-flag-select f--hlc">
  193. <input
  194. value={this.getConOptionName()}
  195. readOnly={true}
  196. className="ant-dropdown-input"
  197. />
  198. <div className="ant-dropdown-icon" />
  199. </div>
  200. </Dropdown>
  201. </React.Fragment>
  202. ) : (
  203. <React.Fragment>
  204. <div className="item-enable" />
  205. <Dropdown
  206. trigger={['click']}
  207. getPopupContainer={triggerNode => triggerNode.parentNode}
  208. overlayClassName={'con-con-flag-dropdown'}
  209. overlay={conFlagsMenu()}
  210. >
  211. <div className="con-con-flag-select f--hlc">
  212. <input
  213. value={this.getConItemFlagName()}
  214. readOnly={true}
  215. className="ant-dropdown-input"
  216. />
  217. <div className="ant-dropdown-icon" />
  218. </div>
  219. </Dropdown>
  220. </React.Fragment>
  221. )}
  222. <div className="item-value-wrap f--h" style={this.getValueWidth()}>
  223. <FormulaEditor
  224. className="event-formula-editor"
  225. uid={this.props.bid + 'value1'}
  226. bid={this.props.bid}
  227. value={this.state.conItem.value1}
  228. onChangeCode={this.onChangeValue.bind(this, 'value1')}
  229. />
  230. </div>
  231. <Dropdown
  232. trigger={['click']}
  233. getPopupContainer={triggerNode => triggerNode.parentNode}
  234. overlayClassName={'con-con-operator-dropdown'}
  235. overlay={conOperatorsMenu()}
  236. >
  237. <div className="con-con-operator-select f--hlc">
  238. <input
  239. value={this.state.conItem.operator}
  240. readOnly={true}
  241. className="ant-dropdown-input"
  242. />
  243. <div className="ant-dropdown-icon" />
  244. </div>
  245. </Dropdown>
  246. <div className="item-value-wrap f--h" style={this.getValueWidth()}>
  247. <FormulaEditor
  248. className="event-formula-editor"
  249. uid={this.props.bid + 'value2'}
  250. bid={this.props.bid}
  251. value={this.state.conItem.value2}
  252. params={this.formulaExtraParams()}
  253. onChangeCode={this.onChangeValue.bind(this, 'value2')}
  254. />
  255. </div>
  256. <button
  257. className="btn-clear btn-con-item-del"
  258. onClick={this.onDeleteCon}
  259. />
  260. {this.props.index === 0 ? (
  261. <button className="btn-clear btn-add-con" onClick={this.onAddCon}>
  262. <div className="btn-icon">
  263. <span className="horizon" />
  264. <span className="vertical" />
  265. </div>
  266. </button>
  267. ) : null}
  268. </div>
  269. )
  270. }
  271. }