BlockActionMethod.jsx 27 KB

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