From dd6547de065d370592ec07aff31ffdde7395ae96 Mon Sep 17 00:00:00 2001 From: znn Date: Tue, 2 Sep 2025 07:27:04 +0530 Subject: [PATCH] downvote with reason (#24922) --- .../base/chat/chat-with-history/hooks.tsx | 2 +- .../base/chat/chat/answer/operation.tsx | 52 +++++++++++++++++-- .../base/chat/embedded-chatbot/hooks.tsx | 2 +- web/app/components/base/chat/types.ts | 1 + .../share/text-generation/result/index.tsx | 2 +- web/i18n/en-US/common.ts | 6 +++ 6 files changed, 59 insertions(+), 6 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 e87c8ddcd..13594a84e 100644 --- a/web/app/components/base/chat/chat-with-history/hooks.tsx +++ b/web/app/components/base/chat/chat-with-history/hooks.tsx @@ -508,7 +508,7 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => { }, [mutateAppConversationData, handleConversationIdInfoChange]) const handleFeedback = useCallback(async (messageId: string, feedback: Feedback) => { - await updateFeedback({ url: `/messages/${messageId}/feedbacks`, body: { rating: feedback.rating } }, isInstalledApp, appId) + await updateFeedback({ url: `/messages/${messageId}/feedbacks`, body: { rating: feedback.rating, content: feedback.content } }, isInstalledApp, appId) notify({ type: 'success', message: t('common.api.success') }) }, [isInstalledApp, appId, t, notify]) diff --git a/web/app/components/base/chat/chat/answer/operation.tsx b/web/app/components/base/chat/chat/answer/operation.tsx index 0fbb7ceef..7ffb21c6d 100644 --- a/web/app/components/base/chat/chat/answer/operation.tsx +++ b/web/app/components/base/chat/chat/answer/operation.tsx @@ -20,6 +20,8 @@ import EditReplyModal from '@/app/components/app/annotation/edit-annotation-moda import Log from '@/app/components/base/chat/chat/log' import ActionButton, { ActionButtonState } from '@/app/components/base/action-button' import NewAudioButton from '@/app/components/base/new-audio-button' +import Modal from '@/app/components/base/modal/modal' +import Textarea from '@/app/components/base/textarea' import cn from '@/utils/classnames' type OperationProps = { @@ -32,6 +34,7 @@ type OperationProps = { hasWorkflowProcess: boolean noChatInput?: boolean } + const Operation: FC = ({ item, question, @@ -52,6 +55,8 @@ const Operation: FC = ({ onRegenerate, } = useChatContext() const [isShowReplyModal, setIsShowReplyModal] = useState(false) + const [isShowFeedbackModal, setIsShowFeedbackModal] = useState(false) + const [feedbackContent, setFeedbackContent] = useState('') const { id, isOpeningStatement, @@ -70,14 +75,29 @@ const Operation: FC = ({ return messageContent }, [agent_thoughts, messageContent]) - const handleFeedback = async (rating: 'like' | 'dislike' | null) => { + const handleFeedback = async (rating: 'like' | 'dislike' | null, content?: string) => { if (!config?.supportFeedback || !onFeedback) return - await onFeedback?.(id, { rating }) + await onFeedback?.(id, { rating, content }) setLocalFeedback({ rating }) } + const handleThumbsDown = () => { + setIsShowFeedbackModal(true) + } + + const handleFeedbackSubmit = async () => { + await handleFeedback('dislike', feedbackContent) + setFeedbackContent('') + setIsShowFeedbackModal(false) + } + + const handleFeedbackCancel = () => { + setFeedbackContent('') + setIsShowFeedbackModal(false) + } + const operationWidth = useMemo(() => { let width = 0 if (!isOpeningStatement) @@ -153,7 +173,7 @@ const Operation: FC = ({ handleFeedback('like')}> - handleFeedback('dislike')}> + @@ -188,6 +208,32 @@ const Operation: FC = ({ createdAt={annotation?.created_at} onRemove={() => onAnnotationRemoved?.(index)} /> + {isShowFeedbackModal && ( + +
+
+ +