BlockActionMethod.jsx 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  1. import React from 'react'
  2. import i18n from 'i18next'
  3. import cls from 'classnames'
  4. import { Menu, Dropdown, Tooltip, Popover } from 'antd'
  5. import newEventActions from 'actions/newEvent'
  6. import newEventStores from 'stores/newEvent'
  7. import widgetStore from 'stores/widget'
  8. import {
  9. nodeIsChild,
  10. nodeIsService,
  11. nodeIsTimerService,
  12. nodeIsTransaction,
  13. nodeIsNormalService,
  14. nodeIsFunctionGroup,
  15. nodeIsApi,
  16. nodeIsDyTransaction,
  17. nodeIsSql,
  18. nodeIsSharedService
  19. } from 'stores/funcs/nodeType'
  20. import {
  21. getEventNodeById,
  22. getEventBlockByBid,
  23. getActionBlockObjNode,
  24. getBlockObj,
  25. getBlockAciton
  26. } from 'stores/funcs/newEvent'
  27. import {
  28. isAsyncDbMethod,
  29. isAsyncDbCustomsMethod,
  30. isAsyncMethod,
  31. genParams,
  32. genAsyncParams,
  33. getReloadMethods,
  34. isMethodAllowed,
  35. getModuleInstanceNameLocale,
  36. modulePropMethod,
  37. isParentWidgetProps,
  38. getActionMethods,
  39. getTargetMethod,
  40. isChangedActionValid
  41. } from 'stores/funcs/event/methodUtils'
  42. import { shallowEqualImmutable, cpJson } from 'utils/utils'
  43. import { isHySa } from 'utils/commons/ctrlHide'
  44. import { BLOCK_OP_TYPE } from 'const/const'
  45. import propType from 'const/propType'
  46. import externalPath from 'src/http/api/externalPath'
  47. import iconStrObj from 'src/assets/icons/iconsStr'
  48. import BlockActionMethodParams from './BlockActionMethodParams'
  49. import BlockActionReload from './BlockActionReload'
  50. import BlockActionDelay from './BlockActionDelay'
  51. const MenuItem = Menu.Item
  52. export default class BlockActionMethod extends React.Component {
  53. constructor(props) {
  54. super(props)
  55. this.obj = this.getObject() // 当前选中了的对象,动作受它影响
  56. this.state = {
  57. methods: this.getMethods(), // 可选动作
  58. actionName: this.getActionName(),
  59. isMini: this.getActionIsMini(),
  60. // hasParams: this.getHasParams(),
  61. methodParams: this.getMethodParams(),
  62. paramsVisible: this.getParamsVisible(),
  63. delay: this.getDelay()
  64. }
  65. this.onEventChange = this.onEventChange.bind(this)
  66. // reload相关
  67. // this.hasDiffParams = this.hasDiffParams.bind(this)
  68. // this.autoReloadSpecialAction = this.autoReloadSpecialAction.bind(this)
  69. this.onReloadAction = this.onReloadAction.bind(this) // 刷新
  70. this.onChangeDelay = this.onChangeDelay.bind(this)
  71. this.genDefaultAction = this.genDefaultAction.bind(this)
  72. // 处理选择的method相关
  73. this.decorateAction = this.decorateAction.bind(this)
  74. // this.combineOldAction = this.combineOldAction.bind(this)
  75. this.onMethodSelect = this.onMethodSelect.bind(this) // action的选择
  76. this.onToggleParamsVisible = this.onToggleParamsVisible.bind(this)
  77. this.getMethods = this.getMethods.bind(this)
  78. this.getObject = this.getObject.bind(this)
  79. this.getActionName = this.getActionName.bind(this)
  80. this.getActionIsMini = this.getActionIsMini.bind(this)
  81. // this.getHasParams = this.getHasParams.bind(this)
  82. this.getMethodParams = this.getMethodParams.bind(this)
  83. this.getParamsVisible = this.getParamsVisible.bind(this)
  84. this.getDelay = this.getDelay.bind(this)
  85. this.getDelayContent = this.getDelayContent.bind(this)
  86. this.getActionLocaleName = this.getActionLocaleName.bind(this)
  87. this.filterTargetMethod = this.filterTargetMethod.bind(this)
  88. this.getTipInfo = this.getTipInfo.bind(this)
  89. this.isAllowedMethod = this.isAllowedMethod.bind(this)
  90. this.forbiddenTips = this.forbiddenTips.bind(this)
  91. }
  92. shouldComponentUpdate(nextProps, nextState) {
  93. return (
  94. !shallowEqualImmutable(this.props, nextProps) ||
  95. !shallowEqualImmutable(this.state, nextState)
  96. )
  97. }
  98. componentDidMount() {
  99. this.unsubscribe = newEventStores.listen(this.onEventChange)
  100. // this.autoReloadSpecialAction()
  101. }
  102. componentWillUnmount() {
  103. this.unsubscribe()
  104. }
  105. componentDidUpdate(preProps) {
  106. if (preProps.bid !== this.props.bid) {
  107. this.obj = this.getObject()
  108. this.setState(
  109. {
  110. methods: this.getMethods(), // 可选动作
  111. actionName: this.getActionName(),
  112. isMini: this.getActionIsMini(),
  113. // hasParams: this.getHasParams(),
  114. methodParams: this.getMethodParams(),
  115. paramsVisible: this.getParamsVisible(),
  116. delay: this.getDelay()
  117. },
  118. () => {
  119. // this.autoReloadSpecialAction()
  120. }
  121. )
  122. }
  123. }
  124. onEventChange(status) {
  125. let obj = {}
  126. let shouldUpdate = true
  127. if (status) {
  128. if (
  129. (status.types.includes('updateBlockProp') &&
  130. this.props.bid === status.data.affectBlockId &&
  131. status.data.prop === 'object') ||
  132. (status.types.includes('reloadBlock') &&
  133. this.props.bid === status.data.affectBlockId)
  134. ) {
  135. // obj通知更新
  136. this.obj = this.getObject()
  137. obj.methods = this.getMethods() // 可选动作
  138. obj.actionName = this.getActionName()
  139. obj.isMini = this.getActionIsMini()
  140. // obj.hasParams = this.getHasParams()
  141. obj.methodParams = this.getMethodParams()
  142. obj.paramsVisible = this.getParamsVisible()
  143. obj.delay = this.getDelay()
  144. this.setState(obj, () => {
  145. if (this.obj && !this.state.actionName) {
  146. // 创建相关方法
  147. this.genDefaultAction()
  148. }
  149. })
  150. shouldUpdate = false
  151. }
  152. if (
  153. status.types.includes('changeActionBlockAction') &&
  154. this.props.bid === status.data.affectBlockId &&
  155. status.data.prop === 'paramsVisible'
  156. ) {
  157. obj.paramsVisible = this.getParamsVisible()
  158. }
  159. if (status.types.includes('updateActionMethod')) {
  160. // 更新方法(主要是参数变化)
  161. let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
  162. let objNode = getActionBlockObjNode({
  163. obj: this.obj,
  164. nodeId
  165. })
  166. if (
  167. objNode &&
  168. objNode.id === status.data.nodeId &&
  169. (!status.data.targetBlockId ||
  170. status.data.targetBlockId === this.props.bid) &&
  171. status.data.methods.includes(this.state.actionName)
  172. ) {
  173. let keepVisible = true
  174. if (
  175. ['clone', 'sendSMS', 'sendSMS_stage'].indexOf(
  176. this.state.actionName
  177. ) >= 0
  178. ) {
  179. keepVisible = false
  180. }
  181. this.onReloadAction(keepVisible, false)
  182. }
  183. }
  184. }
  185. if (Object.keys(obj).length > 0 && shouldUpdate) {
  186. this.setState(obj)
  187. }
  188. }
  189. // hasDiffParams(objNode) {
  190. // let result = false
  191. // let method =
  192. // widgetStore.widget[objNode.type].map.methodsMap[this.state.actionName]
  193. // let params = genParams(method, objNode, this.props.bid, true)
  194. // let block = getEventBlockByBid(this.props.bid)
  195. // let preParams = block && block.action && block.action.params
  196. // if ((!params && preParams) || (params && !preParams)) {
  197. // // 有一个为空
  198. // result = true
  199. // } else if (params && preParams && params.length !== preParams.length) {
  200. // // 都有参数且长度不一致
  201. // result = true
  202. // } else if (params && preParams && params.length === preParams.length) {
  203. // // 都有参数且长度一致
  204. // let hasDif = false
  205. // params.forEach((param, index) => {
  206. // if (
  207. // param.name !== preParams[index].name ||
  208. // param.type !== preParams[index].type ||
  209. // ((param.pType || preParams[index].pType) &&
  210. // param.pType !== preParams[index].pType)
  211. // ) {
  212. // hasDif = true
  213. // }
  214. // })
  215. // result = hasDif
  216. // } else {
  217. // result = false
  218. // }
  219. // return result
  220. // }
  221. // autoReloadSpecialAction() {
  222. // let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
  223. // let objNode = getActionBlockObjNode({
  224. // obj: this.obj,
  225. // nodeId
  226. // })
  227. // if (objNode) {
  228. // let methods = getReloadMethods(objNode)
  229. // if (methods && this.hasDiffParams(objNode)) {
  230. // newEventActions.updateActionMethod({
  231. // nodeId: objNode.id,
  232. // targetBlockId: this.props.bid,
  233. // methods: methods
  234. // })
  235. // }
  236. // }
  237. // }
  238. filterTargetMethod(method) {
  239. let result = method
  240. if (result) {
  241. let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
  242. let objNode = getActionBlockObjNode({
  243. obj: this.obj,
  244. nodeId
  245. })
  246. let node = getEventNodeById(nodeId)
  247. if (
  248. !isChangedActionValid({
  249. rootNode: node,
  250. blockNode: objNode,
  251. blockObj: this.obj,
  252. actionName: result.name
  253. })
  254. ) {
  255. result = undefined
  256. }
  257. }
  258. return result
  259. }
  260. onReloadAction(keepVisible, addRecord) {
  261. let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
  262. let objNode = getActionBlockObjNode({
  263. obj: this.obj,
  264. nodeId
  265. })
  266. let method = this.filterTargetMethod(
  267. getTargetMethod(objNode, this.state.actionName)
  268. )
  269. if (method) {
  270. this.onMethodSelect(
  271. { item: { props: { method: method } } },
  272. keepVisible,
  273. undefined,
  274. false
  275. )
  276. } else {
  277. this.setState(
  278. {
  279. actionName: null,
  280. isMini: false,
  281. // hasParams: false,
  282. methodParams: [],
  283. paramsVisible: 'all'
  284. },
  285. () => {
  286. newEventActions.updateBlockProp({
  287. nodeId,
  288. blockId: this.props.bid,
  289. prop: 'action',
  290. value: null,
  291. trigger: true,
  292. addRecord: addRecord === undefined ? true : addRecord
  293. })
  294. }
  295. )
  296. }
  297. }
  298. onChangeDelay() {
  299. let delay = this.getDelay()
  300. this.setState({
  301. delay: delay
  302. })
  303. }
  304. genDefaultAction() {
  305. let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
  306. let objNode = getActionBlockObjNode({
  307. obj: this.obj,
  308. nodeId
  309. })
  310. if (objNode) {
  311. let method
  312. if (nodeIsService(objNode.type)) {
  313. let methods = this.getMethods()
  314. if (methods && methods.length > 0) {
  315. if (nodeIsTimerService(objNode.type)) {
  316. if (this.obj === 'curObj') {
  317. method = methods.find(meth => {
  318. return meth.name === 'recordResult'
  319. })
  320. }
  321. } else if (nodeIsTransaction(objNode.type)) {
  322. if (this.obj !== 'curObj') {
  323. method = methods.find(meth => {
  324. return meth.name === 'runTransaction'
  325. })
  326. } else {
  327. method = methods.find(meth => {
  328. return meth.name === 'paramResult'
  329. })
  330. }
  331. } else if (nodeIsDyTransaction(objNode.type)) {
  332. method = methods.find(meth => {
  333. return meth.name === 'runDyTransaction'
  334. })
  335. } else if (nodeIsNormalService(objNode.type)) {
  336. if (this.obj !== 'curObj') {
  337. method = methods.find(meth => {
  338. return meth.name === 'fireService' || meth.name === 'runService'
  339. })
  340. } else {
  341. method = methods.find(meth => {
  342. return meth.name === 'paramResult'
  343. })
  344. }
  345. }
  346. }
  347. } else if (nodeIsFunctionGroup(objNode.type)) {
  348. let methods = this.getMethods()
  349. if (methods && methods.length > 0) {
  350. // 触发动作组
  351. if (this.obj !== 'curObj') {
  352. method = methods.find(meth => {
  353. return meth.name === 'fireFuncGroup'
  354. })
  355. } else {
  356. method = methods.find(meth => {
  357. return meth.name === 'funcResult'
  358. })
  359. }
  360. }
  361. } else if (objNode.type === 'data-event') {
  362. let methods = this.getMethods()
  363. if (methods && methods.length > 0) {
  364. method = methods.find(meth => {
  365. return meth.name === 'fireEvent'
  366. })
  367. // // 设置返回结果
  368. // if (method) {
  369. // this.onMethodSelect(undefined, false, method)
  370. // }
  371. }
  372. } else if (nodeIsApi(objNode.type)) {
  373. let methods = this.getMethods()
  374. let targetMethodName =
  375. objNode.type === 'server-api'
  376. ? 'sendServerApiRequest'
  377. : 'sendApiRequest'
  378. if (methods && methods.length > 0) {
  379. method = methods.find(meth => {
  380. return meth.name === targetMethodName
  381. })
  382. }
  383. } else if (nodeIsSql(objNode.type)) {
  384. let methods = this.getMethods()
  385. if (methods && methods.length > 0) {
  386. method = methods.find(meth => {
  387. return meth.name === 'run'
  388. })
  389. }
  390. } else if (nodeIsSharedService(objNode.type)) {
  391. let methods = this.getMethods()
  392. if (methods && methods.length > 0) {
  393. method = methods.find(meth => {
  394. return meth.name === 'fireService' || meth.name === 'runService'
  395. })
  396. }
  397. }
  398. if (method) {
  399. this.onMethodSelect(undefined, false, method)
  400. }
  401. }
  402. }
  403. decorateAction(nAction, method, keepVisible, asyncCb) {
  404. let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
  405. let objNode = getActionBlockObjNode({
  406. obj: this.obj,
  407. nodeId
  408. })
  409. if (method.mini) {
  410. nAction.mini = method.mini
  411. }
  412. if (method.miniType) {
  413. nAction.miniType = method.miniType
  414. }
  415. if (method.miniEmit) {
  416. nAction.miniEmit = method.miniEmit
  417. }
  418. if (method.meth) {
  419. nAction.meth = method.meth
  420. }
  421. if (method.paramsAsObj) {
  422. nAction.paramsAsObj = method.paramsAsObj
  423. }
  424. if (method.callback) {
  425. nAction.callback = true // 表明有callback
  426. }
  427. let isAsync =
  428. isAsyncDbMethod(method.name) ||
  429. isAsyncMethod(method.name) ||
  430. isAsyncDbCustomsMethod(method.name)
  431. if (isAsync) {
  432. genAsyncParams(method, objNode, this.props.bid, params => {
  433. if (params) {
  434. nAction.params = params
  435. }
  436. // this.combineOldAction(nAction, keepVisible)
  437. asyncCb && asyncCb()
  438. })
  439. } else {
  440. let params = genParams(method, objNode, this.props.bid, true)
  441. if (params && params.length > 0) {
  442. nAction.params = params
  443. }
  444. // this.combineOldAction(nAction, keepVisible)
  445. }
  446. }
  447. // combineOldAction(newAction, keepVisible) {
  448. // let block = getEventBlockByBid(this.props.bid)
  449. // if (block && block.action && block.action.name === newAction.name) {
  450. // if (keepVisible) {
  451. // newAction.visible = block.action.visible
  452. // }
  453. // // action信息
  454. // if (block.action.info) {
  455. // newAction.info = cpJson(block.action.info)
  456. // }
  457. // if (block.action.params && newAction.params) {
  458. // newAction.params.forEach(newParam => {
  459. // block.action.params.forEach(oldParam => {
  460. // if (
  461. // newParam.name === oldParam.name &&
  462. // newParam.type === oldParam.type
  463. // ) {
  464. // if (oldParam.pGroup) {
  465. // if (newParam.pGroup === oldParam.pGroup) {
  466. // newParam.value = oldParam.value
  467. // }
  468. // } else {
  469. // // 是否是克隆对象的子对象
  470. // if (oldParam.type === propType.CloneChild) {
  471. // let cloneIDParam = block.action.params[0]
  472. // if (
  473. // cloneIDParam &&
  474. // cloneIDParam.name === 'cloneId' &&
  475. // cloneIDParam.value
  476. // ) {
  477. // // 并非子对象则还原
  478. // if (oldParam.value && oldParam.value.length > 0) {
  479. // oldParam.value.forEach(idProp => {
  480. // if (!nodeIsChild(cloneIDParam.value, idProp.id)) {
  481. // idProp.id = null
  482. // idProp.props = []
  483. // }
  484. // })
  485. // }
  486. // }
  487. // }
  488. // newParam.value = oldParam.value
  489. // }
  490. // }
  491. // })
  492. // })
  493. // }
  494. // }
  495. // }
  496. onTriggerAction(nAction, addRecord) {
  497. // 选择后触发相关的界面改变
  498. this.setState(
  499. {
  500. actionName: nAction.name,
  501. isMini: nAction.mini,
  502. // hasParams: !!(nAction.params && nAction.params.length > 0),
  503. methodParams: cpJson(nAction.params) || [],
  504. paramsVisible: nAction.paramsVisible
  505. },
  506. () => {
  507. let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
  508. newEventActions.updateBlockProp({
  509. nodeId,
  510. blockId: this.props.bid,
  511. prop: 'action',
  512. value: nAction,
  513. trigger: true,
  514. addRecord: addRecord === undefined ? true : addRecord
  515. })
  516. }
  517. )
  518. }
  519. onMethodSelect(option, keepVisible, targetMethod, addRecord) {
  520. if (option && option.key === 'emptyContent') {
  521. return
  522. }
  523. let method
  524. if (targetMethod) {
  525. method = targetMethod
  526. } else if (
  527. option &&
  528. option.item &&
  529. option.item.props &&
  530. option.item.props.method
  531. ) {
  532. method = option.item.props.method
  533. }
  534. if (method) {
  535. // 选择了对象之后的操作
  536. let nAction = { name: method.name, paramsVisible: 'all' }
  537. this.decorateAction(
  538. nAction,
  539. method,
  540. keepVisible,
  541. this.onTriggerAction.bind(this, nAction, addRecord)
  542. )
  543. if (
  544. !isAsyncDbMethod(method.name) &&
  545. !isAsyncMethod(method.name) &&
  546. !isAsyncDbCustomsMethod(method.name)
  547. ) {
  548. this.onTriggerAction(nAction, addRecord)
  549. }
  550. }
  551. }
  552. onToggleParamsVisible() {
  553. newEventActions.toggleActionParamsVisible({ blockId: this.props.bid })
  554. }
  555. getMethods() {
  556. return getActionMethods({
  557. obj: this.obj,
  558. curNodeId: this.props.eventNodeId || newEventStores.curEventNodeId,
  559. isNewEvent: true
  560. })
  561. }
  562. getObject() {
  563. let _obj
  564. let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
  565. let curBlock = getEventBlockByBid(this.props.bid, nodeId)
  566. if (curBlock) {
  567. _obj = getBlockObj({ block: curBlock })
  568. }
  569. return _obj
  570. }
  571. getActionName() {
  572. let result = null
  573. let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
  574. let block = getEventBlockByBid(this.props.bid, nodeId)
  575. if (block) {
  576. result = getBlockAciton(block)
  577. }
  578. return result
  579. }
  580. getActionIsMini() {
  581. let result = false
  582. let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
  583. let block = getEventBlockByBid(this.props.bid, nodeId)
  584. if (block) {
  585. switch (block.op) {
  586. case BLOCK_OP_TYPE.CALL:
  587. result = block.mini || false
  588. break
  589. case BLOCK_OP_TYPE.LET:
  590. result = block.args[0].mini || false
  591. break
  592. }
  593. }
  594. return result
  595. }
  596. // getHasParams() {
  597. // let result = false
  598. // let block = getEventBlockByBid(this.props.bid)
  599. // if (
  600. // block &&
  601. // block.type === EVENT_BLOCK_TYPE.ACTION &&
  602. // block.action &&
  603. // block.action.params
  604. // ) {
  605. // result = block.action.params.length > 0
  606. // }
  607. // return result
  608. // }
  609. getMethodParams() {
  610. let result = []
  611. let actionName = this.getActionName()
  612. if (actionName) {
  613. let methods = this.getMethods()
  614. if (methods) {
  615. let targetMethod = methods.find(method => {
  616. return method.name === actionName
  617. })
  618. if (targetMethod) {
  619. let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
  620. let objNode = getActionBlockObjNode({
  621. obj: this.obj,
  622. nodeId
  623. })
  624. result = genParams(targetMethod, objNode, this.props.bid, true)
  625. }
  626. }
  627. }
  628. return result
  629. }
  630. getParamsVisible() {
  631. let result = undefined
  632. let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
  633. let block = getEventBlockByBid(this.props.bid, nodeId)
  634. if (block && block.paramsVisible) {
  635. result = block.paramsVisible
  636. }
  637. return result || 'all'
  638. }
  639. getDelay() {
  640. let result = 0
  641. let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
  642. let block = getEventBlockByBid(this.props.bid, nodeId)
  643. if (block && block.delay) {
  644. result = block.delay || 0
  645. }
  646. return result
  647. }
  648. getDelayContent() {
  649. if (this.state.delay && this.state.delay > 0) {
  650. return (
  651. i18n.t('EventView.jenga_action_block.delayPrefix') +
  652. this.state.delay +
  653. i18n.t('EventView.jenga_action_block.delayPostfix')
  654. )
  655. }
  656. return ''
  657. }
  658. getActionLocaleName() {
  659. let name = this.state.actionName ? this.state.actionName || '' : ''
  660. let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
  661. let objNode = getActionBlockObjNode({
  662. obj: this.obj,
  663. nodeId
  664. })
  665. if (objNode) {
  666. if (
  667. isParentWidgetProps(objNode) &&
  668. this.state.actionName === 'miniPropValueChange'
  669. ) {
  670. let method = modulePropMethod()
  671. name = method.locale ? method.locale[i18n.language] : name
  672. } else if (this.state.isMini) {
  673. name = getModuleInstanceNameLocale({
  674. nodeId: objNode.id,
  675. type: 'methods',
  676. name: this.state.actionName
  677. })
  678. } else {
  679. let nodeInfo = objNode ? widgetStore.widget[objNode.type] : undefined
  680. if (objNode && nodeInfo && nodeInfo.map && nodeInfo.map.methodsMap) {
  681. name =
  682. nodeInfo.map.methodsMap[name] &&
  683. nodeInfo.map.methodsMap[name].locale
  684. ? nodeInfo.map.methodsMap[name].locale[i18n.language]
  685. : name
  686. }
  687. }
  688. }
  689. return name
  690. }
  691. getTipInfo(item) {
  692. let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
  693. let objNode = getActionBlockObjNode({
  694. obj: this.obj,
  695. nodeId
  696. })
  697. let type = objNode && objNode.type
  698. if (type && item) {
  699. let stopPro = e => {
  700. e.stopPropagation()
  701. }
  702. let info = widgetStore.widget[type].map.methodsMap[item.name]
  703. let content = info && info.desc && info.desc[i18n.language]
  704. let link =
  705. i18n.language === 'en' ? info && info.linkEN : info && info.linkZH
  706. content = content ? (
  707. <div onClick={stopPro}>
  708. {content}
  709. {info && link ? (
  710. <a className="a-tag" href={link} target="_blank">
  711. {i18n.t('Tips.more')}
  712. </a>
  713. ) : (
  714. undefined
  715. )}
  716. </div>
  717. ) : (
  718. undefined
  719. )
  720. return (
  721. (!isHySa() && info && content && (
  722. <Tooltip
  723. title={content}
  724. placement="right"
  725. destroyTooltipOnHide={true}
  726. >
  727. <div className="block-map-help">
  728. <div
  729. className="ih5-icon-help"
  730. dangerouslySetInnerHTML={{ __html: iconStrObj.help }}
  731. />
  732. </div>
  733. </Tooltip>
  734. )) ||
  735. null
  736. )
  737. } else {
  738. return null
  739. }
  740. }
  741. isAllowedMethod(method) {
  742. let curNodeId = this.props.eventNodeId || newEventStores.curEventNodeId
  743. return isMethodAllowed({
  744. obj: this.obj,
  745. method,
  746. curNodeId,
  747. isNewEvent: true
  748. })
  749. }
  750. forbiddenTips() {
  751. return (
  752. <div>
  753. <span>
  754. {i18n.t('EventView.jenga_action_block.cross_page_method_warn')}
  755. </span>
  756. <a href={externalPath.crossPageMethod} target="_blank">
  757. {i18n.t('EventView.jenga_action_block.cross_page_method_detail')}
  758. </a>
  759. </div>
  760. )
  761. }
  762. render() {
  763. let isVisibleOn =
  764. this.state.methodParams.length > 0 &&
  765. this.state.paramsVisible &&
  766. this.state.paramsVisible === 'all'
  767. let isVisibleOff =
  768. this.state.methodParams.length > 0 &&
  769. this.state.paramsVisible &&
  770. this.state.paramsVisible === 'part'
  771. let actionMethodMenu = () => {
  772. return (
  773. <Menu className="method-select-menu" onClick={this.onMethodSelect}>
  774. {!this.state.methods || this.state.methods.length === 0 ? (
  775. <MenuItem key={'emptyContent'} className="empty-content">
  776. {i18n.t('EventView.jenga_action_block.emptyMethod')}
  777. </MenuItem>
  778. ) : (
  779. this.state.methods.map((method, index) => {
  780. let isAllowedMethod = this.isAllowedMethod(method)
  781. return (
  782. <MenuItem
  783. key={index}
  784. method={method}
  785. disabled={!isAllowedMethod}
  786. className={cls({
  787. selected: this.state.actionName === method.name,
  788. last: method.last
  789. })}
  790. >
  791. <div className="f--hlc">
  792. {isAllowedMethod ? (
  793. <div className="method-title">
  794. {method.locale
  795. ? method.locale[i18n.language]
  796. : method.name}
  797. </div>
  798. ) : (
  799. <Popover
  800. overlayClassName={'popover-tips method-popover-tips'}
  801. content={this.forbiddenTips()}
  802. placement="right"
  803. destroyTooltipOnHide={true}
  804. >
  805. <div className="method-title">
  806. {method.locale
  807. ? method.locale[i18n.language]
  808. : method.name}
  809. </div>
  810. </Popover>
  811. )}
  812. {this.getTipInfo(method)}
  813. </div>
  814. </MenuItem>
  815. )
  816. })
  817. )}
  818. </Menu>
  819. )
  820. }
  821. return (
  822. <div className="action-method flex-1">
  823. <div className="method-body flex-1">
  824. <div className="body-wrap f--hlc">
  825. <Dropdown
  826. trigger={['click']}
  827. getPopupContainer={triggerNode => triggerNode.parentNode}
  828. overlayClassName={'method-select-dropdown'}
  829. overlay={actionMethodMenu()}
  830. >
  831. <div className="method-select f--hlc">
  832. <div className="ant-dropdown-input f--hlc">
  833. <div
  834. className={cls('method-name f--hlc', {
  835. placeholder: !this.getActionLocaleName()
  836. })}
  837. >
  838. {this.getActionLocaleName() ||
  839. i18n.t('EventView.jenga_action_block.selectMethod')}
  840. {this.getTipInfo({ name: this.state.actionName })}
  841. </div>
  842. {this.getDelayContent() ? (
  843. <div className="delay-time">{this.getDelayContent()}</div>
  844. ) : null}
  845. </div>
  846. <div className="ant-dropdown-icon" />
  847. </div>
  848. </Dropdown>
  849. <BlockActionReload reload={this.onReloadAction.bind(this, false)} />
  850. <BlockActionDelay
  851. changeDelay={this.onChangeDelay.bind(this)}
  852. bid={this.props.bid}
  853. eventNodeId={this.props.eventNodeId}
  854. />
  855. </div>
  856. <BlockActionMethodParams
  857. params={this.state.methodParams}
  858. actionName={this.state.actionName}
  859. paramsVisible={this.state.paramsVisible}
  860. bid={this.props.bid}
  861. layer={this.props.layer}
  862. groupLayer={this.props.groupLayer}
  863. nestGroupLayer={this.props.nestGroupLayer}
  864. extraGapGroupLayer={this.props.extraGapGroupLayer}
  865. eventNodeId={this.props.eventNodeId}
  866. />
  867. </div>
  868. <div className="method-expand-control f--hcc">
  869. {this.state.methodParams.length === 0 ||
  870. !this.state.actionName ? null : (
  871. <button
  872. className={cls('btn-clear btn-toggle-params-visible', {
  873. 'visible-on': isVisibleOn,
  874. 'visible-off': isVisibleOff
  875. })}
  876. // onClick={this.onToggleParamsVisible}
  877. >
  878. {isVisibleOn && (
  879. <div
  880. className="icon"
  881. dangerouslySetInnerHTML={{ __html: iconStrObj.dropUpIcon }}
  882. />
  883. )}
  884. {isVisibleOff && (
  885. <div
  886. className="icon"
  887. dangerouslySetInnerHTML={{ __html: iconStrObj.dropDownIcon }}
  888. />
  889. )}
  890. </button>
  891. )}
  892. </div>
  893. </div>
  894. )
  895. }
  896. }