JengaItem.jsx 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import React from 'react'
  2. import cls from 'classnames'
  3. import ResizeObserver from 'resize-observer-polyfill'
  4. import treeStores from 'stores/tree'
  5. import newEventStores from 'stores/newEvent'
  6. import { getEventNodeById, minScrollJengaPanel } from 'stores/funcs/newEvent'
  7. import { nodeIsSystem, nodeIsInModule } from 'stores/funcs/nodeType'
  8. import JengaItemTitle from './JengaItemTitle'
  9. import JengaItemEvent from './JengaItemEvent'
  10. export default class JengaItem extends React.Component {
  11. constructor(props) {
  12. super(props)
  13. this.curEventNodeId = newEventStores.curEventNodeId
  14. this.state = {
  15. isActive: this.isCurEventNodeId(this.curEventNodeId),
  16. isEnable: this.isEnable(),
  17. sysList: this.getCurSysList()
  18. }
  19. this.onTreeChange = this.onTreeChange.bind(this)
  20. this.onEventChange = this.onEventChange.bind(this)
  21. this.onActiveObserver = this.onActiveObserver.bind(this)
  22. this.onInactiveObserver = this.onInactiveObserver.bind(this)
  23. this.onResize = this.onResize.bind(this)
  24. this.isCurEventNodeId = this.isCurEventNodeId.bind(this)
  25. this.isEnable = this.isEnable.bind(this)
  26. this.getCurSysList = this.getCurSysList.bind(this)
  27. this.updateCurSysList = this.updateCurSysList.bind(this)
  28. this.getSysList = this.getSysList.bind(this)
  29. this.getModuleSysList = this.getModuleSysList.bind(this)
  30. }
  31. componentDidMount() {
  32. window.addEventListener('resize', this.onResize)
  33. this.unsubscribe = newEventStores.listen(this.onEventChange)
  34. this.unsubscribeTree = treeStores.listen(this.onTreeChange)
  35. this.onActiveObserver()
  36. }
  37. componentWillUnmount() {
  38. window.removeEventListener('resize', this.onResize)
  39. this.unsubscribe()
  40. this.unsubscribeTree()
  41. this.onInactiveObserver()
  42. }
  43. componentDidUpdate(preProps) {
  44. if (preProps.eventNodeId !== this.props.eventNodeId) {
  45. this.setState({
  46. isActive: this.isCurEventNodeId(this.curEventNodeId),
  47. isEnable: this.isEnable(),
  48. sysList: this.getCurSysList()
  49. })
  50. }
  51. }
  52. onTreeChange(status) {
  53. let obj = {}
  54. if (status && status.types) {
  55. if (
  56. status.types.includes('curNodeIdList') ||
  57. status.types.includes('curRootId')
  58. ) {
  59. obj.sysList = this.getCurSysList()
  60. }
  61. }
  62. if (Object.keys(obj).length > 0) {
  63. this.setState(obj)
  64. }
  65. }
  66. onEventChange(status) {
  67. let obj = {}
  68. if (status && status.types) {
  69. if (status.types.includes('curEventNodeId')) {
  70. if (this.curEventNodeId !== status.data.curEventNodeId) {
  71. let curEventNodeId = status.data.curEventNodeId
  72. if (this.isCurEventNodeId(status.data.curEventNodeId)) {
  73. this.updateCurSysList(obj, curEventNodeId, this.curEventNodeId)
  74. }
  75. this.curEventNodeId = curEventNodeId
  76. let isEnable = this.isEnable()
  77. if (isEnable !== this.state.isEnable) {
  78. obj.isEnable = isEnable
  79. }
  80. let isActive = this.isCurEventNodeId(this.curEventNodeId)
  81. if (isActive !== this.state.isActive) {
  82. obj.isActive = isActive
  83. }
  84. }
  85. }
  86. if (status.types.includes('toggleEvent')) {
  87. if (status.data.affectEventNodeId === this.curEventNodeId) {
  88. if (status.data.prop === 'enable') {
  89. if (this.isCurEventNodeId(status.data.affectEventNodeId)) {
  90. let isEnable = this.isEnable()
  91. if (isEnable !== this.state.isEnable) {
  92. obj.isEnable = isEnable
  93. }
  94. }
  95. }
  96. }
  97. }
  98. }
  99. if (Object.keys(obj).length > 0) {
  100. this.setState(obj)
  101. }
  102. }
  103. isCurEventNodeId(curEventNodeId) {
  104. return !this.props.eventNodeId || this.props.eventNodeId === curEventNodeId
  105. }
  106. isEnable() {
  107. let isEnable = true
  108. let nodeId = this.props.eventNodeId || this.curEventNodeId
  109. if (nodeId) {
  110. let node = getEventNodeById(nodeId)
  111. if (node && node.events && node.events.enable === false) {
  112. isEnable = false
  113. }
  114. }
  115. return isEnable
  116. }
  117. onActiveObserver() {
  118. // 选择目标节点
  119. let target = document.querySelector('.jenga-item')
  120. // 创建观察者对象
  121. this.observer = new ResizeObserver(entries => {
  122. let entry = entries[0]
  123. if (entry.contentRect.height !== undefined) {
  124. minScrollJengaPanel()
  125. }
  126. })
  127. // 传入目标节点和观察选项
  128. this.observer.observe(target)
  129. }
  130. onInactiveObserver() {
  131. this.observer && this.observer.disconnect()
  132. }
  133. onResize() {
  134. minScrollJengaPanel()
  135. }
  136. getCurSysList() {
  137. let sysList = []
  138. let curEventNodeId = this.props.eventNodeId || this.curEventNodeId
  139. let moduleRootId = nodeIsInModule(curEventNodeId, true)
  140. // 当前的node是在module内刷新sysList
  141. if (moduleRootId) {
  142. sysList = this.getModuleSysList(moduleRootId)
  143. } else {
  144. // module内的重新获取sysList
  145. sysList = this.getSysList()
  146. }
  147. return sysList
  148. }
  149. updateCurSysList(obj, curNodeId, preNodeId) {
  150. let moduleRootId = nodeIsInModule(curNodeId, true)
  151. // 当前的node是在module内刷新sysList
  152. if (moduleRootId) {
  153. obj.sysList = this.getModuleSysList(moduleRootId)
  154. } else if (nodeIsInModule(preNodeId)) {
  155. // module内的重新获取sysList
  156. obj.sysList = this.getSysList()
  157. }
  158. }
  159. getSysList() {
  160. let result = []
  161. let list = treeStores.curNodeIdList
  162. for (let i = 0, len = list.length; i < len; i++) {
  163. let node = treeStores.getNodeById(list[i])
  164. if (node && node.type === 'data-module') {
  165. // 不计算内部的sys
  166. let lastNodeId = node.id
  167. while (node && node.children && node.children.length > 0) {
  168. node = treeStores.getNodeById(node.children[node.children.length - 1])
  169. }
  170. if (lastNodeId !== node.id) {
  171. lastNodeId = node.id
  172. let lastIndex = list.indexOf(lastNodeId)
  173. if (i < lastIndex && lastIndex < len) {
  174. i = lastIndex
  175. }
  176. }
  177. } else if (node && nodeIsSystem(node.type)) {
  178. result.push(list[i])
  179. }
  180. }
  181. return result
  182. }
  183. getModuleSysList(moduleRootId) {
  184. let result = []
  185. let loopNode = nodeId => {
  186. let node = treeStores.getNodeById(nodeId)
  187. if (node) {
  188. if (nodeIsSystem(node.type)) {
  189. result.push(node.id)
  190. }
  191. if (node.children) {
  192. node.children.forEach(childId => {
  193. loopNode(childId)
  194. })
  195. }
  196. }
  197. }
  198. loopNode(moduleRootId)
  199. return result
  200. }
  201. render() {
  202. return (
  203. <div
  204. className={cls('jenga-item', {
  205. active: this.state.isActive,
  206. disabled: !this.state.isEnable
  207. })}
  208. >
  209. <JengaItemTitle eventNodeId={this.props.eventNodeId} />
  210. <JengaItemEvent
  211. eventNodeId={this.props.eventNodeId}
  212. visibleBlockIds={this.props.visibleBlockIds}
  213. />
  214. </div>
  215. )
  216. }
  217. }