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

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