import React, { useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { useBoolean } from 'ahooks' import produce from 'immer' import { ReactSortable } from 'react-sortablejs' import { RiAddLine, RiAsterisk, RiCloseLine, RiDeleteBinLine, RiDraggable } from '@remixicon/react' import Modal from '@/app/components/base/modal' import Button from '@/app/components/base/button' import ConfirmAddVar from '@/app/components/app/configuration/config-prompt/confirm-add-var' import type { OpeningStatement } from '@/app/components/base/features/types' import { getInputKeys } from '@/app/components/base/block-input' import type { PromptVariable } from '@/models/debug' import type { InputVar } from '@/app/components/workflow/types' import { getNewVar } from '@/utils/var' type OpeningSettingModalProps = { data: OpeningStatement onSave: (newState: OpeningStatement) => void onCancel: () => void promptVariables?: PromptVariable[] workflowVariables?: InputVar[] onAutoAddPromptVariable?: (variable: PromptVariable[]) => void } const MAX_QUESTION_NUM = 5 const OpeningSettingModal = ({ data, onSave, onCancel, promptVariables = [], workflowVariables = [], onAutoAddPromptVariable, }: OpeningSettingModalProps) => { const { t } = useTranslation() const [tempValue, setTempValue] = useState(data?.opening_statement || '') useEffect(() => { setTempValue(data.opening_statement || '') }, [data.opening_statement]) const [tempSuggestedQuestions, setTempSuggestedQuestions] = useState(data.suggested_questions || []) const [isShowConfirmAddVar, { setTrue: showConfirmAddVar, setFalse: hideConfirmAddVar }] = useBoolean(false) const [notIncludeKeys, setNotIncludeKeys] = useState([]) const handleSave = useCallback((ignoreVariablesCheck?: boolean) => { if (!ignoreVariablesCheck) { const keys = getInputKeys(tempValue) const promptKeys = promptVariables.map(item => item.key) const workflowVariableKeys = workflowVariables.map(item => item.variable) let notIncludeKeys: string[] = [] if (promptKeys.length === 0 && workflowVariables.length === 0) { if (keys.length > 0) notIncludeKeys = keys } else { if (workflowVariables.length > 0) notIncludeKeys = keys.filter(key => !workflowVariableKeys.includes(key)) else notIncludeKeys = keys.filter(key => !promptKeys.includes(key)) } if (notIncludeKeys.length > 0) { setNotIncludeKeys(notIncludeKeys) showConfirmAddVar() return } } const newOpening = produce(data, (draft) => { if (draft) { draft.opening_statement = tempValue draft.suggested_questions = tempSuggestedQuestions } }) onSave(newOpening) }, [data, onSave, promptVariables, workflowVariables, showConfirmAddVar, tempSuggestedQuestions, tempValue]) const cancelAutoAddVar = useCallback(() => { hideConfirmAddVar() handleSave(true) }, [handleSave, hideConfirmAddVar]) const autoAddVar = useCallback(() => { onAutoAddPromptVariable?.([ ...notIncludeKeys.map(key => getNewVar(key, 'string')), ]) hideConfirmAddVar() handleSave(true) }, [handleSave, hideConfirmAddVar, notIncludeKeys, onAutoAddPromptVariable]) const renderQuestions = () => { return (
{t('appDebug.openingStatement.openingQuestion')}
ยท
{tempSuggestedQuestions.length}/{MAX_QUESTION_NUM}
{ return { id: index, name, } })} setList={list => setTempSuggestedQuestions(list.map(item => item.name))} handle='.handle' ghostClass="opacity-50" animation={150} > {tempSuggestedQuestions.map((question, index) => { return (
{ const value = e.target.value setTempSuggestedQuestions(tempSuggestedQuestions.map((item, i) => { if (index === i) return value return item })) }} className={'w-full overflow-x-auto pl-1.5 pr-8 text-sm leading-9 text-gray-900 border-0 grow h-9 bg-transparent focus:outline-none cursor-pointer rounded-lg'} />
{ setTempSuggestedQuestions(tempSuggestedQuestions.filter((_, i) => index !== i)) }} >
) })}
{tempSuggestedQuestions.length < MAX_QUESTION_NUM && (
{ setTempSuggestedQuestions([...tempSuggestedQuestions, '']) }} className='mt-1 flex items-center h-9 px-3 gap-2 rounded-lg cursor-pointer text-gray-400 bg-gray-100 hover:bg-gray-200'>
{t('appDebug.variableConfig.addOption')}
)}
) } return ( { }} className='!p-6 !mt-14 !max-w-none !w-[640px] !bg-components-panel-bg-blur' >
{t('appDebug.feature.conversationOpener.title')}