+
{displayConversation.length === 0 ? (
) : (
displayConversation.map((qa, index) => {
@@ -1567,6 +1828,7 @@ function KapaChatPanel({
addFeedback(qa.id, reaction)
}
}}
+ compact={isDock}
/>
)
})
@@ -1579,9 +1841,14 @@ function KapaChatPanel({
)
@@ -1621,49 +1888,96 @@ function StickyTopBlur() {
function KapaUnavailablePanel({
isFullHeight,
onToggleFullHeight,
+ surface,
+ isDockMaximized = false,
+ onToggleDockMaximized,
}: {
isFullHeight: boolean
onToggleFullHeight: () => void
+ surface: SearchSurface
+ isDockMaximized?: boolean
+ onToggleDockMaximized?: () => void
}) {
- const { closeSearch } = useSearchContext()
- const { selectedLibrary, selectedFramework, showSearchResults } =
+ const { closeSearch, setAiDockDirty } = useSearchContext()
+ const { selectedLibrary, selectedFramework, showSearchResults, searchQuery } =
useSearchFilters()
+ const isDock = surface === 'dock'
+
+ React.useEffect(() => {
+ if (!isDock) {
+ return
+ }
+
+ setAiDockDirty(searchQuery.trim().length > 0)
+ }, [isDock, searchQuery, setAiDockDirty])
return (
-
-
-
-
-
+
+ {isDock ? null :
}
+
+ {isDock ? (
+
+ ) : (
+ <>
+
+
+ >
+ )}
+ {isDock && onToggleDockMaximized ? (
+
+
+
+ ) : null}
-
+
Kapa is not configured. Add{' '}
VITE_KAPA_INTEGRATION_ID to enable
@@ -1674,13 +1988,14 @@ function KapaUnavailablePanel({
selectedFramework={showSearchResults ? selectedFramework : ''}
onSuggestion={() => {}}
disabled
+ compact={isDock}
/>
-
+
-
{}} />
+ {}} surface={surface} />
)
@@ -1690,10 +2005,16 @@ function SearchPanel({
isFullHeight,
onToggleFullHeight,
newChatRequestId,
+ surface,
+ isDockMaximized = false,
+ onToggleDockMaximized,
}: {
isFullHeight: boolean
onToggleFullHeight: () => void
newChatRequestId: number
+ surface: SearchSurface
+ isDockMaximized?: boolean
+ onToggleDockMaximized?: () => void
}) {
const integrationId = env.VITE_KAPA_INTEGRATION_ID
const threadIdOverrideRef = React.useRef
(null)
@@ -1706,11 +2027,21 @@ function SearchPanel({
[],
)
+ React.useEffect(() => {
+ return () => {
+ apiService.abortCurrent()
+ }
+ }, [apiService])
+
return (
{integrationId ? (
@@ -1726,12 +2057,18 @@ function SearchPanel({
onToggleFullHeight={onToggleFullHeight}
threadIdOverrideRef={threadIdOverrideRef}
newChatRequestId={newChatRequestId}
+ surface={surface}
+ isDockMaximized={isDockMaximized}
+ onToggleDockMaximized={onToggleDockMaximized}
/>
) : (
)}
@@ -1742,10 +2079,12 @@ function InputBar({
isBusy,
onAskAISubmit,
onStop,
+ surface,
}: {
isBusy: boolean
onAskAISubmit: (question: string) => void
onStop?: () => void
+ surface: SearchSurface
}) {
const { refine } = useSearchBox()
const { searchQuery, setSearchQuery } = useSearchFilters()
@@ -1753,6 +2092,7 @@ function InputBar({
const hasQuery = trimmedQuery.length > 0
const canAsk = trimmedQuery.length >= 3 && !isBusy
const canStop = isBusy && !!onStop
+ const isDock = surface === 'dock'
const inputRef = React.useRef(null)
React.useEffect(() => {
@@ -1778,7 +2118,7 @@ function InputBar({
}
return (
-
+
@@ -1787,7 +2127,11 @@ function InputBar({
ref={inputRef}
type="search"
aria-label="Search"
- placeholder="Search or ask a question..."
+ placeholder={
+ isDock
+ ? 'Ask AI or search docs...'
+ : 'Search or ask a question...'
+ }
value={searchQuery}
onChange={(event) => {
const nextQuery = event.target.value
@@ -1800,7 +2144,10 @@ function InputBar({
submitQuestion()
}
}}
- className="w-full outline-none [&::-webkit-search-cancel-button]:hidden bg-transparent text-sm text-gray-800 dark:text-gray-100 placeholder:text-gray-400 dark:placeholder:text-gray-500"
+ className={twMerge(
+ 'w-full outline-none [&::-webkit-search-cancel-button]:hidden bg-transparent text-gray-800 dark:text-gray-100 placeholder:text-gray-400 dark:placeholder:text-gray-500',
+ isDock ? 'text-[13px]' : 'text-sm',
+ )}
/>