'use client' import type { FC } from 'react' import React, { useState } from 'react' import { useTranslation } from 'react-i18next' import cn from 'classnames' import { RiQuestionLine, } from '@remixicon/react' import produce from 'immer' import type { Emoji, WorkflowToolProviderParameter, WorkflowToolProviderRequest } from '../types' import Drawer from '@/app/components/base/drawer-plus' 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) => { return /^[a-zA-Z0-9_]+$/.test(name) } const onConfirm = () => { if (!label) { return Toast.notify({ type: 'error', message: 'Please enter the tool name', }) } if (!name) { return Toast.notify({ type: 'error', message: 'Please enter the name for tool call', }) } else if (!isNameValid(name)) { return Toast.notify({ type: 'error', message: 'Name for tool call can only contain numbers, letters, and underscores', }) } 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' icon={emoji.content} background={emoji.background} /> setLabel(e.target.value)} />
{/* name for tool call */}
{t('tools.createTool.nameForToolCall')} {t('tools.createTool.nameForToolCallPlaceHolder')}
} selector='workflow-tool-modal-tooltip' >
setName(e.target.value)} /> {!isNameValid(name) && (
{t('tools.createTool.nameForToolCallTip')}
)}
{/* description */}
{t('tools.createTool.description')}