From fd6476b941bd7ca09351476378f31fdd6116836d Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Wed, 9 Oct 2024 17:45:38 +0800 Subject: [PATCH] fix: start chat check & chat send button theme --- .../base/chat/chat-with-history/hooks.tsx | 45 +++++++++++++------ .../base/chat/chat/chat-input-area/index.tsx | 3 +- .../chat/chat/chat-input-area/operation.tsx | 10 +++++ .../base/chat/embedded-chatbot/hooks.tsx | 45 +++++++++++++------ 4 files changed, 76 insertions(+), 27 deletions(-) diff --git a/web/app/components/base/chat/chat-with-history/hooks.tsx b/web/app/components/base/chat/chat-with-history/hooks.tsx index 3a8eb5c7e3..d4fa170e4c 100644 --- a/web/app/components/base/chat/chat-with-history/hooks.tsx +++ b/web/app/components/base/chat/chat-with-history/hooks.tsx @@ -37,6 +37,8 @@ import type { import { useToastContext } from '@/app/components/base/toast' import { changeLanguage } from '@/i18n/i18next-config' import { useAppFavicon } from '@/hooks/use-app-favicon' +import { InputVarType } from '@/app/components/workflow/types' +import { TransferMethod } from '@/types/app' export const useChatWithHistory = (installedAppInfo?: InstalledApp) => { const isInstalledApp = useMemo(() => !!installedAppInfo, [installedAppInfo]) @@ -220,21 +222,38 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => { const { notify } = useToastContext() const checkInputsRequired = useCallback((silent?: boolean) => { - if (inputsForms.length) { - for (let i = 0; i < inputsForms.length; i += 1) { - const item = inputsForms[i] - - if (item.required && !newConversationInputsRef.current[item.variable]) { - if (!silent) { - notify({ - type: 'error', - message: t('appDebug.errorMessage.valueOfVarRequired', { key: item.variable }), - }) - } + let hasEmptyInput = '' + let fileIsUploading = false + const requiredVars = inputsForms.filter(({ required }) => required) + if (requiredVars.length) { + requiredVars.forEach(({ variable, label, type }) => { + if (hasEmptyInput) return + + if (fileIsUploading) + return + + if (!newConversationInputsRef.current[variable] && !silent) + hasEmptyInput = label as string + + if ((type === InputVarType.singleFile || type === InputVarType.multiFiles) && newConversationInputsRef.current[variable] && !silent) { + const files = newConversationInputsRef.current[variable] + if (Array.isArray(files)) + fileIsUploading = files.find(item => item.transferMethod === TransferMethod.local_file && !item.uploadedId) + else + fileIsUploading = files.transferMethod === TransferMethod.local_file && !files.uploadedId } - } - return true + }) + } + + if (hasEmptyInput) { + notify({ type: 'error', message: t('appDebug.errorMessage.valueOfVarRequired', { key: hasEmptyInput }) }) + return false + } + + if (fileIsUploading) { + notify({ type: 'info', message: t('appDebug.errorMessage.waitForFileUpload') }) + return } return true diff --git a/web/app/components/base/chat/chat/chat-input-area/index.tsx b/web/app/components/base/chat/chat/chat-input-area/index.tsx index 72be8a58af..8a5c5298c1 100644 --- a/web/app/components/base/chat/chat/chat-input-area/index.tsx +++ b/web/app/components/base/chat/chat/chat-input-area/index.tsx @@ -50,7 +50,7 @@ const ChatInputArea = ({ onSend, inputs = {}, inputsForm = [], - // theme, + theme, }: ChatInputAreaProps) => { const { t } = useTranslation() const { notify } = useToastContext() @@ -127,6 +127,7 @@ const ChatInputArea = ({ speechToTextConfig={speechToTextConfig} onShowVoiceInput={handleShowVoiceInput} onSend={handleSend} + theme={theme} /> ) diff --git a/web/app/components/base/chat/chat/chat-input-area/operation.tsx b/web/app/components/base/chat/chat/chat-input-area/operation.tsx index f5bd86cf03..56ca863681 100644 --- a/web/app/components/base/chat/chat/chat-input-area/operation.tsx +++ b/web/app/components/base/chat/chat/chat-input-area/operation.tsx @@ -9,6 +9,7 @@ import { import type { EnableType, } from '../../types' +import type { Theme } from '../../embedded-chatbot/theme/theme-context' import Button from '@/app/components/base/button' import ActionButton from '@/app/components/base/action-button' import { FileUploaderInChatInput } from '@/app/components/base/file-uploader' @@ -20,12 +21,14 @@ type OperationProps = { speechToTextConfig?: EnableType onShowVoiceInput?: () => void onSend: () => void + theme?: Theme | null } const Operation = forwardRef(({ fileConfig, speechToTextConfig, onShowVoiceInput, onSend, + theme, }, ref) => { return (
(({ className='ml-3 px-0 w-8' variant='primary' onClick={onSend} + style={ + theme + ? { + backgroundColor: theme.primaryColor, + } + : {} + } > diff --git a/web/app/components/base/chat/embedded-chatbot/hooks.tsx b/web/app/components/base/chat/embedded-chatbot/hooks.tsx index affd3c5955..631d3b56bc 100644 --- a/web/app/components/base/chat/embedded-chatbot/hooks.tsx +++ b/web/app/components/base/chat/embedded-chatbot/hooks.tsx @@ -30,6 +30,8 @@ import type { } from '@/models/share' import { useToastContext } from '@/app/components/base/toast' import { changeLanguage } from '@/i18n/i18next-config' +import { InputVarType } from '@/app/components/workflow/types' +import { TransferMethod } from '@/types/app' export const useEmbeddedChatbot = () => { const isInstalledApp = false @@ -206,21 +208,38 @@ export const useEmbeddedChatbot = () => { const { notify } = useToastContext() const checkInputsRequired = useCallback((silent?: boolean) => { - if (inputsForms.length) { - for (let i = 0; i < inputsForms.length; i += 1) { - const item = inputsForms[i] - - if (item.required && !newConversationInputsRef.current[item.variable]) { - if (!silent) { - notify({ - type: 'error', - message: t('appDebug.errorMessage.valueOfVarRequired', { key: item.variable }), - }) - } + let hasEmptyInput = '' + let fileIsUploading = false + const requiredVars = inputsForms.filter(({ required }) => required) + if (requiredVars.length) { + requiredVars.forEach(({ variable, label, type }) => { + if (hasEmptyInput) return + + if (fileIsUploading) + return + + if (!newConversationInputsRef.current[variable] && !silent) + hasEmptyInput = label as string + + if ((type === InputVarType.singleFile || type === InputVarType.multiFiles) && newConversationInputsRef.current[variable] && !silent) { + const files = newConversationInputsRef.current[variable] + if (Array.isArray(files)) + fileIsUploading = files.find(item => item.transferMethod === TransferMethod.local_file && !item.uploadedId) + else + fileIsUploading = files.transferMethod === TransferMethod.local_file && !files.uploadedId } - } - return true + }) + } + + if (hasEmptyInput) { + notify({ type: 'error', message: t('appDebug.errorMessage.valueOfVarRequired', { key: hasEmptyInput }) }) + return false + } + + if (fileIsUploading) { + notify({ type: 'info', message: t('appDebug.errorMessage.waitForFileUpload') }) + return } return true