diff --git a/src/knowledgebase/chatbot/chatbot.controller.ts b/src/knowledgebase/chatbot/chatbot.controller.ts index fa16fe7..d6d435f 100644 --- a/src/knowledgebase/chatbot/chatbot.controller.ts +++ b/src/knowledgebase/chatbot/chatbot.controller.ts @@ -125,6 +125,7 @@ export class ChatbotController { id, data.msgIdx, data.feedback, + data.conversationFeedback || false, ); } diff --git a/src/knowledgebase/chatbot/chatbot.dto.ts b/src/knowledgebase/chatbot/chatbot.dto.ts index 88d4ff2..4c28555 100644 --- a/src/knowledgebase/chatbot/chatbot.dto.ts +++ b/src/knowledgebase/chatbot/chatbot.dto.ts @@ -25,6 +25,9 @@ export class SetChatbotSessionMsgFeedbackDTO { @IsEnum(ChatAnswerFeedbackType) feedback: ChatAnswerFeedbackType; + + @IsOptional() + conversationFeedback?: boolean; } export class ChatbotQueryDTO { diff --git a/src/knowledgebase/chatbot/chatbot.service.ts b/src/knowledgebase/chatbot/chatbot.service.ts index 72e2131..2f9cbb0 100644 --- a/src/knowledgebase/chatbot/chatbot.service.ts +++ b/src/knowledgebase/chatbot/chatbot.service.ts @@ -987,22 +987,31 @@ export class ChatbotService { } /** - * Set Feedback for Chat Session Msg by Msg Idx + * Set Feedback for Chat Session Msg by Msg Idx or Conversation Level * @param sessionId * @param msgIdx * @param feedback + * @param isConversationFeedback */ async setSessionMessageFeedback( sessionId: string, msgIdx: number, feedback: ChatAnswerFeedbackType, + isConversationFeedback = false, ) { try { - await this.kbDbService.setChatSessionMessageFeedback( - new ObjectId(sessionId), - msgIdx, - feedback, - ); + if (isConversationFeedback) { + await this.kbDbService.setChatSessionConversationFeedback( + new ObjectId(sessionId), + feedback, + ); + } else { + await this.kbDbService.setChatSessionMessageFeedback( + new ObjectId(sessionId), + msgIdx, + feedback, + ); + } } catch { throw new HttpException('Invalid Session', HttpStatus.NOT_FOUND); } diff --git a/src/knowledgebase/knowledgebase-db.service.ts b/src/knowledgebase/knowledgebase-db.service.ts index 1949963..4f139da 100644 --- a/src/knowledgebase/knowledgebase-db.service.ts +++ b/src/knowledgebase/knowledgebase-db.service.ts @@ -661,6 +661,22 @@ export class KnowledgebaseDbService { ); } + async setChatSessionConversationFeedback( + id: ObjectId, + feedback: ChatAnswerFeedbackType, + ) { + await this.chatSessionCollection.updateOne( + { + _id: id, + }, + { + $set: { + conversationFeedback: feedback, + }, + }, + ); + } + /** ******************************************* * PROMPT RELATED ******************************************** */ diff --git a/src/knowledgebase/knowledgebase.schema.ts b/src/knowledgebase/knowledgebase.schema.ts index 8947dfd..0298ddb 100644 --- a/src/knowledgebase/knowledgebase.schema.ts +++ b/src/knowledgebase/knowledgebase.schema.ts @@ -207,6 +207,7 @@ export interface ChatSession { startedAt: Date; updatedAt: Date; embeddingModel?: EmbeddingModel; + conversationFeedback?: ChatAnswerFeedbackType; } export type ChatSessionSparse = Pick< ChatSession, diff --git a/widget/app.css b/widget/app.css index 37f52da..f77a896 100644 --- a/widget/app.css +++ b/widget/app.css @@ -810,7 +810,7 @@ span.form-required { } @keyframes jumpingAnimation { - 0 { + 0% { transform: translate(0, 0); } @@ -828,7 +828,7 @@ span.form-required { } @keyframes jumpingAnimationSmall { - 0 { + 0% { transform: translate(0, 0); } @@ -1067,4 +1067,67 @@ a.chat-source-btn { height: 14px; margin-right: 5px; color: #757575; +} + +/* Persistent conversation feedback at bottom */ +.conversation-feedback-persistent { + font-size: 12px; + margin-right: 5px; + margin-bottom: 5px; + cursor: pointer; + padding: 5px 8px; + color: #333; + white-space: nowrap; + width: fit-content; +} + +.conversation-feedback-persistent .feedback-buttons { + display: flex; + gap: 12px; + align-items: center; +} + +.conversation-feedback-persistent .feedback-btn { + background: white; + border: 2px solid #e5e7eb; + box-shadow: 0px 5px 6px -4px rgba(0, 0, 0, 0.15); + cursor: pointer; + padding: 10px 12px; + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.2s ease; + opacity: 1; +} + +.conversation-feedback-persistent .feedback-btn:hover { + background-color: rgba(0, 0, 0, 0.04); + box-shadow: 0px 1px 2px 1px rgba(0, 0, 0, 0.08); + transform: translateY(-1px); +} + +.conversation-feedback-persistent .feedback-btn svg { + width: 20px; + height: 20px; + stroke: currentColor; + fill: none; +} + +.conversation-feedback-persistent .feedback-btn.conversation-thumbs-up { + color: #10b981; +} + +.conversation-feedback-persistent .feedback-btn.conversation-thumbs-down { + color: #ef4444; +} + +.conversation-feedback-persistent .feedback-btn.selected { + background-color: rgba(0, 0, 0, 0.04); + box-shadow: 0px 1px 2px 1px rgba(0, 0, 0, 0.08); +} + +.conversation-feedback-persistent .feedback-btn.conversation-thumbs-down.selected { + background-color: rgba(0, 0, 0, 0.04); + box-shadow: 0px 1px 2px 1px rgba(0, 0, 0, 0.08); } \ No newline at end of file diff --git a/widget/index.html b/widget/index.html index 306c11c..131ce36 100644 --- a/widget/index.html +++ b/widget/index.html @@ -165,6 +165,22 @@