feat: workflow new nodes (#4683)
Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: Patryk Garstecki <patryk20120@yahoo.pl> Co-authored-by: Sebastian.W <thiner@gmail.com> Co-authored-by: 呆萌闷油瓶 <253605712@qq.com> Co-authored-by: takatost <takatost@users.noreply.github.com> Co-authored-by: rechardwang <wh_goodjob@163.com> Co-authored-by: Nite Knite <nkCoding@gmail.com> Co-authored-by: Chenhe Gu <guchenhe@gmail.com> Co-authored-by: Joshua <138381132+joshua20231026@users.noreply.github.com> Co-authored-by: Weaxs <459312872@qq.com> Co-authored-by: Ikko Eltociear Ashimine <eltociear@gmail.com> Co-authored-by: leejoo0 <81673835+leejoo0@users.noreply.github.com> Co-authored-by: JzoNg <jzongcode@gmail.com> Co-authored-by: sino <sino2322@gmail.com> Co-authored-by: Vikey Chen <vikeytk@gmail.com> Co-authored-by: wanghl <Wang-HL@users.noreply.github.com> Co-authored-by: Haolin Wang-汪皓临 <haolin.wang@atlaslovestravel.com> Co-authored-by: Zixuan Cheng <61724187+Theysua@users.noreply.github.com> Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> Co-authored-by: Bowen Liang <bowenliang@apache.org> Co-authored-by: Bowen Liang <liangbowen@gf.com.cn> Co-authored-by: fanghongtai <42790567+fanghongtai@users.noreply.github.com> Co-authored-by: wxfanghongtai <wxfanghongtai@gf.com.cn> Co-authored-by: Matri <qjp@bithuman.io> Co-authored-by: Benjamin <benjaminx@gmail.com>
This commit is contained in:
@@ -5,9 +5,11 @@ import type {
|
||||
import {
|
||||
cloneElement,
|
||||
memo,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
} from 'react'
|
||||
import cn from 'classnames'
|
||||
import type { NodeProps } from '../../types'
|
||||
import {
|
||||
BlockEnum,
|
||||
@@ -17,11 +19,14 @@ import {
|
||||
useNodesReadOnly,
|
||||
useToolIcon,
|
||||
} from '../../hooks'
|
||||
import { useNodeIterationInteractions } from '../iteration/use-interactions'
|
||||
import {
|
||||
NodeSourceHandle,
|
||||
NodeTargetHandle,
|
||||
} from './components/node-handle'
|
||||
import NodeResizer from './components/node-resizer'
|
||||
import NodeControl from './components/node-control'
|
||||
import AddVariablePopupWithPosition from './components/add-variable-popup-with-position'
|
||||
import BlockIcon from '@/app/components/workflow/block-icon'
|
||||
import {
|
||||
CheckCircle,
|
||||
@@ -40,9 +45,24 @@ const BaseNode: FC<BaseNodeProps> = ({
|
||||
}) => {
|
||||
const nodeRef = useRef<HTMLDivElement>(null)
|
||||
const { nodesReadOnly } = useNodesReadOnly()
|
||||
const { handleNodeIterationChildSizeChange } = useNodeIterationInteractions()
|
||||
const toolIcon = useToolIcon(data)
|
||||
|
||||
const showSelectedBorder = data.selected || data._isBundled
|
||||
useEffect(() => {
|
||||
if (nodeRef.current && data.selected && data.isInIteration) {
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
handleNodeIterationChildSizeChange(id)
|
||||
})
|
||||
|
||||
resizeObserver.observe(nodeRef.current)
|
||||
|
||||
return () => {
|
||||
resizeObserver.disconnect()
|
||||
}
|
||||
}
|
||||
}, [data.isInIteration, data.selected, id, handleNodeIterationChildSizeChange])
|
||||
|
||||
const showSelectedBorder = data.selected || data._isBundled || data._isEntering
|
||||
const {
|
||||
showRunningBorder,
|
||||
showSuccessBorder,
|
||||
@@ -57,26 +77,47 @@ const BaseNode: FC<BaseNodeProps> = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`
|
||||
flex border-[2px] rounded-2xl
|
||||
${(showSelectedBorder && !data._isInvalidConnection) ? 'border-primary-600' : 'border-transparent'}
|
||||
`}
|
||||
className={cn(
|
||||
'flex border-[2px] rounded-2xl',
|
||||
showSelectedBorder ? 'border-primary-600' : 'border-transparent',
|
||||
)}
|
||||
ref={nodeRef}
|
||||
style={{
|
||||
width: data.type === BlockEnum.Iteration ? data.width : 'auto',
|
||||
height: data.type === BlockEnum.Iteration ? data.height : 'auto',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={`
|
||||
group relative pb-1 w-[240px] bg-[#fcfdff] shadow-xs
|
||||
border border-transparent rounded-[15px]
|
||||
${!data._runningStatus && 'hover:shadow-lg'}
|
||||
${showRunningBorder && '!border-primary-500'}
|
||||
${showSuccessBorder && '!border-[#12B76A]'}
|
||||
${showFailedBorder && '!border-[#F04438]'}
|
||||
${data._isInvalidConnection && '!border-[#F04438]'}
|
||||
${data._isBundled && '!shadow-lg'}
|
||||
`}
|
||||
className={cn(
|
||||
'group relative pb-1 shadow-xs',
|
||||
'border border-transparent rounded-[15px]',
|
||||
data.type !== BlockEnum.Iteration && 'w-[240px] bg-[#fcfdff]',
|
||||
data.type === BlockEnum.Iteration && 'flex flex-col w-full h-full bg-[#fcfdff]/80',
|
||||
!data._runningStatus && 'hover:shadow-lg',
|
||||
showRunningBorder && '!border-primary-500',
|
||||
showSuccessBorder && '!border-[#12B76A]',
|
||||
showFailedBorder && '!border-[#F04438]',
|
||||
data._isBundled && '!shadow-lg',
|
||||
)}
|
||||
>
|
||||
{
|
||||
data.type !== BlockEnum.VariableAssigner && !data._isCandidate && (
|
||||
data._showAddVariablePopup && (
|
||||
<AddVariablePopupWithPosition
|
||||
nodeId={id}
|
||||
nodeData={data}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
data.type === BlockEnum.Iteration && (
|
||||
<NodeResizer
|
||||
nodeId={id}
|
||||
nodeData={data}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
data.type !== BlockEnum.VariableAssigner && data.type !== BlockEnum.VariableAggregator && !data._isCandidate && (
|
||||
<NodeTargetHandle
|
||||
id={id}
|
||||
data={data}
|
||||
@@ -103,7 +144,10 @@ const BaseNode: FC<BaseNodeProps> = ({
|
||||
/>
|
||||
)
|
||||
}
|
||||
<div className='flex items-center px-3 pt-3 pb-2'>
|
||||
<div className={cn(
|
||||
'flex items-center px-3 pt-3 pb-2 rounded-t-2xl',
|
||||
data.type === BlockEnum.Iteration && 'bg-[rgba(250,252,255,0.9)]',
|
||||
)}>
|
||||
<BlockIcon
|
||||
className='shrink-0 mr-2'
|
||||
type={data.type}
|
||||
@@ -116,6 +160,13 @@ const BaseNode: FC<BaseNodeProps> = ({
|
||||
>
|
||||
{data.title}
|
||||
</div>
|
||||
{
|
||||
data._iterationLength && data._iterationIndex && data._runningStatus === NodeRunningStatus.Running && (
|
||||
<div className='mr-1.5 text-xs font-medium text-primary-600'>
|
||||
{data._iterationIndex}/{data._iterationLength}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
(data._runningStatus === NodeRunningStatus.Running || data._singleRunningStatus === NodeRunningStatus.Running) && (
|
||||
<Loading02 className='w-3.5 h-3.5 text-primary-600 animate-spin' />
|
||||
@@ -132,9 +183,20 @@ const BaseNode: FC<BaseNodeProps> = ({
|
||||
)
|
||||
}
|
||||
</div>
|
||||
{cloneElement(children, { id, data })}
|
||||
{
|
||||
data.desc && (
|
||||
data.type !== BlockEnum.Iteration && (
|
||||
cloneElement(children, { id, data })
|
||||
)
|
||||
}
|
||||
{
|
||||
data.type === BlockEnum.Iteration && (
|
||||
<div className='grow pl-1 pr-1 pb-1'>
|
||||
{cloneElement(children, { id, data })}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
data.desc && data.type !== BlockEnum.Iteration && (
|
||||
<div className='px-3 pt-1 pb-2 text-xs leading-[18px] text-gray-500 whitespace-pre-line break-words'>
|
||||
{data.desc}
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user