'use client' import type { FC } from 'react' import React, { useState } from 'react' import { useTranslation } from 'react-i18next' import produce from 'immer' import type { Emoji, WorkflowToolProviderParameter, WorkflowToolProviderRequest } from '../types' import cn from '@/utils/classnames' import Drawer from '@/app/components/base/drawer-plus' import Input from '@/app/components/base/input' import Textarea from '@/app/components/base/textarea' import Button from '@/app/components/base/button' import Toast from '@/app/components/base/toast' import EmojiPicker from '@/app/components/base/emoji-picker' import AppIcon from '@/app/components/base/app-icon' import MethodSelector from '@/app/components/tools/workflow-tool/method-selector' import LabelSelector from '@/app/components/tools/labels/selector' import ConfirmModal from '@/app/components/tools/workflow-tool/confirm-modal' import Tooltip from '@/app/components/base/tooltip' type Props = { isAdd?: boolean payload: any onHide: () => void onRemove?: () => void onCreate?: (payload: WorkflowToolProviderRequest & { workflow_app_id: string }) => void onSave?: (payload: WorkflowToolProviderRequest & Partial<{ workflow_app_id: string workflow_tool_id: string }>) => void } // Add and Edit const WorkflowToolAsModal: FC = ({ isAdd, payload, onHide, onRemove, onSave, onCreate, }) => { const { t } = useTranslation() const [showEmojiPicker, setShowEmojiPicker] = useState(false) const [emoji, setEmoji] = useState(payload.icon) const [label, setLabel] = useState(payload.label) const [name, setName] = useState(payload.name) const [description, setDescription] = useState(payload.description) const [parameters, setParameters] = useState(payload.parameters) const handleParameterChange = (key: string, value: string, index: number) => { const newData = produce(parameters, (draft: WorkflowToolProviderParameter[]) => { if (key === 'description') draft[index].description = value else draft[index].form = value }) setParameters(newData) } const [labels, setLabels] = useState(payload.labels) const handleLabelSelect = (value: string[]) => { setLabels(value) } const [privacyPolicy, setPrivacyPolicy] = useState(payload.privacy_policy) const [showModal, setShowModal] = useState(false) const isNameValid = (name: string) => { // when the user has not input anything, no need for a warning if (name === '') return true return /^[a-zA-Z0-9_]+$/.test(name) } const onConfirm = () => { let errorMessage = '' if (!label) errorMessage = t('common.errorMsg.fieldRequired', { field: t('tools.createTool.name') }) if (!name) errorMessage = t('common.errorMsg.fieldRequired', { field: t('tools.createTool.nameForToolCall') }) if (!isNameValid(name)) errorMessage = t('tools.createTool.nameForToolCall') + t('tools.createTool.nameForToolCallTip') if (errorMessage) { Toast.notify({ type: 'error', message: errorMessage, }) return } const requestParams = { name, description, icon: emoji, label, parameters: parameters.map(item => ({ name: item.name, description: item.description, form: item.form, })), labels, privacy_policy: privacyPolicy, } if (!isAdd) { onSave?.({ ...requestParams, workflow_tool_id: payload.workflow_tool_id, }) } else { onCreate?.({ ...requestParams, workflow_app_id: payload.workflow_app_id, }) } } return ( <>
{/* name & icon */}
{t('tools.createTool.name')} *
{ setShowEmojiPicker(true) }} className='cursor-pointer' iconType='emoji' icon={emoji.content} background={emoji.background} /> setLabel(e.target.value)} />
{/* name for tool call */}
{t('tools.createTool.nameForToolCall')} * {t('tools.createTool.nameForToolCallPlaceHolder')}
} />
setName(e.target.value)} /> {!isNameValid(name) && (
{t('tools.createTool.nameForToolCallTip')}
)}
{/* description */}
{t('tools.createTool.description')}