mirror of https://github.com/langgenius/dify.git
fix
This commit is contained in:
parent
8ae46a8a14
commit
547df0b5fe
|
|
@ -155,6 +155,7 @@ export const NODES_INITIAL_DATA = {
|
|||
|
||||
export const NODE_WIDTH = 220
|
||||
export const X_OFFSET = 64
|
||||
export const NODE_WIDTH_X_OFFSET = NODE_WIDTH + X_OFFSET
|
||||
export const Y_OFFSET = 39
|
||||
export const TREE_DEEPTH = 20
|
||||
|
||||
|
|
|
|||
|
|
@ -14,20 +14,21 @@ import {
|
|||
Position,
|
||||
getConnectedEdges,
|
||||
getIncomers,
|
||||
getOutgoers,
|
||||
useReactFlow,
|
||||
useStoreApi,
|
||||
} from 'reactflow'
|
||||
import type {
|
||||
BlockEnum,
|
||||
Node,
|
||||
} from './types'
|
||||
import type { Node } from './types'
|
||||
import {
|
||||
BlockEnum,
|
||||
NodeRunningStatus,
|
||||
WorkflowRunningStatus,
|
||||
} from './types'
|
||||
import {
|
||||
NODES_EXTRA_DATA,
|
||||
NODES_INITIAL_DATA,
|
||||
NODE_WIDTH_X_OFFSET,
|
||||
Y_OFFSET,
|
||||
} from './constants'
|
||||
import { getLayoutByDagre } from './utils'
|
||||
import { useStore } from './store'
|
||||
|
|
@ -468,6 +469,8 @@ export const useWorkflow = () => {
|
|||
} = store.getState()
|
||||
const nodes = getNodes()
|
||||
const currentNode = nodes.find(node => node.id === currentNodeId)!
|
||||
const outgoers = getOutgoers(currentNode, nodes, edges).sort((a, b) => a.position.y - b.position.y)
|
||||
const lastOutgoer = outgoers[outgoers.length - 1]
|
||||
const nextNode: Node = {
|
||||
id: `${Date.now()}`,
|
||||
type: 'custom',
|
||||
|
|
@ -477,8 +480,8 @@ export const useWorkflow = () => {
|
|||
selected: true,
|
||||
},
|
||||
position: {
|
||||
x: currentNode.position.x + 304,
|
||||
y: currentNode.position.y,
|
||||
x: lastOutgoer ? lastOutgoer.position.x : currentNode.position.x + NODE_WIDTH_X_OFFSET,
|
||||
y: lastOutgoer ? lastOutgoer.position.y + lastOutgoer.height! + Y_OFFSET : currentNode.position.y,
|
||||
},
|
||||
targetPosition: Position.Left,
|
||||
}
|
||||
|
|
@ -504,6 +507,69 @@ export const useWorkflow = () => {
|
|||
handleSyncWorkflowDraft()
|
||||
}, [store, nodesInitialData, handleSyncWorkflowDraft])
|
||||
|
||||
const handleNodeAddPrev = useCallback((
|
||||
currentNodeId: string,
|
||||
nodeType: BlockEnum,
|
||||
targetHandle: string,
|
||||
toolDefaultValue?: ToolDefaultValue,
|
||||
) => {
|
||||
const { runningStatus } = useStore.getState()
|
||||
|
||||
if (runningStatus)
|
||||
return
|
||||
|
||||
const {
|
||||
getNodes,
|
||||
setNodes,
|
||||
edges,
|
||||
setEdges,
|
||||
} = store.getState()
|
||||
const nodes = getNodes()
|
||||
const currentNodeIndex = nodes.findIndex(node => node.id === currentNodeId)
|
||||
const currentNode = nodes[currentNodeIndex]
|
||||
const prevNode: Node = {
|
||||
id: `${Date.now()}`,
|
||||
type: 'custom',
|
||||
data: {
|
||||
...nodesInitialData[nodeType],
|
||||
...(toolDefaultValue || {}),
|
||||
selected: true,
|
||||
},
|
||||
position: {
|
||||
x: currentNode.position.x,
|
||||
y: currentNode.position.y,
|
||||
},
|
||||
targetPosition: Position.Left,
|
||||
}
|
||||
const newNodes = produce(nodes, (draft) => {
|
||||
draft.forEach((node, index) => {
|
||||
node.data.selected = false
|
||||
|
||||
if (index === currentNodeIndex)
|
||||
node.position.x += NODE_WIDTH_X_OFFSET
|
||||
})
|
||||
draft.push(prevNode)
|
||||
})
|
||||
setNodes(newNodes)
|
||||
|
||||
if (prevNode.type !== BlockEnum.IfElse && prevNode.type !== BlockEnum.QuestionClassifier) {
|
||||
const newEdge = {
|
||||
id: `${prevNode.id}-${currentNode.id}`,
|
||||
type: 'custom',
|
||||
source: prevNode.id,
|
||||
sourceHandle: 'source',
|
||||
target: currentNode.id,
|
||||
targetHandle,
|
||||
}
|
||||
const newEdges = produce(edges, (draft) => {
|
||||
draft.push(newEdge)
|
||||
})
|
||||
setEdges(newEdges)
|
||||
}
|
||||
|
||||
handleSyncWorkflowDraft()
|
||||
}, [store, nodesInitialData, handleSyncWorkflowDraft])
|
||||
|
||||
const handleNodeChange = useCallback((
|
||||
currentNodeId: string,
|
||||
nodeType: BlockEnum,
|
||||
|
|
@ -691,6 +757,7 @@ export const useWorkflow = () => {
|
|||
handleNodeDelete,
|
||||
handleNodeDataUpdate,
|
||||
handleNodeAddNext,
|
||||
handleNodeAddPrev,
|
||||
handleNodeChange,
|
||||
|
||||
handleEdgeEnter,
|
||||
|
|
|
|||
|
|
@ -4,21 +4,23 @@ import {
|
|||
useCallback,
|
||||
useState,
|
||||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useWorkflow } from '../../../hooks'
|
||||
import type { Node } from '../../../types'
|
||||
import { canRunBySingle } from '../../../utils'
|
||||
import PanelOperator from './panel-operator'
|
||||
import { Loading02 } from '@/app/components/base/icons/src/vender/line/general'
|
||||
import {
|
||||
Play,
|
||||
Stop,
|
||||
} from '@/app/components/base/icons/src/vender/line/mediaAndDevices'
|
||||
import TooltipPlus from '@/app/components/base/tooltip-plus'
|
||||
|
||||
type NodeControlProps = Pick<Node, 'id' | 'data'>
|
||||
const NodeControl: FC<NodeControlProps> = ({
|
||||
id,
|
||||
data,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const [open, setOpen] = useState(false)
|
||||
const { handleNodeDataUpdate } = useWorkflow()
|
||||
|
||||
|
|
@ -38,14 +40,6 @@ const NodeControl: FC<NodeControlProps> = ({
|
|||
className='flex items-center px-0.5 h-6 bg-white rounded-lg border-[0.5px] border-gray-100 shadow-xs text-gray-500'
|
||||
onClick={e => e.stopPropagation()}
|
||||
>
|
||||
{
|
||||
data._isSingleRun && (
|
||||
<div className='flex items-center mr-1 px-1 h-5 rounded-md bg-primary-50 text-xs font-medium text-primary-600'>
|
||||
<Loading02 className='mr-1 w-3 h-3 animate-spin' />
|
||||
RUNNING
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
canRunBySingle(data.type) && (
|
||||
<div
|
||||
|
|
@ -53,14 +47,22 @@ const NodeControl: FC<NodeControlProps> = ({
|
|||
onClick={() => {
|
||||
handleNodeDataUpdate({
|
||||
id,
|
||||
data: { _isSingleRun: !data._isSingleRun },
|
||||
data: {
|
||||
_isSingleRun: !data._isSingleRun,
|
||||
},
|
||||
})
|
||||
}}
|
||||
>
|
||||
{
|
||||
data._isSingleRun
|
||||
? <Stop className='w-3 h-3' />
|
||||
: <Play className='w-3 h-3' />
|
||||
: (
|
||||
<TooltipPlus
|
||||
popupContent={t('workflow.panel.runThisStep')}
|
||||
>
|
||||
<Play className='w-3 h-3' />
|
||||
</TooltipPlus>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ export const NodeTargetHandle = ({
|
|||
nodeSelectorClassName,
|
||||
}: NodeHandleProps) => {
|
||||
const [open, setOpen] = useState(false)
|
||||
const { handleNodeAddPrev } = useWorkflow()
|
||||
const edges = useEdges()
|
||||
const connectedEdges = getConnectedEdges([{ id } as Node], edges)
|
||||
const connected = connectedEdges.find(edge => edge.targetHandle === handleId && edge.target === id)
|
||||
|
|
@ -42,6 +43,9 @@ export const NodeTargetHandle = ({
|
|||
if (!connected)
|
||||
setOpen(v => !v)
|
||||
}, [connected])
|
||||
const handleSelect = useCallback((type: BlockEnum, toolDefaultValue?: ToolDefaultValue) => {
|
||||
handleNodeAddPrev(id, type, handleId, toolDefaultValue)
|
||||
}, [handleNodeAddPrev, id, handleId])
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -64,7 +68,7 @@ export const NodeTargetHandle = ({
|
|||
<BlockSelector
|
||||
open={open}
|
||||
onOpenChange={handleOpenChange}
|
||||
onSelect={() => {}}
|
||||
onSelect={handleSelect}
|
||||
asChild
|
||||
placement='left'
|
||||
triggerClassName={open => `
|
||||
|
|
|
|||
|
|
@ -106,12 +106,12 @@ const BaseNode: FC<BaseNodeProps> = ({
|
|||
)
|
||||
}
|
||||
</div>
|
||||
<div className='mb-1'>
|
||||
<div className='pb-1'>
|
||||
{cloneElement(children, { id, data })}
|
||||
</div>
|
||||
{
|
||||
data.desc && (
|
||||
<div className='px-3 pt-s1 pb-2 text-xs leading-[18px] text-gray-500 whitespace-pre-line break-words'>
|
||||
<div className='px-3 pt-1 pb-2 text-xs leading-[18px] text-gray-500 whitespace-pre-line break-words'>
|
||||
{data.desc}
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -33,24 +33,28 @@ const Node: FC<NodeProps<QuestionClassifierNodeType>> = (props) => {
|
|||
readonly
|
||||
/>
|
||||
)}
|
||||
<div className='mt-2 space-y-0.5'>
|
||||
{topics.map((topic, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className='relative'
|
||||
>
|
||||
<InfoPanel
|
||||
title={`${t(`${i18nPrefix}.class`)} ${index + 1}`}
|
||||
content={topic.name}
|
||||
/>
|
||||
<NodeSourceHandle
|
||||
{...props}
|
||||
handleId={topic.id}
|
||||
handleClassName='!top-1/2 !-translate-y-1/2 !-right-[21px]'
|
||||
/>
|
||||
{
|
||||
!!topics.length && (
|
||||
<div className='mt-2 space-y-0.5'>
|
||||
{topics.map((topic, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className='relative'
|
||||
>
|
||||
<InfoPanel
|
||||
title={`${t(`${i18nPrefix}.class`)} ${index + 1}`}
|
||||
content={topic.name}
|
||||
/>
|
||||
<NodeSourceHandle
|
||||
{...props}
|
||||
handleId={topic.id}
|
||||
handleClassName='!top-1/2 !-translate-y-1/2 !-right-[21px]'
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,6 +171,6 @@ export const canRunBySingle = (nodeType: BlockEnum) => {
|
|||
|| nodeType === BlockEnum.Tool
|
||||
}
|
||||
|
||||
export const getVariables = () => {
|
||||
export const getVariables = (currentNodeId: string) => {
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue