wwf
2 天以前 a430284aa21e3ae1f0d5654e55b2ad2852519cc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import { memo, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import {
  getConnectedEdges,
  getOutgoers,
  useEdges,
  useStoreApi,
} from 'reactflow'
import { useToolIcon } from '../../../../hooks'
import BlockIcon from '../../../../block-icon'
import type {
  Node,
} from '../../../../types'
import { BlockEnum } from '../../../../types'
import Line from './line'
import Container from './container'
import { hasErrorHandleNode } from '@/app/components/workflow/utils'
import { ErrorHandleTypeEnum } from '@/app/components/workflow/nodes/_base/components/error-handle/types'
 
type NextStepProps = {
  selectedNode: Node
}
const NextStep = ({
  selectedNode,
}: NextStepProps) => {
  const { t } = useTranslation()
  const data = selectedNode.data
  const toolIcon = useToolIcon(data)
  const store = useStoreApi()
  const branches = useMemo(() => {
    return data._targetBranches || []
  }, [data])
  const edges = useEdges()
  const outgoers = getOutgoers(selectedNode as Node, store.getState().getNodes(), edges)
  const connectedEdges = getConnectedEdges([selectedNode] as Node[], edges).filter(edge => edge.source === selectedNode!.id)
 
  const list = useMemo(() => {
    let items = []
    if (branches?.length) {
      items = branches.map((branch, index) => {
        const connected = connectedEdges.filter(edge => edge.sourceHandle === branch.id)
        const nextNodes = connected.map(edge => outgoers.find(outgoer => outgoer.id === edge.target)!)
 
        return {
          branch: {
            ...branch,
            name: data.type === BlockEnum.QuestionClassifier ? `${t('workflow.nodes.questionClassifiers.class')} ${index + 1}` : branch.name,
          },
          nextNodes,
        }
      })
    }
    else {
      const connected = connectedEdges.filter(edge => edge.sourceHandle === 'source')
      const nextNodes = connected.map(edge => outgoers.find(outgoer => outgoer.id === edge.target)!)
 
      items = [{
        branch: {
          id: '',
          name: '',
        },
        nextNodes,
      }]
 
      if (data.error_strategy === ErrorHandleTypeEnum.failBranch && hasErrorHandleNode(data.type)) {
        const connected = connectedEdges.filter(edge => edge.sourceHandle === ErrorHandleTypeEnum.failBranch)
        const nextNodes = connected.map(edge => outgoers.find(outgoer => outgoer.id === edge.target)!)
 
        items.push({
          branch: {
            id: ErrorHandleTypeEnum.failBranch,
            name: t('workflow.common.onFailure'),
          },
          nextNodes,
        })
      }
    }
 
    return items
  }, [branches, connectedEdges, data.error_strategy, data.type, outgoers, t])
 
  return (
    <div className='flex py-1'>
      <div className='shrink-0 relative flex items-center justify-center w-9 h-9 bg-background-default rounded-lg border-[0.5px] border-divider-regular shadow-xs'>
        <BlockIcon
          type={selectedNode!.data.type}
          toolIcon={toolIcon}
        />
      </div>
      <Line
        list={list.length ? list.map(item => item.nextNodes.length + 1) : [1]}
      />
      <div className='grow space-y-2'>
        {
          list.map((item, index) => {
            return (
              <Container
                key={index}
                nodeId={selectedNode!.id}
                nodeData={selectedNode!.data}
                sourceHandle={item.branch.id}
                nextNodes={item.nextNodes}
                branchName={item.branch.name}
                isFailBranch={item.branch.id === ErrorHandleTypeEnum.failBranch}
              />
            )
          })
        }
      </div>
    </div>
  )
}
 
export default memo(NextStep)