| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | import { | 
					
						
							|  |  |  |   memo, | 
					
						
							|  |  |  |   useState, | 
					
						
							|  |  |  | } from 'react' | 
					
						
							|  |  |  | import { useTranslation } from 'react-i18next' | 
					
						
							|  |  |  | import { | 
					
						
							|  |  |  |   useEdges, | 
					
						
							|  |  |  |   useNodes, | 
					
						
							|  |  |  | } from 'reactflow' | 
					
						
							| 
									
										
										
										
											2024-06-20 11:05:08 +08:00
										 |  |  | import { | 
					
						
							|  |  |  |   RiCloseLine, | 
					
						
							|  |  |  |   RiListCheck3, | 
					
						
							|  |  |  | } from '@remixicon/react' | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | import BlockIcon from '../block-icon' | 
					
						
							|  |  |  | import { | 
					
						
							|  |  |  |   useChecklist, | 
					
						
							|  |  |  |   useNodesInteractions, | 
					
						
							|  |  |  | } from '../hooks' | 
					
						
							|  |  |  | import type { | 
					
						
							|  |  |  |   CommonEdgeType, | 
					
						
							|  |  |  |   CommonNodeType, | 
					
						
							|  |  |  | } from '../types' | 
					
						
							| 
									
										
										
										
											2024-07-09 15:05:40 +08:00
										 |  |  | import cn from '@/utils/classnames' | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | import { | 
					
						
							|  |  |  |   PortalToFollowElem, | 
					
						
							|  |  |  |   PortalToFollowElemContent, | 
					
						
							|  |  |  |   PortalToFollowElemTrigger, | 
					
						
							|  |  |  | } from '@/app/components/base/portal-to-follow-elem' | 
					
						
							|  |  |  | import { | 
					
						
							|  |  |  |   ChecklistSquare, | 
					
						
							|  |  |  | } from '@/app/components/base/icons/src/vender/line/general' | 
					
						
							|  |  |  | import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-28 17:09:56 +08:00
										 |  |  | type WorkflowChecklistProps = { | 
					
						
							|  |  |  |   disabled: boolean | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | const WorkflowChecklist = ({ | 
					
						
							|  |  |  |   disabled, | 
					
						
							|  |  |  | }: WorkflowChecklistProps) => { | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |   const { t } = useTranslation() | 
					
						
							|  |  |  |   const [open, setOpen] = useState(false) | 
					
						
							|  |  |  |   const nodes = useNodes<CommonNodeType>() | 
					
						
							|  |  |  |   const edges = useEdges<CommonEdgeType>() | 
					
						
							|  |  |  |   const needWarningNodes = useChecklist(nodes, edges) | 
					
						
							|  |  |  |   const { handleNodeSelect } = useNodesInteractions() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( | 
					
						
							|  |  |  |     <PortalToFollowElem | 
					
						
							|  |  |  |       placement='bottom-end' | 
					
						
							|  |  |  |       offset={{ | 
					
						
							|  |  |  |         mainAxis: 12, | 
					
						
							|  |  |  |         crossAxis: 4, | 
					
						
							|  |  |  |       }} | 
					
						
							|  |  |  |       open={open} | 
					
						
							|  |  |  |       onOpenChange={setOpen} | 
					
						
							|  |  |  |     > | 
					
						
							| 
									
										
										
										
											2024-04-28 17:09:56 +08:00
										 |  |  |       <PortalToFollowElemTrigger onClick={() => !disabled && setOpen(v => !v)}> | 
					
						
							|  |  |  |         <div | 
					
						
							|  |  |  |           className={cn( | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |             'relative ml-0.5 flex h-7 w-7 items-center justify-center rounded-md', | 
					
						
							|  |  |  |             disabled && 'cursor-not-allowed opacity-50', | 
					
						
							| 
									
										
										
										
											2024-04-28 17:09:56 +08:00
										 |  |  |           )} | 
					
						
							|  |  |  |         > | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |           <div | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |             className={cn('group flex h-full w-full cursor-pointer items-center justify-center rounded-md hover:bg-state-accent-hover', open && 'bg-state-accent-hover')} | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |           > | 
					
						
							| 
									
										
										
										
											2024-06-20 11:05:08 +08:00
										 |  |  |             <RiListCheck3 | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |               className={cn('h-4 w-4 group-hover:text-components-button-secondary-accent-text', open ? 'text-components-button-secondary-accent-text' : 'text-components-button-ghost-text')} | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |             /> | 
					
						
							|  |  |  |           </div> | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             !!needWarningNodes.length && ( | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |               <div className='absolute -right-1.5 -top-1.5 flex h-[18px] min-w-[18px] items-center justify-center rounded-full border border-gray-100 bg-[#F79009] text-[11px] font-semibold text-white'> | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |                 {needWarningNodes.length} | 
					
						
							|  |  |  |               </div> | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |       </PortalToFollowElemTrigger> | 
					
						
							|  |  |  |       <PortalToFollowElemContent className='z-[12]'> | 
					
						
							|  |  |  |         <div | 
					
						
							| 
									
										
										
										
											2025-04-10 17:15:48 +08:00
										 |  |  |           className='w-[420px] overflow-y-auto rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg' | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |           style={{ | 
					
						
							|  |  |  |             maxHeight: 'calc(2 / 3 * 100vh)', | 
					
						
							|  |  |  |           }} | 
					
						
							|  |  |  |         > | 
					
						
							| 
									
										
										
										
											2025-04-10 17:15:48 +08:00
										 |  |  |           <div className='text-md sticky top-0 z-[1] flex h-[44px] items-center bg-components-panel-bg pl-4 pr-3 pt-3 font-semibold text-text-primary'> | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |             <div className='grow'>{t('workflow.panel.checklist')}{needWarningNodes.length ? `(${needWarningNodes.length})` : ''}</div> | 
					
						
							|  |  |  |             <div | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |               className='flex h-6 w-6 shrink-0 cursor-pointer items-center justify-center' | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |               onClick={() => setOpen(false)} | 
					
						
							|  |  |  |             > | 
					
						
							| 
									
										
										
										
											2025-04-10 17:15:48 +08:00
										 |  |  |               <RiCloseLine className='h-4 w-4 text-text-tertiary' /> | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |             </div> | 
					
						
							|  |  |  |           </div> | 
					
						
							|  |  |  |           <div className='py-2'> | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               !!needWarningNodes.length && ( | 
					
						
							|  |  |  |                 <> | 
					
						
							| 
									
										
										
										
											2025-04-10 17:15:48 +08:00
										 |  |  |                   <div className='px-4 text-xs text-text-tertiary'>{t('workflow.panel.checklistTip')}</div> | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |                   <div className='px-4 py-2'> | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                       needWarningNodes.map(node => ( | 
					
						
							|  |  |  |                         <div | 
					
						
							|  |  |  |                           key={node.id} | 
					
						
							| 
									
										
										
										
											2025-04-10 17:15:48 +08:00
										 |  |  |                           className='mb-2 cursor-pointer rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xs last-of-type:mb-0' | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |                           onClick={() => { | 
					
						
							|  |  |  |                             handleNodeSelect(node.id) | 
					
						
							|  |  |  |                             setOpen(false) | 
					
						
							|  |  |  |                           }} | 
					
						
							|  |  |  |                         > | 
					
						
							| 
									
										
										
										
											2025-04-10 17:15:48 +08:00
										 |  |  |                           <div className='flex h-9 items-center p-2 text-xs font-medium text-text-secondary'> | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |                             <BlockIcon | 
					
						
							|  |  |  |                               type={node.type} | 
					
						
							|  |  |  |                               className='mr-1.5' | 
					
						
							|  |  |  |                               toolIcon={node.toolIcon} | 
					
						
							|  |  |  |                             /> | 
					
						
							| 
									
										
										
										
											2024-07-09 15:12:41 +08:00
										 |  |  |                             <span className='grow truncate'> | 
					
						
							|  |  |  |                               {node.title} | 
					
						
							|  |  |  |                             </span> | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |                           </div> | 
					
						
							| 
									
										
										
										
											2025-04-10 17:15:48 +08:00
										 |  |  |                           <div className='border-t-[0.5px] border-divider-regular'> | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |                             { | 
					
						
							|  |  |  |                               node.unConnected && ( | 
					
						
							| 
									
										
										
										
											2025-04-10 17:15:48 +08:00
										 |  |  |                                 <div className='px-3 py-2 last:rounded-b-lg'> | 
					
						
							|  |  |  |                                   <div className='flex text-xs leading-[18px] text-text-tertiary'> | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                                     <AlertTriangle className='mr-2 mt-[3px] h-3 w-3 text-[#F79009]' /> | 
					
						
							| 
									
										
										
										
											2024-09-07 15:59:38 +07:00
										 |  |  |                                     {t('workflow.common.needConnectTip')} | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |                                   </div> | 
					
						
							|  |  |  |                                 </div> | 
					
						
							|  |  |  |                               ) | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                             { | 
					
						
							|  |  |  |                               node.errorMessage && ( | 
					
						
							| 
									
										
										
										
											2025-04-10 17:15:48 +08:00
										 |  |  |                                 <div className='px-3 py-2 last:rounded-b-lg'> | 
					
						
							|  |  |  |                                   <div className='flex text-xs leading-[18px] text-text-tertiary'> | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                                     <AlertTriangle className='mr-2 mt-[3px] h-3 w-3 text-[#F79009]' /> | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |                                     {node.errorMessage} | 
					
						
							|  |  |  |                                   </div> | 
					
						
							|  |  |  |                                 </div> | 
					
						
							|  |  |  |                               ) | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                           </div> | 
					
						
							|  |  |  |                         </div> | 
					
						
							|  |  |  |                       )) | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                   </div> | 
					
						
							|  |  |  |                 </> | 
					
						
							|  |  |  |               ) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               !needWarningNodes.length && ( | 
					
						
							| 
									
										
										
										
											2025-04-10 17:15:48 +08:00
										 |  |  |                 <div className='mx-4 mb-3 rounded-lg bg-components-panel-bg py-4 text-center text-xs text-text-tertiary'> | 
					
						
							|  |  |  |                   <ChecklistSquare className='mx-auto mb-[5px] h-8 w-8 text-text-quaternary' /> | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |                   {t('workflow.panel.checklistResolved')} | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  |               ) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           </div> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |       </PortalToFollowElemContent> | 
					
						
							|  |  |  |     </PortalToFollowElem> | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default memo(WorkflowChecklist) |