docs: use Kapa React SDK (#12792)
This commit is contained in:
@@ -1,33 +1,33 @@
|
||||
import React, { useEffect, useRef } from "react"
|
||||
import clsx from "clsx"
|
||||
import { useAiAssistantChat } from "../../../../providers/AiAssistant/Chat"
|
||||
import { ArrowUpCircleSolid } from "@medusajs/icons"
|
||||
import { useAiAssistant } from "../../../../providers"
|
||||
import { useChat } from "@kapaai/react-sdk"
|
||||
import { useAiAssistantChatNavigation } from "../../../../hooks"
|
||||
|
||||
export const AiAssistantChatWindowInput = () => {
|
||||
const {
|
||||
inputRef,
|
||||
question,
|
||||
setQuestion,
|
||||
handleSubmit: submitQuestion,
|
||||
loading,
|
||||
getThreadItems,
|
||||
} = useAiAssistantChat()
|
||||
const { chatOpened } = useAiAssistant()
|
||||
type AiAssistantChatWindowInputProps = {
|
||||
chatWindowRef: React.RefObject<HTMLDivElement | null>
|
||||
}
|
||||
|
||||
export const AiAssistantChatWindowInput = ({
|
||||
chatWindowRef,
|
||||
}: AiAssistantChatWindowInputProps) => {
|
||||
const { chatOpened, inputRef, loading } = useAiAssistant()
|
||||
const { submitQuery, conversation } = useChat()
|
||||
const [question, setQuestion] = React.useState("")
|
||||
const formRef = useRef<HTMLFormElement | null>(null)
|
||||
|
||||
const onSubmit = (e?: React.FormEvent<HTMLFormElement>) => {
|
||||
e?.preventDefault()
|
||||
submitQuestion()
|
||||
submitQuery(question)
|
||||
setQuestion("")
|
||||
}
|
||||
|
||||
const handleKeyboardDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||
if (e.key === "ArrowUp" && !question) {
|
||||
const lastQuestion = getThreadItems()
|
||||
.reverse()
|
||||
.find((item) => item.type === "question")
|
||||
const lastQuestion = conversation.getLatest()?.question
|
||||
if (lastQuestion) {
|
||||
setQuestion(lastQuestion.content)
|
||||
setQuestion(lastQuestion)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -87,6 +87,16 @@ export const AiAssistantChatWindowInput = () => {
|
||||
}
|
||||
}, [chatOpened, inputRef.current])
|
||||
|
||||
useAiAssistantChatNavigation({
|
||||
getChatWindowElm: () => chatWindowRef.current as HTMLElement | null,
|
||||
getInputElm: () => inputRef.current as HTMLTextAreaElement | null,
|
||||
focusInput: () =>
|
||||
inputRef.current?.focus({
|
||||
preventScroll: true,
|
||||
}),
|
||||
question,
|
||||
})
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
@@ -103,7 +113,7 @@ export const AiAssistantChatWindowInput = () => {
|
||||
"appearance-none text-base md:text-small placeholder:text-medusa-fg-muted",
|
||||
"text-medusa-fg-base max-h-[210px] overflow-auto resize-none bg-transparent",
|
||||
"focus:outline-none focus:ring-0 disabled:cursor-not-allowed max-h-[210px]",
|
||||
"disabled:!bg-transparent disabled:text-medusa-fg-disabled"
|
||||
"disabled:!bg-transparent disabled:text-medusa-fg-disabled disabled:placeholder:text-medusa-fg-disabled"
|
||||
)}
|
||||
value={question}
|
||||
onChange={(e) => setQuestion(e.target.value)}
|
||||
|
||||
@@ -1,31 +1,37 @@
|
||||
"use client"
|
||||
|
||||
import clsx from "clsx"
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react"
|
||||
import React, {
|
||||
Fragment,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react"
|
||||
import { useAiAssistant, useIsBrowser } from "../../../providers"
|
||||
import { AiAssistantChatWindowHeader } from "./Header"
|
||||
import { useAiAssistantChat } from "../../../providers/AiAssistant/Chat"
|
||||
import { AiAssistantSuggestions } from "../Suggestions"
|
||||
import { AiAssistantThreadItem } from "../ThreadItem"
|
||||
import { AiAssistantChatWindowInput } from "./Input"
|
||||
import { useAiAssistantChatNavigation, useKeyboardShortcut } from "../../.."
|
||||
import { useKeyboardShortcut } from "../../.."
|
||||
import { AiAssistantChatWindowFooter } from "./Footer"
|
||||
import { useChat } from "@kapaai/react-sdk"
|
||||
|
||||
const DEFAULT_HEIGHT = "calc(100% - 8px)"
|
||||
|
||||
export const AiAssistantChatWindow = () => {
|
||||
const { chatOpened, setChatOpened, chatType: type } = useAiAssistant()
|
||||
const {
|
||||
chatOpened,
|
||||
setChatOpened,
|
||||
chatType: type,
|
||||
inputRef,
|
||||
contentRef,
|
||||
loading,
|
||||
} = useAiAssistant()
|
||||
const { conversation, error } = useChat()
|
||||
const [height, setHeight] = useState(DEFAULT_HEIGHT)
|
||||
const [showFade, setShowFade] = useState(false)
|
||||
const { isBrowser } = useIsBrowser()
|
||||
const {
|
||||
inputRef,
|
||||
thread,
|
||||
getThreadItems: getChatThreadItems,
|
||||
answer,
|
||||
loading,
|
||||
contentRef,
|
||||
} = useAiAssistantChat()
|
||||
const chatWindowRef = useRef<HTMLDivElement | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
@@ -39,21 +45,27 @@ export const AiAssistantChatWindow = () => {
|
||||
}, [chatOpened])
|
||||
|
||||
const getThreadItems = useCallback(() => {
|
||||
const sortedThread = getChatThreadItems()
|
||||
|
||||
return sortedThread.map((item, index) => (
|
||||
<AiAssistantThreadItem item={item} key={index} />
|
||||
return conversation.map((item, index) => (
|
||||
<Fragment key={index}>
|
||||
<AiAssistantThreadItem
|
||||
item={{
|
||||
type: "question",
|
||||
content: item.question,
|
||||
sources: item.sources,
|
||||
question_id: item.id,
|
||||
}}
|
||||
/>
|
||||
<AiAssistantThreadItem
|
||||
item={{
|
||||
type: "answer",
|
||||
content: item.answer,
|
||||
sources: item.sources,
|
||||
question_id: item.id,
|
||||
}}
|
||||
/>
|
||||
</Fragment>
|
||||
))
|
||||
}, [getChatThreadItems])
|
||||
|
||||
useAiAssistantChatNavigation({
|
||||
getChatWindowElm: () => chatWindowRef.current as HTMLElement | null,
|
||||
getInputElm: () => inputRef.current as HTMLTextAreaElement | null,
|
||||
focusInput: () =>
|
||||
inputRef.current?.focus({
|
||||
preventScroll: true,
|
||||
}),
|
||||
})
|
||||
}, [conversation])
|
||||
|
||||
useKeyboardShortcut({
|
||||
metakey: false,
|
||||
@@ -75,7 +87,8 @@ export const AiAssistantChatWindow = () => {
|
||||
}
|
||||
setShowFade(
|
||||
!loading &&
|
||||
parentElm.offsetHeight + parentElm.scrollTop < parentElm.scrollHeight
|
||||
parentElm.offsetHeight + parentElm.scrollTop <
|
||||
parentElm.scrollHeight - 1
|
||||
)
|
||||
}
|
||||
|
||||
@@ -168,14 +181,13 @@ export const AiAssistantChatWindow = () => {
|
||||
)}
|
||||
>
|
||||
<div ref={contentRef}>
|
||||
{!thread.length && <AiAssistantSuggestions />}
|
||||
{!conversation.length && <AiAssistantSuggestions />}
|
||||
{getThreadItems()}
|
||||
{(answer.length || loading) && (
|
||||
{error?.length && (
|
||||
<AiAssistantThreadItem
|
||||
item={{
|
||||
type: "answer",
|
||||
content: answer,
|
||||
order: 0,
|
||||
type: "error",
|
||||
content: error,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
@@ -189,7 +201,7 @@ export const AiAssistantChatWindow = () => {
|
||||
)}
|
||||
></span>
|
||||
</div>
|
||||
<AiAssistantChatWindowInput />
|
||||
<AiAssistantChatWindowInput chatWindowRef={chatWindowRef} />
|
||||
<AiAssistantChatWindowFooter />
|
||||
</div>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user