| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 | 
							- 'use client'
 
- import type { FC } from 'react'
 
- import React, { useState, useEffect } from 'react'
 
- import { useTranslation } from 'react-i18next'
 
- import { useContext } from 'use-context-selector'
 
- import s from './style.module.css'
 
- import type { SiteInfo } from '@/models/share'
 
- import type { PromptConfig } from '@/models/debug'
 
- import { ToastContext } from '@/app/components/base/toast'
 
- import Select from '@/app/components/base/select'
 
- import { DEFAULT_VALUE_MAX_LEN } from '@/config'
 
- import TemplateVarPanel, { PanelTitle, VarOpBtnGroup } from '../value-panel'
 
- import { AppInfo, PromptTemplate, ChatBtn, EditBtn, FootLogo } from './massive-component'
 
- // regex to match the {{}} and replace it with a span
 
- const regex = /\{\{([^}]+)\}\}/g
 
- export type IWelcomeProps = {
 
-   conversationName: string
 
-   hasSetInputs: boolean
 
-   isPublicVersion: boolean
 
-   siteInfo: SiteInfo
 
-   promptConfig: PromptConfig
 
-   onStartChat: (inputs: Record<string, any>) => void
 
-   canEidtInpus: boolean
 
-   savedInputs: Record<string, any>
 
-   onInputsChange: (inputs: Record<string, any>) => void
 
-   plan: string
 
- }
 
- const Welcome: FC<IWelcomeProps> = ({
 
-   conversationName,
 
-   hasSetInputs,
 
-   isPublicVersion,
 
-   siteInfo,
 
-   plan,
 
-   promptConfig,
 
-   onStartChat,
 
-   canEidtInpus,
 
-   savedInputs,
 
-   onInputsChange
 
- }) => {
 
-   const { t } = useTranslation()
 
-   const hasVar = promptConfig.prompt_variables.length > 0
 
-   const [isFold, setIsFold] = useState<boolean>(true)
 
-   const [inputs, setInputs] = useState<Record<string, any>>((() => {
 
-     if (hasSetInputs) {
 
-       return savedInputs
 
-     }
 
-     const res: Record<string, any> = {}
 
-     if (promptConfig) {
 
-       promptConfig.prompt_variables.forEach((item) => {
 
-         res[item.key] = ''
 
-       })
 
-     }
 
-     // debugger
 
-     return res
 
-   })())
 
-   useEffect(() => {
 
-     if (!savedInputs) {
 
-       const res: Record<string, any> = {}
 
-       if (promptConfig) {
 
-         promptConfig.prompt_variables.forEach((item) => {
 
-           res[item.key] = ''
 
-         })
 
-       }
 
-       setInputs(res)
 
-     } else {
 
-       setInputs(savedInputs)
 
-     }
 
-   }, [savedInputs])
 
-   const highLightPromoptTemplate = (() => {
 
-     if (!promptConfig)
 
-       return ''
 
-     const res = promptConfig.prompt_template.replace(regex, (match, p1) => {
 
-       return `<span class='text-gray-800 font-bold'>${inputs?.[p1] ? inputs?.[p1] : match}</span>`
 
-     })
 
-     return res
 
-   })()
 
-   const { notify } = useContext(ToastContext)
 
-   const logError = (message: string) => {
 
-     notify({ type: 'error', message, duration: 3000 })
 
-   }
 
-   const renderHeader = () => {
 
-     return (
 
-       <div className='absolute top-0 left-0 right-0 flex items-center justify-between border-b border-gray-100 mobile:h-12 tablet:h-16 px-8 bg-white'>
 
-         <div className='text-gray-900'>{conversationName}</div>
 
-       </div>
 
-     )
 
-   }
 
-   const renderInputs = () => {
 
-     return (
 
-       <div className='space-y-3'>
 
-         {promptConfig.prompt_variables.map(item => (
 
-           <div className='tablet:flex tablet:!h-9 mobile:space-y-2 tablet:space-y-0 mobile:text-xs tablet:text-sm' key={item.key}>
 
-             <label className={`flex-shrink-0 flex items-center mobile:text-gray-700 tablet:text-gray-900 mobile:font-medium pc:font-normal ${s.formLabel}`}>{item.name}</label>
 
-             {item.type === 'select' ? (
 
-               <Select
 
-                 className='w-full'
 
-                 defaultValue={inputs?.[item.key]}
 
-                 onSelect={(i) => { setInputs({ ...inputs, [item.key]: i.value }) }}
 
-                 items={(item.options || []).map(i => ({ name: i, value: i }))}
 
-                 allowSearch={false}
 
-                 bgClassName='bg-gray-50'
 
-               />
 
-             ) : (
 
-               <input
 
-                 placeholder={`${item.name}${!item.required ? `(${t('appDebug.variableTable.optional')})` : ''}`}
 
-                 value={inputs?.[item.key] || ''}
 
-                 onChange={(e) => { setInputs({ ...inputs, [item.key]: e.target.value }) }}
 
-                 className={`w-full flex-grow py-2 pl-3 pr-3 box-border rounded-lg bg-gray-50`}
 
-                 maxLength={item.max_length || DEFAULT_VALUE_MAX_LEN}
 
-               />
 
-             )}
 
-           </div>
 
-         ))}
 
-       </div>
 
-     )
 
-   }
 
-   const canChat = () => {
 
-     const prompt_variables = promptConfig?.prompt_variables
 
-     if (!inputs || !prompt_variables || prompt_variables?.length === 0) {
 
-       return true
 
-     }
 
-     let hasEmptyInput = false
 
-     const requiredVars = prompt_variables?.filter(({ key, name, required }) => {
 
-       const res = (!key || !key.trim()) || (!name || !name.trim()) || (required || required === undefined || required === null)
 
-       return res
 
-     }) || [] // compatible with old version
 
-     requiredVars.forEach(({ key }) => {
 
-       if (hasEmptyInput) {
 
-         return
 
-       }
 
-       if (!inputs?.[key]) {
 
-         hasEmptyInput = true
 
-       }
 
-     })
 
-     if (hasEmptyInput) {
 
-       logError(t('appDebug.errorMessage.valueOfVarRequired'))
 
-       return false
 
-     }
 
-     return !hasEmptyInput
 
-   }
 
-   const handleChat = () => {
 
-     if (!canChat()) {
 
-       return
 
-     }
 
-     onStartChat(inputs)
 
-   }
 
-   const renderNoVarPanel = () => {
 
-     if (isPublicVersion) {
 
-       return (
 
-         <div>
 
-           <AppInfo siteInfo={siteInfo} />
 
-           <TemplateVarPanel
 
-             isFold={false}
 
-             header={
 
-               <>
 
-                 <PanelTitle
 
-                   title={t('share.chat.publicPromptConfigTitle')}
 
-                   className='mb-1'
 
-                 />
 
-                 <PromptTemplate html={highLightPromoptTemplate} />
 
-               </>
 
-             }
 
-           >
 
-             <ChatBtn onClick={handleChat} />
 
-           </TemplateVarPanel>
 
-         </div>
 
-       )
 
-     }
 
-     // private version
 
-     return (
 
-       <TemplateVarPanel
 
-         isFold={false}
 
-         header={
 
-           <AppInfo siteInfo={siteInfo} />
 
-         }
 
-       >
 
-         <ChatBtn onClick={handleChat} />
 
-       </TemplateVarPanel>
 
-     )
 
-   }
 
-   const renderVarPanel = () => {
 
-     return (
 
-       <TemplateVarPanel
 
-         isFold={false}
 
-         header={
 
-           <AppInfo siteInfo={siteInfo} />
 
-         }
 
-       >
 
-         {renderInputs()}
 
-         <ChatBtn
 
-           className='mt-3 mobile:ml-0 tablet:ml-[128px]'
 
-           onClick={handleChat}
 
-         />
 
-       </TemplateVarPanel>
 
-     )
 
-   }
 
-   const renderVarOpBtnGroup = () => {
 
-     return (
 
-       <VarOpBtnGroup
 
-         onConfirm={() => {
 
-           if (!canChat()) {
 
-             return
 
-           }
 
-           onInputsChange(inputs)
 
-           setIsFold(true)
 
-         }}
 
-         onCancel={() => {
 
-           setInputs(savedInputs)
 
-           setIsFold(true)
 
-         }}
 
-       />
 
-     )
 
-   }
 
-   const renderHasSetInputsPublic = () => {
 
-     if (!canEidtInpus) {
 
-       return (
 
-         <TemplateVarPanel
 
-           isFold={false}
 
-           header={
 
-             <>
 
-               <PanelTitle
 
-                 title={t('share.chat.publicPromptConfigTitle')}
 
-                 className='mb-1'
 
-               />
 
-               <PromptTemplate html={highLightPromoptTemplate} />
 
-             </>
 
-           }
 
-         />
 
-       )
 
-     }
 
-     return (
 
-       <TemplateVarPanel
 
-         isFold={isFold}
 
-         header={
 
-           <>
 
-             <PanelTitle
 
-               title={t('share.chat.publicPromptConfigTitle')}
 
-               className='mb-1'
 
-             />
 
-             <PromptTemplate html={highLightPromoptTemplate} />
 
-             {isFold && (
 
-               <div className='flex items-center justify-between mt-3 border-t border-indigo-100 pt-4 text-xs text-indigo-600'>
 
-                 <span className='text-gray-700'>{t('share.chat.configStatusDes')}</span>
 
-                 <EditBtn onClick={() => setIsFold(false)} />
 
-               </div>
 
-             )}
 
-           </>
 
-         }
 
-       >
 
-         {renderInputs()}
 
-         {renderVarOpBtnGroup()}
 
-       </TemplateVarPanel>
 
-     )
 
-   }
 
-   const renderHasSetInputsPrivate = () => {
 
-     if (!canEidtInpus || !hasVar) {
 
-       return null
 
-     }
 
-     return (
 
-       <TemplateVarPanel
 
-         isFold={isFold}
 
-         header={
 
-           <div className='flex items-center justify-between text-indigo-600'>
 
-             <PanelTitle
 
-               title={!isFold ? t('share.chat.privatePromptConfigTitle') : t('share.chat.configStatusDes')}
 
-             />
 
-             {isFold && (
 
-               <EditBtn onClick={() => setIsFold(false)} />
 
-             )}
 
-           </div>
 
-         }
 
-       >
 
-         {renderInputs()}
 
-         {renderVarOpBtnGroup()}
 
-       </TemplateVarPanel>
 
-     )
 
-   }
 
-   const renderHasSetInputs = () => {
 
-     if (!isPublicVersion && !canEidtInpus || !hasVar) {
 
-       return null
 
-     }
 
-     return (
 
-       <div
 
-         className='pt-[88px] mb-5'
 
-       >
 
-         {isPublicVersion ? renderHasSetInputsPublic() : renderHasSetInputsPrivate()}
 
-       </div>)
 
-   }
 
-   return (
 
-     <div className='relative mobile:min-h-[48px] tablet:min-h-[64px]'>
 
-       {hasSetInputs && renderHeader()}
 
-       <div className='mx-auto pc:w-[794px] max-w-full mobile:w-full px-3.5'>
 
-         {/*  Has't set inputs  */}
 
-         {
 
-           !hasSetInputs && (
 
-             <div className='mobile:pt-[72px] tablet:pt-[128px] pc:pt-[200px]'>
 
-               {hasVar ? (
 
-                 renderVarPanel()
 
-               ) : (
 
-                 renderNoVarPanel()
 
-               )}
 
-             </div>
 
-           )
 
-         }
 
-         {/* Has set inputs */}
 
-         {hasSetInputs && renderHasSetInputs()}
 
-         {/* foot */}
 
-         {!hasSetInputs && (
 
-           <div className='mt-4 flex justify-between items-center h-8 text-xs text-gray-400'>
 
-             {siteInfo.privacy_policy
 
-               ? <div>{t('share.chat.privacyPolicyLeft')}
 
-                 <a
 
-                   className='text-gray-500'
 
-                   href={siteInfo.privacy_policy}
 
-                   target='_blank'>{t('share.chat.privacyPolicyMiddle')}</a>
 
-                 {t('share.chat.privacyPolicyRight')}
 
-               </div>
 
-               : <div>
 
-               </div>}
 
-             {plan === 'basic' && <a className='flex items-center pr-3 space-x-3' href="https://dify.ai/" target="_blank">
 
-               <span className='uppercase'>{t('share.chat.powerBy')}</span>
 
-               <FootLogo />
 
-             </a>}
 
-           </div>
 
-         )}
 
-       </div>
 
-     </div >
 
-   )
 
- }
 
- export default React.memo(Welcome)
 
 
  |