| 
									
										
										
										
											2025-03-05 17:41:15 +08:00
										 |  |  | import { | 
					
						
							|  |  |  |   memo, | 
					
						
							|  |  |  |   useCallback, | 
					
						
							|  |  |  | } from 'react' | 
					
						
							|  |  |  | import { | 
					
						
							|  |  |  |   RiAddLine, | 
					
						
							|  |  |  | } from '@remixicon/react' | 
					
						
							|  |  |  | import { useTranslation } from 'react-i18next' | 
					
						
							|  |  |  | import { | 
					
						
							|  |  |  |   useAvailableBlocks, | 
					
						
							|  |  |  |   useNodesInteractions, | 
					
						
							|  |  |  |   useNodesReadOnly, | 
					
						
							|  |  |  | } from '../../hooks' | 
					
						
							|  |  |  | import type { LoopNodeType } from './types' | 
					
						
							|  |  |  | import cn from '@/utils/classnames' | 
					
						
							|  |  |  | import BlockSelector from '@/app/components/workflow/block-selector' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import type { | 
					
						
							|  |  |  |   OnSelectBlock, | 
					
						
							|  |  |  | } from '@/app/components/workflow/types' | 
					
						
							|  |  |  | import { | 
					
						
							|  |  |  |   BlockEnum, | 
					
						
							|  |  |  | } from '@/app/components/workflow/types' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type AddBlockProps = { | 
					
						
							|  |  |  |   loopNodeId: string | 
					
						
							|  |  |  |   loopNodeData: LoopNodeType | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | const AddBlock = ({ | 
					
						
							|  |  |  |   loopNodeData, | 
					
						
							|  |  |  | }: AddBlockProps) => { | 
					
						
							|  |  |  |   const { t } = useTranslation() | 
					
						
							|  |  |  |   const { nodesReadOnly } = useNodesReadOnly() | 
					
						
							|  |  |  |   const { handleNodeAdd } = useNodesInteractions() | 
					
						
							| 
									
										
										
										
											2025-04-24 16:29:58 +08:00
										 |  |  |   const { availableNextBlocks } = useAvailableBlocks(BlockEnum.Start, true) | 
					
						
							| 
									
										
										
										
											2025-03-05 17:41:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const handleSelect = useCallback<OnSelectBlock>((type, toolDefaultValue) => { | 
					
						
							|  |  |  |     handleNodeAdd( | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         nodeType: type, | 
					
						
							|  |  |  |         toolDefaultValue, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         prevNodeId: loopNodeData.start_node_id, | 
					
						
							|  |  |  |         prevNodeSourceHandle: 'source', | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |   }, [handleNodeAdd, loopNodeData.start_node_id]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const renderTriggerElement = useCallback((open: boolean) => { | 
					
						
							|  |  |  |     return ( | 
					
						
							|  |  |  |       <div className={cn( | 
					
						
							| 
									
										
										
										
											2025-04-10 17:15:48 +08:00
										 |  |  |         'system-sm-medium relative inline-flex h-8 cursor-pointer items-center rounded-lg border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg px-3 text-components-button-secondary-text shadow-xs backdrop-blur-[5px] hover:bg-components-button-secondary-bg-hover', | 
					
						
							|  |  |  |         `${nodesReadOnly && '!cursor-not-allowed bg-components-button-secondary-bg-disabled'}`, | 
					
						
							|  |  |  |         open && 'bg-components-button-secondary-bg-hover', | 
					
						
							| 
									
										
										
										
											2025-03-05 17:41:15 +08:00
										 |  |  |       )}> | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |         <RiAddLine className='mr-1 h-4 w-4' /> | 
					
						
							| 
									
										
										
										
											2025-03-05 17:41:15 +08:00
										 |  |  |         {t('workflow.common.addBlock')} | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |   }, [nodesReadOnly, t]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |     <div className='absolute left-14 top-7 z-10 flex h-8 items-center'> | 
					
						
							|  |  |  |       <div className='group/insert relative h-0.5 w-16 bg-gray-300'> | 
					
						
							|  |  |  |         <div className='absolute right-0 top-1/2 h-2 w-0.5 -translate-y-1/2 bg-primary-500'></div> | 
					
						
							| 
									
										
										
										
											2025-03-05 17:41:15 +08:00
										 |  |  |       </div> | 
					
						
							|  |  |  |       <BlockSelector | 
					
						
							|  |  |  |         disabled={nodesReadOnly} | 
					
						
							|  |  |  |         onSelect={handleSelect} | 
					
						
							|  |  |  |         trigger={renderTriggerElement} | 
					
						
							|  |  |  |         triggerInnerClassName='inline-flex' | 
					
						
							|  |  |  |         popupClassName='!min-w-[256px]' | 
					
						
							|  |  |  |         availableBlocksTypes={availableNextBlocks} | 
					
						
							|  |  |  |       /> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default memo(AddBlock) |