JengaItem.jsx 7.0 KB

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