feat(chat-ui): integrate chat model selection handling in Composer and related components

This commit is contained in:
Anish Sarkar 2026-06-14 12:40:49 +05:30
parent d9a4f14f99
commit 381d17d9b3
3 changed files with 25 additions and 3 deletions

View file

@ -522,6 +522,11 @@ const Composer: FC = () => {
editorRef.current?.focus();
}, [isDesktop, showDocumentPopover, showPromptPicker, threadId]);
const handleChatModelSelected = useCallback(() => {
if (!isDesktop) return;
editorRef.current?.focus();
}, [isDesktop]);
// Close document picker when a sidebar slide-out panel (inbox, etc.) opens.
// React only on changes to the tick — comparing against the previously-seen
// value preserves the one-shot semantics of the prior window-event approach
@ -935,6 +940,7 @@ const Composer: FC = () => {
<ComposerAction
isBlockedByOtherUser={isBlockedByOtherUser}
searchSpaceId={Number(search_space_id)}
onChatModelSelected={handleChatModelSelected}
/>
<ConnectorIndicator showTrigger={false} />
</div>
@ -955,11 +961,13 @@ const Composer: FC = () => {
interface ComposerActionProps {
isBlockedByOtherUser?: boolean;
searchSpaceId: number;
onChatModelSelected?: () => void;
}
const ComposerAction: FC<ComposerActionProps> = ({
isBlockedByOtherUser = false,
searchSpaceId,
onChatModelSelected,
}) => {
const mentionedDocuments = useAtomValue(mentionedDocumentsAtom);
const setConnectorDialogOpen = useSetAtom(connectorDialogOpenAtom);
@ -1573,6 +1581,7 @@ const ComposerAction: FC<ComposerActionProps> = ({
<ChatHeader
searchSpaceId={searchSpaceId}
className="h-9 max-w-[44vw] px-2 sm:max-w-[220px] sm:px-3"
onChatModelSelected={onChatModelSelected}
/>
<AuiIf condition={({ thread }) => !thread.isRunning}>
<ComposerPrimitive.Send asChild disabled={isSendDisabled}>

View file

@ -5,12 +5,17 @@ import { ModelSelector } from "./model-selector";
interface ChatHeaderProps {
searchSpaceId: number;
className?: string;
onChatModelSelected?: () => void;
}
export function ChatHeader({ searchSpaceId, className }: ChatHeaderProps) {
export function ChatHeader({ searchSpaceId, className, onChatModelSelected }: ChatHeaderProps) {
return (
<div className="flex items-center gap-2">
<ModelSelector searchSpaceId={searchSpaceId} className={className} />
<ModelSelector
searchSpaceId={searchSpaceId}
className={className}
onChatModelSelected={onChatModelSelected}
/>
</div>
);
}

View file

@ -33,6 +33,7 @@ import { providerDisplay } from "../settings/model-connections/provider-metadata
interface ModelSelectorProps {
searchSpaceId: number;
className?: string;
onChatModelSelected?: () => void;
}
type ChatModel = ModelRead & {
@ -82,7 +83,11 @@ function groupedModels(models: ChatModel[]) {
}, {});
}
export function ModelSelector({ searchSpaceId, className }: ModelSelectorProps) {
export function ModelSelector({
searchSpaceId,
className,
onChatModelSelected,
}: ModelSelectorProps) {
const router = useRouter();
const isMobile = useIsMobile();
const [open, setOpen] = useState(false);
@ -114,6 +119,9 @@ export function ModelSelector({ searchSpaceId, className }: ModelSelectorProps)
function selectModel(modelId: number) {
updateRoles.mutate({ chat_model_id: modelId });
setOpen(false);
requestAnimationFrame(() => {
onChatModelSelected?.();
});
}
function manageModelConnections() {