BlockConConItem.jsx 8.3 KB

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