Ver Fonte

fix: webapp variable input & app unavailable status (#2405)

zxhlyh há 1 ano atrás
pai
commit
d8de2017b5

+ 46 - 0
web/app/components/base/chat/chat-with-history/config-panel/form-input.tsx

@@ -0,0 +1,46 @@
+import type { FC } from 'react'
+import { useTranslation } from 'react-i18next'
+import { memo } from 'react'
+
+type InputProps = {
+  form: any
+  value: string
+  onChange: (variable: string, value: string) => void
+}
+const FormInput: FC<InputProps> = ({
+  form,
+  value,
+  onChange,
+}) => {
+  const { t } = useTranslation()
+  const {
+    type,
+    label,
+    required,
+    max_length,
+    variable,
+  } = form
+
+  if (type === 'paragraph') {
+    return (
+      <textarea
+        value={value}
+        className='grow h-[104px] rounded-lg bg-gray-100 px-2.5 py-2 outline-none appearance-none resize-none'
+        onChange={e => onChange(variable, e.target.value)}
+        placeholder={`${label}${!required ? `(${t('appDebug.variableTable.optional')})` : ''}`}
+      />
+    )
+  }
+
+  return (
+    <input
+      className='grow h-9 rounded-lg bg-gray-100 px-2.5 outline-none appearance-none'
+      value={value || ''}
+      maxLength={max_length}
+      onChange={e => onChange(variable, e.target.value)}
+      placeholder={`${label}${!required ? `(${t('appDebug.variableTable.optional')})` : ''}`}
+    />
+  )
+}
+
+export default memo(FormInput)

+ 9 - 19
web/app/components/base/chat/chat-with-history/config-panel/form.tsx

@@ -1,5 +1,7 @@
+import { useCallback } from 'react'
 import { useTranslation } from 'react-i18next'
 import { useChatWithHistoryContext } from '../context'
+import Input from './form-input'
 import { PortalSelect } from '@/app/components/base/select'
 
 const Form = () => {
@@ -11,43 +13,31 @@ const Form = () => {
     isMobile,
   } = useChatWithHistoryContext()
 
-  const handleFormChange = (variable: string, value: string) => {
+  const handleFormChange = useCallback((variable: string, value: string) => {
     handleNewConversationInputsChange({
       ...newConversationInputs,
       [variable]: value,
     })
-  }
+  }, [newConversationInputs, handleNewConversationInputsChange])
 
   const renderField = (form: any) => {
     const {
       label,
       required,
-      max_length,
       variable,
       options,
     } = form
 
-    if (form.type === 'text-input') {
-      return (
-        <input
-          className='grow h-9 rounded-lg bg-gray-100 px-2.5 outline-none appearance-none'
-          value={newConversationInputs[variable] || ''}
-          maxLength={max_length}
-          onChange={e => handleFormChange(variable, e.target.value)}
-          placeholder={`${label}${!required ? `(${t('appDebug.variableTable.optional')})` : ''}`}
-        />
-      )
-    }
-    if (form.type === 'paragraph') {
+    if (form.type === 'text-input' || form.type === 'paragraph') {
       return (
-        <textarea
+        <Input
+          form={form}
           value={newConversationInputs[variable]}
-          className='grow h-[104px] rounded-lg bg-gray-100 px-2.5 py-2 outline-none appearance-none resize-none'
-          onChange={e => handleFormChange(variable, e.target.value)}
-          placeholder={`${label}${!required ? `(${t('appDebug.variableTable.optional')})` : ''}`}
+          onChange={handleFormChange}
         />
       )
     }
+
     return (
       <PortalSelect
         popupClassName='w-[200px]'

+ 1 - 0
web/app/components/base/chat/chat-with-history/context.tsx

@@ -16,6 +16,7 @@ import type {
 } from '@/models/share'
 
 export type ChatWithHistoryContextValue = {
+  appInfoError?: any
   appInfoLoading?: boolean
   appMeta?: AppMeta
   appData?: AppData

+ 2 - 1
web/app/components/base/chat/chat-with-history/hooks.tsx

@@ -40,7 +40,7 @@ import { changeLanguage } from '@/i18n/i18next-config'
 
 export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
   const isInstalledApp = useMemo(() => !!installedAppInfo, [installedAppInfo])
-  const { data: appInfo, isLoading: appInfoLoading } = useSWR(installedAppInfo ? null : 'appInfo', fetchAppInfo)
+  const { data: appInfo, isLoading: appInfoLoading, error: appInfoError } = useSWR(installedAppInfo ? null : 'appInfo', fetchAppInfo)
 
   const appData = useMemo(() => {
     if (isInstalledApp) {
@@ -350,6 +350,7 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
   }, [isInstalledApp, appId, t, notify])
 
   return {
+    appInfoError,
     appInfoLoading,
     isInstalledApp,
     appId,

+ 29 - 2
web/app/components/base/chat/chat-with-history/index.tsx

@@ -17,6 +17,7 @@ import type { InstalledApp } from '@/models/explore'
 import Loading from '@/app/components/base/loading'
 import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
 import { checkOrSetAccessToken } from '@/app/components/share/utils'
+import AppUnavailable from '@/app/components/base/app-unavailable'
 
 type ChatWithHistoryProps = {
   className?: string
@@ -25,6 +26,7 @@ const ChatWithHistory: FC<ChatWithHistoryProps> = ({
   className,
 }) => {
   const {
+    appInfoError,
     appData,
     appInfoLoading,
     appPrevChatList,
@@ -53,6 +55,12 @@ const ChatWithHistory: FC<ChatWithHistoryProps> = ({
     )
   }
 
+  if (appInfoError) {
+    return (
+      <AppUnavailable />
+    )
+  }
+
   return (
     <div className={`h-full flex bg-white ${className} ${isMobile && 'flex-col'}`}>
       {
@@ -100,6 +108,7 @@ const ChatWithHistoryWrap: FC<ChatWithHistoryWrapProps> = ({
   const isMobile = media === MediaType.mobile
 
   const {
+    appInfoError,
     appInfoLoading,
     appData,
     appParams,
@@ -132,6 +141,7 @@ const ChatWithHistoryWrap: FC<ChatWithHistoryWrapProps> = ({
 
   return (
     <ChatWithHistoryContext.Provider value={{
+      appInfoError,
       appInfoLoading,
       appData,
       appParams,
@@ -172,15 +182,32 @@ const ChatWithHistoryWrapWithCheckToken: FC<ChatWithHistoryWrapProps> = ({
   className,
 }) => {
   const [inited, setInited] = useState(false)
+  const [appUnavailable, setAppUnavailable] = useState<boolean>(false)
+  const [isUnknwonReason, setIsUnknwonReason] = useState<boolean>(false)
 
   useAsyncEffect(async () => {
     if (!inited) {
-      if (!installedAppInfo)
-        await checkOrSetAccessToken()
+      if (!installedAppInfo) {
+        try {
+          await checkOrSetAccessToken()
+        }
+        catch (e: any) {
+          if (e.status === 404) {
+            setAppUnavailable(true)
+          }
+          else {
+            setIsUnknwonReason(true)
+            setAppUnavailable(true)
+          }
+        }
+      }
       setInited(true)
     }
   }, [])
 
+  if (appUnavailable)
+    return <AppUnavailable isUnknwonReason={isUnknwonReason} />
+
   if (!inited)
     return null