fix(chat): tidy composer pickers
This commit is contained in:
@@ -57,6 +57,28 @@ type MobileVariantTarget = { providerId: string; modelId: string };
|
|||||||
const buildModelRefKey = (providerID: string, modelID: string) => `${providerID}:${modelID}`;
|
const buildModelRefKey = (providerID: string, modelID: string) => `${providerID}:${modelID}`;
|
||||||
const MAX_INLINE_MOBILE_VARIANT_OPTIONS = 6;
|
const MAX_INLINE_MOBILE_VARIANT_OPTIONS = 6;
|
||||||
|
|
||||||
|
const AgentDescriptionTooltip: React.FC<{
|
||||||
|
description?: string;
|
||||||
|
children: React.ReactElement;
|
||||||
|
}> = ({ description, children }) => {
|
||||||
|
if (!description) {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip delayDuration={450}>
|
||||||
|
<TooltipTrigger asChild>{children}</TooltipTrigger>
|
||||||
|
<TooltipContent
|
||||||
|
side="right"
|
||||||
|
sideOffset={8}
|
||||||
|
className="max-w-xs text-left transition-none data-[starting-style]:opacity-100 data-[starting-style]:scale-100 data-[ending-style]:opacity-100 data-[ending-style]:scale-100"
|
||||||
|
>
|
||||||
|
<span className="typography-meta text-muted-foreground">{description}</span>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const asPermissionRuleset = (value: unknown): PermissionRule[] | null => {
|
const asPermissionRuleset = (value: unknown): PermissionRule[] | null => {
|
||||||
if (!Array.isArray(value)) {
|
if (!Array.isArray(value)) {
|
||||||
return null;
|
return null;
|
||||||
@@ -2316,6 +2338,7 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
|
|||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<DropdownMenuContent
|
<DropdownMenuContent
|
||||||
|
side="top"
|
||||||
className="w-[min(380px,calc(100vw-2rem))] p-0 flex flex-col"
|
className="w-[min(380px,calc(100vw-2rem))] p-0 flex flex-col"
|
||||||
align="end"
|
align="end"
|
||||||
alignOffset={-40}
|
alignOffset={-40}
|
||||||
@@ -2618,7 +2641,7 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<DropdownMenuContent align="end" alignOffset={-40} className="w-[min(180px,calc(100vw-2rem))]">
|
<DropdownMenuContent side="top" align="end" alignOffset={-40} className="w-[min(180px,calc(100vw-2rem))]">
|
||||||
<DropdownMenuLabel className="typography-ui-header font-semibold text-foreground">{t('chat.modelControls.thinking')}</DropdownMenuLabel>
|
<DropdownMenuLabel className="typography-ui-header font-semibold text-foreground">{t('chat.modelControls.thinking')}</DropdownMenuLabel>
|
||||||
<DropdownMenuItem className="typography-meta" onSelect={() => handleVariantSelect(undefined)}>
|
<DropdownMenuItem className="typography-meta" onSelect={() => handleVariantSelect(undefined)}>
|
||||||
<div className="flex items-center justify-between gap-2 w-full min-w-0">
|
<div className="flex items-center justify-between gap-2 w-full min-w-0">
|
||||||
@@ -2708,7 +2731,7 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<DropdownMenuContent align="end" alignOffset={-40} className="w-[min(280px,calc(100vw-2rem))] p-0 flex flex-col">
|
<DropdownMenuContent side="top" align="end" alignOffset={-40} className="w-[min(280px,calc(100vw-2rem))] p-0 flex flex-col">
|
||||||
<div className="p-2 border-b border-border/40">
|
<div className="p-2 border-b border-border/40">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<Icon name="search" className="absolute left-2.5 top-1/2 -translate-y-1/2 size-3.5 text-muted-foreground" />
|
<Icon name="search" className="absolute left-2.5 top-1/2 -translate-y-1/2 size-3.5 text-muted-foreground" />
|
||||||
@@ -2746,12 +2769,11 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
sortedAndFilteredAgents.map((agent) => (
|
sortedAndFilteredAgents.map((agent) => (
|
||||||
<DropdownMenuItem
|
<AgentDescriptionTooltip key={agent.name} description={agent.description}>
|
||||||
key={agent.name}
|
<DropdownMenuItem
|
||||||
className="typography-meta"
|
className="typography-meta"
|
||||||
onSelect={() => handleAgentChange(agent.name)}
|
onSelect={() => handleAgentChange(agent.name)}
|
||||||
>
|
>
|
||||||
<div className="flex flex-col gap-0.5">
|
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<div className={cn(
|
<div className={cn(
|
||||||
'h-1 w-1 rounded-full agent-dot',
|
'h-1 w-1 rounded-full agent-dot',
|
||||||
@@ -2759,13 +2781,8 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
|
|||||||
)} />
|
)} />
|
||||||
<span className="font-medium">{capitalizeAgentName(agent.name)}</span>
|
<span className="font-medium">{capitalizeAgentName(agent.name)}</span>
|
||||||
</div>
|
</div>
|
||||||
{agent.description && (
|
</DropdownMenuItem>
|
||||||
<span className="typography-meta text-muted-foreground max-w-[200px] ml-2.5 break-words">
|
</AgentDescriptionTooltip>
|
||||||
{agent.description}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ export const ComposerAttachmentControls = React.memo(function ComposerAttachment
|
|||||||
<Icon name="add-circle" className={cn(iconSizeClass, 'text-current')} />
|
<Icon name="add-circle" className={cn(iconSizeClass, 'text-current')} />
|
||||||
</button>
|
</button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align="start">
|
<DropdownMenuContent side="top" align="start">
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
onSelect={() => {
|
onSelect={() => {
|
||||||
requestAnimationFrame(handlePickLocalFiles);
|
requestAnimationFrame(handlePickLocalFiles);
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ export function DraftTargetSelectors(props: DraftTargetProps) {
|
|||||||
: <ProjectLabel project={selectedProject} theme={theme} />}
|
: <ProjectLabel project={selectedProject} theme={theme} />}
|
||||||
</SelectValue>
|
</SelectValue>
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent fitContent>
|
<SelectContent side="top" fitContent>
|
||||||
{projects.map((project) => (
|
{projects.map((project) => (
|
||||||
<SelectItem key={project.id} value={project.id} className="max-w-[24rem] truncate">
|
<SelectItem key={project.id} value={project.id} className="max-w-[24rem] truncate">
|
||||||
<ProjectLabel project={project} theme={theme} />
|
<ProjectLabel project={project} theme={theme} />
|
||||||
@@ -144,7 +144,7 @@ export function DraftTargetSelectors(props: DraftTargetProps) {
|
|||||||
{selectedBranchLabel ?? t('chat.chatInput.branch')}
|
{selectedBranchLabel ?? t('chat.chatInput.branch')}
|
||||||
</SelectValue>
|
</SelectValue>
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent className="w-max min-w-48">
|
<SelectContent side="top" className="w-max min-w-48">
|
||||||
{projectRootBranchOption ? (
|
{projectRootBranchOption ? (
|
||||||
<SelectGroup>
|
<SelectGroup>
|
||||||
<SelectLabel>{t('chat.chatInput.projectRoot')}</SelectLabel>
|
<SelectLabel>{t('chat.chatInput.projectRoot')}</SelectLabel>
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { getRegisteredRuntimeAPIs } from '@/contexts/runtimeAPIRegistry';
|
|||||||
import { useI18n } from '@/lib/i18n';
|
import { useI18n } from '@/lib/i18n';
|
||||||
import { parseModelIdentifier } from '@/lib/modelIdentifier';
|
import { parseModelIdentifier } from '@/lib/modelIdentifier';
|
||||||
import { runtimeFetch } from '@/lib/runtime-fetch';
|
import { runtimeFetch } from '@/lib/runtime-fetch';
|
||||||
|
import { isPrimaryMode } from '@/components/chat/mobileControlsUtils';
|
||||||
|
|
||||||
const getDisplayModel = (
|
const getDisplayModel = (
|
||||||
storedModel: string | undefined
|
storedModel: string | undefined
|
||||||
@@ -390,6 +391,7 @@ export const DefaultsSettings: React.FC = () => {
|
|||||||
<AgentSelector
|
<AgentSelector
|
||||||
agentName={defaultAgent || ''}
|
agentName={defaultAgent || ''}
|
||||||
onChange={handleAgentChange}
|
onChange={handleAgentChange}
|
||||||
|
filter={(agent) => isPrimaryMode(agent.mode)}
|
||||||
className={SETTINGS_CUSTOM_TRIGGER_CLASS}
|
className={SETTINGS_CUSTOM_TRIGGER_CLASS}
|
||||||
/>
|
/>
|
||||||
</SettingsFieldRow>
|
</SettingsFieldRow>
|
||||||
|
|||||||
Reference in New Issue
Block a user