| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  | 'use client' | 
					
						
							|  |  |  | import React, { useCallback, useEffect, useMemo, useState } from 'react' | 
					
						
							|  |  |  | import { useTranslation } from 'react-i18next' | 
					
						
							|  |  |  | import { useRouter } from 'next/navigation' | 
					
						
							| 
									
										
										
										
											2025-03-07 18:10:40 +08:00
										 |  |  | import { RiArrowRightUpLine, RiHammerLine } from '@remixicon/react' | 
					
						
							|  |  |  | import Divider from '../../base/divider' | 
					
						
							| 
									
										
										
										
											2024-07-09 15:05:40 +08:00
										 |  |  | import cn from '@/utils/classnames' | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  | import Button from '@/app/components/base/button' | 
					
						
							|  |  |  | import Indicator from '@/app/components/header/indicator' | 
					
						
							|  |  |  | import WorkflowToolModal from '@/app/components/tools/workflow-tool' | 
					
						
							|  |  |  | import Loading from '@/app/components/base/loading' | 
					
						
							|  |  |  | import Toast from '@/app/components/base/toast' | 
					
						
							|  |  |  | import { createWorkflowToolProvider, fetchWorkflowToolDetailByAppID, saveWorkflowToolProvider } from '@/service/tools' | 
					
						
							|  |  |  | import type { Emoji, WorkflowToolProviderParameter, WorkflowToolProviderRequest, WorkflowToolProviderResponse } from '@/app/components/tools/types' | 
					
						
							|  |  |  | import type { InputVar } from '@/app/components/workflow/types' | 
					
						
							| 
									
										
										
										
											2025-03-07 18:10:40 +08:00
										 |  |  | import type { PublishWorkflowParams } from '@/types/workflow' | 
					
						
							| 
									
										
										
										
											2024-06-14 07:34:25 -05:00
										 |  |  | import { useAppContext } from '@/context/app-context' | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | import { useInvalidateAllWorkflowTools } from '@/service/use-tools' | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | type Props = { | 
					
						
							|  |  |  |   disabled: boolean | 
					
						
							|  |  |  |   published: boolean | 
					
						
							|  |  |  |   detailNeedUpdate: boolean | 
					
						
							|  |  |  |   workflowAppId: string | 
					
						
							|  |  |  |   icon: Emoji | 
					
						
							|  |  |  |   name: string | 
					
						
							|  |  |  |   description: string | 
					
						
							|  |  |  |   inputs?: InputVar[] | 
					
						
							| 
									
										
										
										
											2025-03-07 18:10:40 +08:00
										 |  |  |   handlePublish: (params?: PublishWorkflowParams) => Promise<void> | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |   onRefreshData?: () => void | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const WorkflowToolConfigureButton = ({ | 
					
						
							|  |  |  |   disabled, | 
					
						
							|  |  |  |   published, | 
					
						
							|  |  |  |   detailNeedUpdate, | 
					
						
							|  |  |  |   workflowAppId, | 
					
						
							|  |  |  |   icon, | 
					
						
							|  |  |  |   name, | 
					
						
							|  |  |  |   description, | 
					
						
							|  |  |  |   inputs, | 
					
						
							|  |  |  |   handlePublish, | 
					
						
							|  |  |  |   onRefreshData, | 
					
						
							|  |  |  | }: Props) => { | 
					
						
							|  |  |  |   const { t } = useTranslation() | 
					
						
							|  |  |  |   const router = useRouter() | 
					
						
							|  |  |  |   const [showModal, setShowModal] = useState(false) | 
					
						
							|  |  |  |   const [isLoading, setIsLoading] = useState(false) | 
					
						
							|  |  |  |   const [detail, setDetail] = useState<WorkflowToolProviderResponse>() | 
					
						
							| 
									
										
										
										
											2024-06-14 07:34:25 -05:00
										 |  |  |   const { isCurrentWorkspaceManager } = useAppContext() | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |   const invalidateAllWorkflowTools = useInvalidateAllWorkflowTools() | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const outdated = useMemo(() => { | 
					
						
							|  |  |  |     if (!detail) | 
					
						
							|  |  |  |       return false | 
					
						
							|  |  |  |     if (detail.tool.parameters.length !== inputs?.length) { | 
					
						
							|  |  |  |       return true | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       for (const item of inputs || []) { | 
					
						
							|  |  |  |         const param = detail.tool.parameters.find(toolParam => toolParam.name === item.variable) | 
					
						
							|  |  |  |         if (!param) { | 
					
						
							|  |  |  |           return true | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (param.required !== item.required) { | 
					
						
							|  |  |  |           return true | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           if (item.type === 'paragraph' && param.type !== 'string') | 
					
						
							|  |  |  |             return true | 
					
						
							| 
									
										
										
										
											2024-09-26 17:50:36 +08:00
										 |  |  |           if (item.type === 'text-input' && param.type !== 'string') | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |             return true | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false | 
					
						
							|  |  |  |   }, [detail, inputs]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const payload = useMemo(() => { | 
					
						
							|  |  |  |     let parameters: WorkflowToolProviderParameter[] = [] | 
					
						
							|  |  |  |     if (!published) { | 
					
						
							|  |  |  |       parameters = (inputs || []).map((item) => { | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |           name: item.variable, | 
					
						
							|  |  |  |           description: '', | 
					
						
							|  |  |  |           form: 'llm', | 
					
						
							|  |  |  |           required: item.required, | 
					
						
							|  |  |  |           type: item.type, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (detail && detail.tool) { | 
					
						
							|  |  |  |       parameters = (inputs || []).map((item) => { | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |           name: item.variable, | 
					
						
							|  |  |  |           required: item.required, | 
					
						
							|  |  |  |           type: item.type === 'paragraph' ? 'string' : item.type, | 
					
						
							|  |  |  |           description: detail.tool.parameters.find(param => param.name === item.variable)?.llm_description || '', | 
					
						
							|  |  |  |           form: detail.tool.parameters.find(param => param.name === item.variable)?.form || 'llm', | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       icon: detail?.icon || icon, | 
					
						
							|  |  |  |       label: detail?.label || name, | 
					
						
							|  |  |  |       name: detail?.name || '', | 
					
						
							|  |  |  |       description: detail?.description || description, | 
					
						
							|  |  |  |       parameters, | 
					
						
							|  |  |  |       labels: detail?.tool?.labels || [], | 
					
						
							|  |  |  |       privacy_policy: detail?.privacy_policy || '', | 
					
						
							|  |  |  |       ...(published | 
					
						
							|  |  |  |         ? { | 
					
						
							|  |  |  |           workflow_tool_id: detail?.workflow_tool_id, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         : { | 
					
						
							|  |  |  |           workflow_app_id: workflowAppId, | 
					
						
							|  |  |  |         }), | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }, [detail, published, workflowAppId, icon, name, description, inputs]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const getDetail = useCallback(async (workflowAppId: string) => { | 
					
						
							|  |  |  |     setIsLoading(true) | 
					
						
							|  |  |  |     const res = await fetchWorkflowToolDetailByAppID(workflowAppId) | 
					
						
							|  |  |  |     setDetail(res) | 
					
						
							|  |  |  |     setIsLoading(false) | 
					
						
							|  |  |  |   }, []) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   useEffect(() => { | 
					
						
							|  |  |  |     if (published) | 
					
						
							|  |  |  |       getDetail(workflowAppId) | 
					
						
							|  |  |  |   }, [getDetail, published, workflowAppId]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   useEffect(() => { | 
					
						
							|  |  |  |     if (detailNeedUpdate) | 
					
						
							|  |  |  |       getDetail(workflowAppId) | 
					
						
							|  |  |  |   }, [detailNeedUpdate, getDetail, workflowAppId]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const createHandle = async (data: WorkflowToolProviderRequest & { workflow_app_id: string }) => { | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       await createWorkflowToolProvider(data) | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |       invalidateAllWorkflowTools() | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |       onRefreshData?.() | 
					
						
							|  |  |  |       getDetail(workflowAppId) | 
					
						
							|  |  |  |       Toast.notify({ | 
					
						
							|  |  |  |         type: 'success', | 
					
						
							|  |  |  |         message: t('common.api.actionSuccess'), | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |       setShowModal(false) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     catch (e) { | 
					
						
							|  |  |  |       Toast.notify({ type: 'error', message: (e as Error).message }) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const updateWorkflowToolProvider = async (data: WorkflowToolProviderRequest & Partial<{ | 
					
						
							|  |  |  |     workflow_app_id: string | 
					
						
							|  |  |  |     workflow_tool_id: string | 
					
						
							|  |  |  |   }>) => { | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       await handlePublish() | 
					
						
							|  |  |  |       await saveWorkflowToolProvider(data) | 
					
						
							|  |  |  |       onRefreshData?.() | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |       invalidateAllWorkflowTools() | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |       getDetail(workflowAppId) | 
					
						
							|  |  |  |       Toast.notify({ | 
					
						
							|  |  |  |         type: 'success', | 
					
						
							|  |  |  |         message: t('common.api.actionSuccess'), | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |       setShowModal(false) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     catch (e) { | 
					
						
							|  |  |  |       Toast.notify({ type: 'error', message: (e as Error).message }) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( | 
					
						
							|  |  |  |     <> | 
					
						
							| 
									
										
										
										
											2025-03-07 18:10:40 +08:00
										 |  |  |       <Divider type='horizontal' className='h-[1px] bg-divider-subtle' /> | 
					
						
							|  |  |  |       {(!published || !isLoading) && ( | 
					
						
							|  |  |  |         <div className={cn( | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |           'group rounded-lg bg-background-section-burn transition-colors', | 
					
						
							|  |  |  |           disabled ? 'cursor-not-allowed opacity-30 shadow-xs' : 'cursor-pointer', | 
					
						
							| 
									
										
										
										
											2025-03-07 18:10:40 +08:00
										 |  |  |           !disabled && !published && 'hover:bg-state-accent-hover', | 
					
						
							|  |  |  |         )}> | 
					
						
							|  |  |  |           {isCurrentWorkspaceManager | 
					
						
							|  |  |  |             ? ( | 
					
						
							|  |  |  |               <div | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                 className='flex items-center justify-start gap-2 p-2 pl-2.5' | 
					
						
							| 
									
										
										
										
											2025-03-07 18:10:40 +08:00
										 |  |  |                 onClick={() => !disabled && !published && setShowModal(true)} | 
					
						
							|  |  |  |               > | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                 <RiHammerLine className={cn('relative h-4 w-4 text-text-secondary', !disabled && !published && 'group-hover:text-text-accent')} /> | 
					
						
							| 
									
										
										
										
											2024-06-14 07:34:25 -05:00
										 |  |  |                 <div | 
					
						
							| 
									
										
										
										
											2025-03-07 18:10:40 +08:00
										 |  |  |                   title={t('workflow.common.workflowAsTool') || ''} | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                   className={cn('system-sm-medium shrink grow basis-0 truncate text-text-secondary', !disabled && !published && 'group-hover:text-text-accent')} | 
					
						
							| 
									
										
										
										
											2024-06-14 07:34:25 -05:00
										 |  |  |                 > | 
					
						
							| 
									
										
										
										
											2025-03-07 18:10:40 +08:00
										 |  |  |                   {t('workflow.common.workflowAsTool')} | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  |                 {!published && ( | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                   <span className='system-2xs-medium-uppercase shrink-0 rounded-[5px] border border-divider-deep bg-components-badge-bg-dimm px-1 py-0.5 text-text-tertiary'> | 
					
						
							| 
									
										
										
										
											2025-03-07 18:10:40 +08:00
										 |  |  |                     {t('workflow.common.configureRequired')} | 
					
						
							|  |  |  |                   </span> | 
					
						
							|  |  |  |                 )} | 
					
						
							|  |  |  |               </div>) | 
					
						
							|  |  |  |             : ( | 
					
						
							|  |  |  |               <div | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                 className='flex items-center justify-start gap-2 p-2 pl-2.5' | 
					
						
							| 
									
										
										
										
											2025-03-07 18:10:40 +08:00
										 |  |  |               > | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                 <RiHammerLine className='h-4 w-4 text-text-tertiary' /> | 
					
						
							| 
									
										
										
										
											2024-06-14 07:34:25 -05:00
										 |  |  |                 <div | 
					
						
							| 
									
										
										
										
											2025-03-07 18:10:40 +08:00
										 |  |  |                   title={t('workflow.common.workflowAsTool') || ''} | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                   className='system-sm-medium shrink grow basis-0 truncate text-text-tertiary' | 
					
						
							| 
									
										
										
										
											2024-06-14 07:34:25 -05:00
										 |  |  |                 > | 
					
						
							| 
									
										
										
										
											2025-03-07 18:10:40 +08:00
										 |  |  |                   {t('workflow.common.workflowAsTool')} | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |                 </div> | 
					
						
							|  |  |  |               </div> | 
					
						
							|  |  |  |             )} | 
					
						
							| 
									
										
										
										
											2025-03-07 18:10:40 +08:00
										 |  |  |           {published && ( | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |             <div className='border-t-[0.5px] border-divider-regular px-2.5 py-2'> | 
					
						
							| 
									
										
										
										
											2025-03-07 18:10:40 +08:00
										 |  |  |               <div className='flex justify-between gap-x-2'> | 
					
						
							|  |  |  |                 <Button | 
					
						
							|  |  |  |                   size='small' | 
					
						
							|  |  |  |                   className='w-[140px]' | 
					
						
							|  |  |  |                   onClick={() => setShowModal(true)} | 
					
						
							|  |  |  |                   disabled={!isCurrentWorkspaceManager} | 
					
						
							|  |  |  |                 > | 
					
						
							|  |  |  |                   {t('workflow.common.configure')} | 
					
						
							|  |  |  |                   {outdated && <Indicator className='ml-1' color={'yellow'} />} | 
					
						
							|  |  |  |                 </Button> | 
					
						
							|  |  |  |                 <Button | 
					
						
							|  |  |  |                   size='small' | 
					
						
							|  |  |  |                   className='w-[140px]' | 
					
						
							|  |  |  |                   onClick={() => router.push('/tools?category=workflow')} | 
					
						
							|  |  |  |                 > | 
					
						
							|  |  |  |                   {t('workflow.common.manageInTools')} | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                   <RiArrowRightUpLine className='ml-1 h-4 w-4' /> | 
					
						
							| 
									
										
										
										
											2025-03-07 18:10:40 +08:00
										 |  |  |                 </Button> | 
					
						
							|  |  |  |               </div> | 
					
						
							|  |  |  |               {outdated && <div className='mt-1 text-xs leading-[18px] text-text-warning'> | 
					
						
							|  |  |  |                 {t('workflow.common.workflowAsToolTip')} | 
					
						
							|  |  |  |               </div>} | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |           )} | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |       )} | 
					
						
							|  |  |  |       {published && isLoading && <div className='pt-2'><Loading type='app' /></div>} | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |       {showModal && ( | 
					
						
							|  |  |  |         <WorkflowToolModal | 
					
						
							|  |  |  |           isAdd={!published} | 
					
						
							|  |  |  |           payload={payload} | 
					
						
							|  |  |  |           onHide={() => setShowModal(false)} | 
					
						
							|  |  |  |           onCreate={createHandle} | 
					
						
							|  |  |  |           onSave={updateWorkflowToolProvider} | 
					
						
							|  |  |  |         /> | 
					
						
							|  |  |  |       )} | 
					
						
							|  |  |  |     </> | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | export default WorkflowToolConfigureButton |