diff --git a/apps/web/src/components/features/input/BusterChatInput/BusterChatInputBase.tsx b/apps/web/src/components/features/input/BusterChatInput/BusterChatInputBase.tsx index a900141ff..ba5812b1e 100644 --- a/apps/web/src/components/features/input/BusterChatInput/BusterChatInputBase.tsx +++ b/apps/web/src/components/features/input/BusterChatInput/BusterChatInputBase.tsx @@ -104,6 +104,10 @@ export const BusterChatInputBase: React.FC = React.memo( onSubmit({ ...value, mode }); }; + const onSuggestionItemClick = useMemoizedFn(() => { + onSubmitPreflight(); + }); + const onCloseCreateShortcutModal = useMemoizedFn(() => { setOpenCreateShortcutModal(false); }); @@ -123,6 +127,7 @@ export const BusterChatInputBase: React.FC = React.memo( e.preventDefault()} content={
diff --git a/apps/web/src/components/ui/inputs/MentionInputSuggestions/MentionInputSuggestions.tsx b/apps/web/src/components/ui/inputs/MentionInputSuggestions/MentionInputSuggestions.tsx index 9d33a67fa..ace33a14c 100644 --- a/apps/web/src/components/ui/inputs/MentionInputSuggestions/MentionInputSuggestions.tsx +++ b/apps/web/src/components/ui/inputs/MentionInputSuggestions/MentionInputSuggestions.tsx @@ -66,6 +66,12 @@ export const MentionInputSuggestions = forwardRef< ? !hasClickedSelect && suggestionItems.length > 0 : isInteracting && suggestionItems.length > 0; + // biome-ignore lint/style/noNonNullAssertion: we know the ref is not null + const getValue = mentionsInputRef.current?.getValue!; + // biome-ignore lint/style/noNonNullAssertion: we know the ref is not null + const addMentionToInput = mentionsInputRef.current?.addMentionToInput!; + const mounted = useMounted(); + const onChangeInputValue: MentionInputProps['onChange'] = useCallback( (d) => { const { transformedValue } = d; @@ -113,17 +119,12 @@ export const MentionInputSuggestions = forwardRef< setValue(stringValue); } onClick?.(); - if (closeSuggestionOnSelect && params.closeOnSelect !== false) setHasClickedSelect(true); onSuggestionItemClick?.(params); + + if (closeSuggestionOnSelect && params.closeOnSelect !== false) setHasClickedSelect(true); } ); - // biome-ignore lint/style/noNonNullAssertion: we know the ref is not null - const getValue = mentionsInputRef.current?.getValue!; - // biome-ignore lint/style/noNonNullAssertion: we know the ref is not null - const addMentionToInput = mentionsInputRef.current?.addMentionToInput!; - const mounted = useMounted(); - const onBlur = useMemoizedFn(() => { setIsInteracting(false); }); @@ -193,6 +194,9 @@ export const MentionInputSuggestions = forwardRef< )} shouldFilter={shouldFilter} filter={filter || customFilter} + onClick={() => { + setIsInteracting(true); + }} > { + const onSelectItem = () => { + onSelect({ + value, + inputValue, + label, + onClick, + addValueToInput, + closeOnSelect, + disabled, + loading, + }); + }; + return ( { + onSelectItem(); + }} onSelect={() => { - onSelect({ - value, - inputValue, - label, - onClick, - addValueToInput, - closeOnSelect, - disabled, - loading, - }); + onSelectItem(); }} > {icon && ( diff --git a/apps/web/src/components/ui/popover/Popover.tsx b/apps/web/src/components/ui/popover/Popover.tsx index 9a4a1a27f..d0661c02b 100644 --- a/apps/web/src/components/ui/popover/Popover.tsx +++ b/apps/web/src/components/ui/popover/Popover.tsx @@ -9,7 +9,7 @@ import { export interface PopoverProps extends React.ComponentProps, - Pick, 'align' | 'side'> { + Pick, 'align' | 'side' | 'onOpenAutoFocus'> { children: React.ReactNode; content: React.ReactNode; className?: string; @@ -28,6 +28,7 @@ export const Popover = React.memo( trigger = 'click', size = 'default', sideOffset, + onOpenAutoFocus, ...props }) => { return ( @@ -41,6 +42,7 @@ export const Popover = React.memo( className={className} size={size} sideOffset={sideOffset} + onOpenAutoFocus={onOpenAutoFocus} > {content} diff --git a/apps/web/src/context/Chats/useChat.ts b/apps/web/src/context/Chats/useChat.ts index b480bbdff..2103f1389 100644 --- a/apps/web/src/context/Chats/useChat.ts +++ b/apps/web/src/context/Chats/useChat.ts @@ -1,4 +1,5 @@ import type { MessageAnalysisMode } from '@buster/server-shared/chats'; +import { useMutation } from '@tanstack/react-query'; import { useNavigate } from '@tanstack/react-router'; import { create } from 'mutative'; import type { FileType } from '@/api/asset_interfaces/chat'; @@ -6,6 +7,7 @@ import { useGetChatMemoized, useGetChatMessageMemoized } from '@/api/buster_rest import { useStartNewChat, useStopChat } from '@/api/buster_rest/chats/queryRequestsV2'; import { useChatUpdate } from '@/api/buster_rest/chats/useChatUpdate'; import { useMemoizedFn } from '@/hooks/useMemoizedFn'; +import { timeout } from '@/lib/timeout'; type StartChatParams = { prompt: string | undefined; @@ -19,39 +21,43 @@ type StartChatParams = { export const useChat = () => { const navigate = useNavigate(); - const { mutateAsync: startNewChat, isPending: isSubmittingChat } = useStartNewChat(); + const { mutateAsync: startNewChatServerFn } = useStartNewChat(); const { mutateAsync: stopChatMutation } = useStopChat(); const getChatMemoized = useGetChatMemoized(); const getChatMessageMemoized = useGetChatMessageMemoized(); const { onUpdateChat, onUpdateChatMessage } = useChatUpdate(); - const startChat = async ({ - prompt, - chatId, - metricId, - dashboardId, - messageId, - mode, - }: StartChatParams) => { - const res = await startNewChat({ + const { mutateAsync: startChat, isPending: isSubmittingChat } = useMutation({ + mutationFn: async ({ prompt, - chat_id: chatId, - metric_id: metricId, - dashboard_id: dashboardId, - message_id: messageId, - message_analysis_mode: mode, - }); - - const { message_ids, id } = res; - - const hasMultipleMessages = message_ids.length > 1; - if (!hasMultipleMessages) { - navigate({ - to: '/app/chats/$chatId', - params: { chatId: id }, + chatId, + metricId, + dashboardId, + messageId, + mode, + }: StartChatParams) => { + const res = await startNewChatServerFn({ + prompt, + chat_id: chatId, + metric_id: metricId, + dashboard_id: dashboardId, + message_id: messageId, + message_analysis_mode: mode, }); - } - }; + + const { message_ids, id } = res; + + const hasMultipleMessages = message_ids.length > 1; + if (!hasMultipleMessages) { + await navigate({ + to: '/app/chats/$chatId', + params: { chatId: id }, + }); + } + + await timeout(150); + }, + }); const onStartNewChat = useMemoizedFn( async (d: { prompt: string; mode: StartChatParams['mode'] }) => {