| | |
| | | hasRetryNode, |
| | | } from '../../utils' |
| | | import { useNodeIterationInteractions } from '../iteration/use-interactions' |
| | | import { useNodeLoopInteractions } from '../loop/use-interactions' |
| | | import type { IterationNodeType } from '../iteration/types' |
| | | import { |
| | | NodeSourceHandle, |
| | |
| | | const nodeRef = useRef<HTMLDivElement>(null) |
| | | const { nodesReadOnly } = useNodesReadOnly() |
| | | const { handleNodeIterationChildSizeChange } = useNodeIterationInteractions() |
| | | const { handleNodeLoopChildSizeChange } = useNodeLoopInteractions() |
| | | const toolIcon = useToolIcon(data) |
| | | |
| | | useEffect(() => { |
| | |
| | | } |
| | | }, [data.isInIteration, data.selected, id, handleNodeIterationChildSizeChange]) |
| | | |
| | | useEffect(() => { |
| | | if (nodeRef.current && data.selected && data.isInLoop) { |
| | | const resizeObserver = new ResizeObserver(() => { |
| | | handleNodeLoopChildSizeChange(id) |
| | | }) |
| | | |
| | | resizeObserver.observe(nodeRef.current) |
| | | |
| | | return () => { |
| | | resizeObserver.disconnect() |
| | | } |
| | | } |
| | | }, [data.isInLoop, data.selected, id, handleNodeLoopChildSizeChange]) |
| | | |
| | | const showSelectedBorder = data.selected || data._isBundled || data._isEntering |
| | | const { |
| | | showRunningBorder, |
| | |
| | | } |
| | | }, [data._runningStatus, showSelectedBorder]) |
| | | |
| | | const LoopIndex = useMemo(() => { |
| | | let text = '' |
| | | |
| | | if (data._runningStatus === NodeRunningStatus.Running) |
| | | text = t('workflow.nodes.loop.currentLoopCount', { count: data._loopIndex }) |
| | | if (data._runningStatus === NodeRunningStatus.Succeeded || data._runningStatus === NodeRunningStatus.Failed) |
| | | text = t('workflow.nodes.loop.totalLoopCount', { count: data._loopIndex }) |
| | | |
| | | if (text) { |
| | | return ( |
| | | <div |
| | | className={cn( |
| | | 'system-xs-medium mr-2 text-text-tertiary', |
| | | data._runningStatus === NodeRunningStatus.Running && 'text-text-accent', |
| | | )} |
| | | > |
| | | {text} |
| | | </div> |
| | | ) |
| | | } |
| | | |
| | | return null |
| | | }, [data._loopIndex, data._runningStatus, t]) |
| | | |
| | | return ( |
| | | <div |
| | | className={cn( |
| | | 'flex rounded-2xl border-[2px]', |
| | | 'flex border-[2px] rounded-2xl', |
| | | showSelectedBorder ? 'border-components-option-card-option-selected-border' : 'border-transparent', |
| | | !showSelectedBorder && data._inParallelHovering && 'border-workflow-block-border-highlight', |
| | | data._waitingRun && 'opacity-70', |
| | | )} |
| | | ref={nodeRef} |
| | | style={{ |
| | | width: (data.type === BlockEnum.Iteration || data.type === BlockEnum.Loop) ? data.width : 'auto', |
| | | height: (data.type === BlockEnum.Iteration || data.type === BlockEnum.Loop) ? data.height : 'auto', |
| | | width: data.type === BlockEnum.Iteration ? data.width : 'auto', |
| | | height: data.type === BlockEnum.Iteration ? data.height : 'auto', |
| | | }} |
| | | > |
| | | <div |
| | | className={cn( |
| | | 'group relative pb-1 shadow-xs', |
| | | 'rounded-[15px] border border-transparent', |
| | | (data.type !== BlockEnum.Iteration && data.type !== BlockEnum.Loop) && 'w-[240px] bg-workflow-block-bg', |
| | | (data.type === BlockEnum.Iteration || data.type === BlockEnum.Loop) && 'flex h-full w-full flex-col border-workflow-block-border bg-workflow-block-bg-transparent', |
| | | 'border border-transparent rounded-[15px]', |
| | | data.type !== BlockEnum.Iteration && 'w-[240px] bg-workflow-block-bg', |
| | | data.type === BlockEnum.Iteration && 'flex flex-col w-full h-full bg-workflow-block-bg-transparent border-workflow-block-border', |
| | | !data._runningStatus && 'hover:shadow-lg', |
| | | showRunningBorder && '!border-state-accent-solid', |
| | | showSuccessBorder && '!border-state-success-solid', |
| | |
| | | > |
| | | { |
| | | data._inParallelHovering && ( |
| | | <div className='top system-2xs-medium-uppercase absolute -top-2.5 left-2 z-10 text-text-tertiary'> |
| | | <div className='absolute left-2 -top-2.5 top system-2xs-medium-uppercase text-text-tertiary z-10'> |
| | | {t('workflow.common.parallelRun')} |
| | | </div> |
| | | ) |
| | |
| | | } |
| | | { |
| | | data.type === BlockEnum.Iteration && ( |
| | | <NodeResizer |
| | | nodeId={id} |
| | | nodeData={data} |
| | | /> |
| | | ) |
| | | } |
| | | { |
| | | data.type === BlockEnum.Loop && ( |
| | | <NodeResizer |
| | | nodeId={id} |
| | | nodeData={data} |
| | |
| | | ) |
| | | } |
| | | <div className={cn( |
| | | 'flex items-center rounded-t-2xl px-3 pb-2 pt-3', |
| | | (data.type === BlockEnum.Iteration || data.type === BlockEnum.Loop) && 'bg-transparent', |
| | | 'flex items-center px-3 pt-3 pb-2 rounded-t-2xl', |
| | | data.type === BlockEnum.Iteration && 'bg-transparent', |
| | | )}> |
| | | <BlockIcon |
| | | className='mr-2 shrink-0' |
| | | className='shrink-0 mr-2' |
| | | type={data.type} |
| | | size='md' |
| | | toolIcon={toolIcon} |
| | | /> |
| | | <div |
| | | title={data.title} |
| | | className='system-sm-semibold-uppercase mr-1 flex grow items-center truncate text-text-primary' |
| | | className='grow mr-1 system-sm-semibold-uppercase text-text-primary truncate flex items-center' |
| | | > |
| | | <div> |
| | | {data.title} |
| | |
| | | {t('workflow.nodes.iteration.parallelModeEnableDesc')} |
| | | </div>} |
| | | > |
| | | <div className='system-2xs-medium-uppercase ml-1 flex items-center justify-center rounded-[5px] border-[1px] border-text-warning px-[5px] py-[3px] text-text-warning '> |
| | | <div className='flex justify-center items-center px-[5px] py-[3px] ml-1 border-[1px] border-text-warning rounded-[5px] text-text-warning system-2xs-medium-uppercase '> |
| | | {t('workflow.nodes.iteration.parallelModeUpper')} |
| | | </div> |
| | | </Tooltip> |
| | |
| | | ) |
| | | } |
| | | { |
| | | data.type === BlockEnum.Loop && data._loopIndex && LoopIndex |
| | | } |
| | | { |
| | | (data._runningStatus === NodeRunningStatus.Running || data._singleRunningStatus === NodeRunningStatus.Running) && ( |
| | | <RiLoader2Line className='h-3.5 w-3.5 animate-spin text-text-accent' /> |
| | | <RiLoader2Line className='w-3.5 h-3.5 text-text-accent animate-spin' /> |
| | | ) |
| | | } |
| | | { |
| | | data._runningStatus === NodeRunningStatus.Succeeded && ( |
| | | <RiCheckboxCircleFill className='h-3.5 w-3.5 text-text-success' /> |
| | | <RiCheckboxCircleFill className='w-3.5 h-3.5 text-text-success' /> |
| | | ) |
| | | } |
| | | { |
| | | data._runningStatus === NodeRunningStatus.Failed && ( |
| | | <RiErrorWarningFill className='h-3.5 w-3.5 text-text-destructive' /> |
| | | <RiErrorWarningFill className='w-3.5 h-3.5 text-text-destructive' /> |
| | | ) |
| | | } |
| | | { |
| | | data._runningStatus === NodeRunningStatus.Exception && ( |
| | | <RiAlertFill className='h-3.5 w-3.5 text-text-warning-secondary' /> |
| | | <RiAlertFill className='w-3.5 h-3.5 text-text-warning-secondary' /> |
| | | ) |
| | | } |
| | | </div> |
| | | { |
| | | data.type !== BlockEnum.Iteration && data.type !== BlockEnum.Loop && ( |
| | | data.type !== BlockEnum.Iteration && ( |
| | | cloneElement(children, { id, data }) |
| | | ) |
| | | } |
| | | { |
| | | (data.type === BlockEnum.Iteration || data.type === BlockEnum.Loop) && ( |
| | | <div className='grow pb-1 pl-1 pr-1'> |
| | | data.type === BlockEnum.Iteration && ( |
| | | <div className='grow pl-1 pr-1 pb-1'> |
| | | {cloneElement(children, { id, data })} |
| | | </div> |
| | | ) |
| | |
| | | ) |
| | | } |
| | | { |
| | | data.desc && data.type !== BlockEnum.Iteration && data.type !== BlockEnum.Loop && ( |
| | | <div className='system-xs-regular whitespace-pre-line break-words px-3 pb-2 pt-1 text-text-tertiary'> |
| | | data.desc && data.type !== BlockEnum.Iteration && ( |
| | | <div className='px-3 pt-1 pb-2 system-xs-regular text-text-tertiary whitespace-pre-line break-words'> |
| | | {data.desc} |
| | | </div> |
| | | ) |