feat(web): implement composer suggestion popover and integrate with document mention picker

This commit is contained in:
Anish Sarkar 2026-05-26 13:37:59 +05:30
parent 18c66409a0
commit 0d65a2e4e3
4 changed files with 389 additions and 313 deletions

View file

@ -65,6 +65,7 @@ import {
} from "@/components/assistant-ui/inline-mention-editor";
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
import { UserMessage } from "@/components/assistant-ui/user-message";
import { ComposerSuggestionPopoverContent } from "@/components/new-chat/composer-suggestion-popup";
import {
DocumentMentionPicker,
type DocumentMentionPickerRef,
@ -90,6 +91,7 @@ import {
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Popover, PopoverAnchor } from "@/components/ui/popover";
import { Skeleton } from "@/components/ui/skeleton";
import { Switch } from "@/components/ui/switch";
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
@ -533,6 +535,11 @@ const Composer: FC = () => {
}
}, [showDocumentPopover]);
const handleDocumentPopoverOpenChange = useCallback((open: boolean) => {
setShowDocumentPopover(open);
if (!open) setMentionQuery("");
}, []);
const handleActionTrigger = useCallback((query: string) => {
setShowPromptPicker(true);
setActionQuery(query);
@ -545,6 +552,11 @@ const Composer: FC = () => {
}
}, [showPromptPicker]);
const handlePromptPickerOpenChange = useCallback((open: boolean) => {
setShowPromptPicker(open);
if (!open) setActionQuery("");
}, []);
const handleActionSelect = useCallback(
(action: { name: string; prompt: string; mode: "transform" | "explore" }) => {
let userText = editorRef.current?.getText() ?? "";
@ -723,8 +735,9 @@ const Composer: FC = () => {
currentUserId={currentUser?.id ?? null}
members={members ?? []}
/>
{showDocumentPopover && (
<div className="absolute bottom-full left-0 z-[9999] mb-2">
<Popover open={showDocumentPopover} onOpenChange={handleDocumentPopoverOpenChange}>
<PopoverAnchor className="pointer-events-none absolute inset-0" />
<ComposerSuggestionPopoverContent side="top">
<DocumentMentionPicker
ref={documentPickerRef}
searchSpaceId={Number(search_space_id)}
@ -736,15 +749,11 @@ const Composer: FC = () => {
initialSelectedDocuments={mentionedDocuments}
externalSearch={mentionQuery}
/>
</div>
)}
{showPromptPicker && (
<div
className={cn(
"absolute left-0 z-[9999]",
clipboardInitialText ? "top-full mt-2" : "bottom-full mb-2"
)}
>
</ComposerSuggestionPopoverContent>
</Popover>
<Popover open={showPromptPicker} onOpenChange={handlePromptPickerOpenChange}>
<PopoverAnchor className="pointer-events-none absolute inset-0" />
<ComposerSuggestionPopoverContent side={clipboardInitialText ? "bottom" : "top"}>
<PromptPicker
ref={promptPickerRef}
onSelect={clipboardInitialText ? handleQuickAskSelect : handleActionSelect}
@ -754,8 +763,8 @@ const Composer: FC = () => {
}}
externalSearch={actionQuery}
/>
</div>
)}
</ComposerSuggestionPopoverContent>
</Popover>
<div className="flex w-full flex-col">
<div
className={cn(