| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 | 
							- 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<string[]>([])
 
-   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 (
 
-       <div>
 
-         <div className='flex items-center py-2'>
 
-           <div className='shrink-0 flex space-x-0.5 leading-[18px] text-xs font-medium text-gray-500'>
 
-             <div className='uppercase'>{t('appDebug.openingStatement.openingQuestion')}</div>
 
-             <div>·</div>
 
-             <div>{tempSuggestedQuestions.length}/{MAX_QUESTION_NUM}</div>
 
-           </div>
 
-           <div className='ml-3 grow w-0 h-px bg-[#243, 244, 246]'></div>
 
-         </div>
 
-         <ReactSortable
 
-           className="space-y-1"
 
-           list={tempSuggestedQuestions.map((name, index) => {
 
-             return {
 
-               id: index,
 
-               name,
 
-             }
 
-           })}
 
-           setList={list => setTempSuggestedQuestions(list.map(item => item.name))}
 
-           handle='.handle'
 
-           ghostClass="opacity-50"
 
-           animation={150}
 
-         >
 
-           {tempSuggestedQuestions.map((question, index) => {
 
-             return (
 
-               <div className='group relative rounded-lg border border-gray-200 flex items-center pl-2.5 hover:border-gray-300 hover:bg-white' key={index}>
 
-                 <RiDraggable className='handle w-4 h-4 cursor-grab' />
 
-                 <input
 
-                   type="input"
 
-                   value={question || ''}
 
-                   onChange={(e) => {
 
-                     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'}
 
-                 />
 
-                 <div
 
-                   className='block absolute top-1/2 translate-y-[-50%] right-1.5 p-1 rounded-md cursor-pointer hover:bg-[#FEE4E2] hover:text-[#D92D20]'
 
-                   onClick={() => {
 
-                     setTempSuggestedQuestions(tempSuggestedQuestions.filter((_, i) => index !== i))
 
-                   }}
 
-                 >
 
-                   <RiDeleteBinLine className='w-3.5 h-3.5' />
 
-                 </div>
 
-               </div>
 
-             )
 
-           })}</ReactSortable>
 
-         {tempSuggestedQuestions.length < MAX_QUESTION_NUM && (
 
-           <div
 
-             onClick={() => { 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'>
 
-             <RiAddLine className='w-4 h-4' />
 
-             <div className='text-gray-500 text-[13px]'>{t('appDebug.variableConfig.addOption')}</div>
 
-           </div>
 
-         )}
 
-       </div>
 
-     )
 
-   }
 
-   return (
 
-     <Modal
 
-       isShow
 
-       onClose={() => { }}
 
-       className='!p-6 !mt-14 !max-w-none !w-[640px] !bg-components-panel-bg-blur'
 
-     >
 
-       <div className='flex items-center justify-between mb-6'>
 
-         <div className='text-text-primary title-2xl-semi-bold'>{t('appDebug.feature.conversationOpener.title')}</div>
 
-         <div className='p-1 cursor-pointer' onClick={onCancel}><RiCloseLine className='w-4 h-4 text-text-tertiary'/></div>
 
-       </div>
 
-       <div className='flex gap-2 mb-8'>
 
-         <div className='shrink-0 mt-1.5 w-8 h-8 p-1.5 rounded-lg border-components-panel-border bg-util-colors-orange-dark-orange-dark-500'>
 
-           <RiAsterisk className='w-5 h-5 text-text-primary-on-surface' />
 
-         </div>
 
-         <div className='grow p-3 bg-chat-bubble-bg rounded-2xl border-t border-divider-subtle shadow-xs'>
 
-           <textarea
 
-             value={tempValue}
 
-             rows={3}
 
-             onChange={e => setTempValue(e.target.value)}
 
-             className="w-full px-0 text-text-secondary system-md-regular  border-0 bg-transparent focus:outline-none"
 
-             placeholder={t('appDebug.openingStatement.placeholder') as string}
 
-           />
 
-           {renderQuestions()}
 
-         </div>
 
-       </div>
 
-       <div className='flex items-center justify-end'>
 
-         <Button
 
-           onClick={onCancel}
 
-           className='mr-2'
 
-         >
 
-           {t('common.operation.cancel')}
 
-         </Button>
 
-         <Button
 
-           variant='primary'
 
-           onClick={() => handleSave()}
 
-         >
 
-           {t('common.operation.save')}
 
-         </Button>
 
-       </div>
 
-       {isShowConfirmAddVar && (
 
-         <ConfirmAddVar
 
-           varNameArr={notIncludeKeys}
 
-           onConfirm={autoAddVar}
 
-           onCancel={cancelAutoAddVar}
 
-           onHide={hideConfirmAddVar}
 
-         />
 
-       )}
 
-     </Modal>
 
-   )
 
- }
 
- export default OpeningSettingModal
 
 
  |