use-workflow-node-loop-started.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import { useCallback } from 'react'
  2. import {
  3. useReactFlow,
  4. useStoreApi,
  5. } from 'reactflow'
  6. import produce from 'immer'
  7. import { useWorkflowStore } from '@/app/components/workflow/store'
  8. import type { LoopStartedResponse } from '@/types/workflow'
  9. import { NodeRunningStatus } from '@/app/components/workflow/types'
  10. import { DEFAULT_LOOP_TIMES } from '@/app/components/workflow/constants'
  11. export const useWorkflowNodeLoopStarted = () => {
  12. const store = useStoreApi()
  13. const reactflow = useReactFlow()
  14. const workflowStore = useWorkflowStore()
  15. const handleWorkflowNodeLoopStarted = useCallback((
  16. params: LoopStartedResponse,
  17. containerParams: {
  18. clientWidth: number,
  19. clientHeight: number,
  20. },
  21. ) => {
  22. const { data } = params
  23. const {
  24. workflowRunningData,
  25. setWorkflowRunningData,
  26. setLoopTimes,
  27. } = workflowStore.getState()
  28. const {
  29. getNodes,
  30. setNodes,
  31. edges,
  32. setEdges,
  33. transform,
  34. } = store.getState()
  35. const nodes = getNodes()
  36. setWorkflowRunningData(produce(workflowRunningData!, (draft) => {
  37. draft.tracing!.push({
  38. ...data,
  39. status: NodeRunningStatus.Running,
  40. })
  41. }))
  42. setLoopTimes(DEFAULT_LOOP_TIMES)
  43. const {
  44. setViewport,
  45. } = reactflow
  46. const currentNodeIndex = nodes.findIndex(node => node.id === data.node_id)
  47. const currentNode = nodes[currentNodeIndex]
  48. const position = currentNode.position
  49. const zoom = transform[2]
  50. if (!currentNode.parentId) {
  51. setViewport({
  52. x: (containerParams.clientWidth - 400 - currentNode.width! * zoom) / 2 - position.x * zoom,
  53. y: (containerParams.clientHeight - currentNode.height! * zoom) / 2 - position.y * zoom,
  54. zoom: transform[2],
  55. })
  56. }
  57. const newNodes = produce(nodes, (draft) => {
  58. draft[currentNodeIndex].data._runningStatus = NodeRunningStatus.Running
  59. draft[currentNodeIndex].data._loopLength = data.metadata.loop_length
  60. draft[currentNodeIndex].data._waitingRun = false
  61. })
  62. setNodes(newNodes)
  63. const newEdges = produce(edges, (draft) => {
  64. const incomeEdges = draft.filter(edge => edge.target === data.node_id)
  65. incomeEdges.forEach((edge) => {
  66. edge.data = {
  67. ...edge.data,
  68. _sourceRunningStatus: nodes.find(node => node.id === edge.source)!.data._runningStatus,
  69. _targetRunningStatus: NodeRunningStatus.Running,
  70. _waitingRun: false,
  71. }
  72. })
  73. })
  74. setEdges(newEdges)
  75. }, [workflowStore, store, reactflow])
  76. return {
  77. handleWorkflowNodeLoopStarted,
  78. }
  79. }