@@ -20,6 +20,8 @@ interface ApiConfigSelectorProps {
2020 listApiConfigMeta : Array < { id : string ; name : string ; modelId ?: string } >
2121 pinnedApiConfigs ?: Record < string , boolean >
2222 togglePinnedApiConfig : ( id : string ) => void
23+ scheduledConfigId ?: string
24+ onScheduleChange ?: ( configId : string | undefined ) => void
2325}
2426
2527export const ApiConfigSelector = ( {
@@ -32,6 +34,8 @@ export const ApiConfigSelector = ({
3234 listApiConfigMeta,
3335 pinnedApiConfigs,
3436 togglePinnedApiConfig,
37+ scheduledConfigId,
38+ onScheduleChange,
3539} : ApiConfigSelectorProps ) => {
3640 const { t } = useAppTranslation ( )
3741 const [ open , setOpen ] = useState ( false )
@@ -73,11 +77,23 @@ export const ApiConfigSelector = ({
7377
7478 const handleSelect = useCallback (
7579 ( configId : string ) => {
76- onChange ( configId )
80+ if ( disabled && onScheduleChange ) {
81+ // When disabled, schedule the change instead of applying immediately
82+ if ( scheduledConfigId === configId ) {
83+ // If clicking the same config, cancel the scheduled change
84+ onScheduleChange ( undefined )
85+ } else {
86+ // Schedule the new config
87+ onScheduleChange ( configId )
88+ }
89+ } else {
90+ // Apply immediately when not disabled
91+ onChange ( configId )
92+ }
7793 setOpen ( false )
7894 setSearchValue ( "" )
7995 } ,
80- [ onChange ] ,
96+ [ disabled , onChange , onScheduleChange , scheduledConfigId ] ,
8197 )
8298
8399 const handleEditClick = useCallback ( ( ) => {
@@ -88,6 +104,7 @@ export const ApiConfigSelector = ({
88104 const renderConfigItem = useCallback (
89105 ( config : { id : string ; name : string ; modelId ?: string } , isPinned : boolean ) => {
90106 const isCurrentConfig = config . id === value
107+ const isScheduledConfig = config . id === scheduledConfigId
91108
92109 return (
93110 < div
@@ -98,6 +115,7 @@ export const ApiConfigSelector = ({
98115 "hover:bg-vscode-list-hoverBackground" ,
99116 isCurrentConfig &&
100117 "bg-vscode-list-activeSelectionBackground text-vscode-list-activeSelectionForeground" ,
118+ isScheduledConfig && ! isCurrentConfig && "border-l-2 border-vscode-focusBorder" ,
101119 ) } >
102120 < div className = "flex-1 min-w-0 flex items-center gap-1 overflow-hidden" >
103121 < span className = "flex-shrink-0" > { config . name } </ span >
@@ -112,11 +130,18 @@ export const ApiConfigSelector = ({
112130 ) }
113131 </ div >
114132 < div className = "flex items-center gap-1" >
115- { isCurrentConfig && (
133+ { isCurrentConfig && ! isScheduledConfig && (
116134 < div className = "size-5 p-1 flex items-center justify-center" >
117135 < span className = "codicon codicon-check text-xs" />
118136 </ div >
119137 ) }
138+ { isScheduledConfig && (
139+ < StandardTooltip content = { disabled ? t ( "chat:scheduledSwitch" ) : t ( "chat:nextModel" ) } >
140+ < div className = "size-5 p-1 flex items-center justify-center" >
141+ < span className = "codicon codicon-clock text-xs text-vscode-focusBorder" />
142+ </ div >
143+ </ StandardTooltip >
144+ ) }
120145 < StandardTooltip content = { isPinned ? t ( "chat:unpin" ) : t ( "chat:pin" ) } >
121146 < Button
122147 variant = "ghost"
@@ -138,25 +163,40 @@ export const ApiConfigSelector = ({
138163 </ div >
139164 )
140165 } ,
141- [ value , handleSelect , t , togglePinnedApiConfig ] ,
166+ [ value , scheduledConfigId , handleSelect , t , togglePinnedApiConfig , disabled ] ,
142167 )
143168
169+ // Get the scheduled config's display name
170+ const scheduledConfigName = useMemo ( ( ) => {
171+ if ( ! scheduledConfigId ) return null
172+ const config = listApiConfigMeta . find ( ( c ) => c . id === scheduledConfigId )
173+ return config ?. name || null
174+ } , [ scheduledConfigId , listApiConfigMeta ] )
175+
144176 return (
145177 < Popover open = { open } onOpenChange = { setOpen } data-testid = "api-config-selector-root" >
146- < StandardTooltip content = { title } >
178+ < StandardTooltip
179+ content = { scheduledConfigName && disabled ? `${ title } (Scheduled: ${ scheduledConfigName } )` : title } >
147180 < PopoverTrigger
148- disabled = { disabled }
181+ disabled = { false } // Always allow opening the dropdown
149182 data-testid = "dropdown-trigger"
150183 className = { cn (
151184 "min-w-0 inline-flex items-center relative whitespace-nowrap px-1.5 py-1 text-xs" ,
152- "bg-transparent border border-[rgba(255,255,255,0.08)] rounded-md text-vscode-foreground" ,
185+ "bg-transparent border rounded-md text-vscode-foreground" ,
153186 "transition-all duration-150 focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder focus-visible:ring-inset" ,
154187 disabled
155- ? "opacity-50 cursor-not-allowed"
156- : "opacity-90 hover:opacity-100 hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)] cursor-pointer" ,
188+ ? scheduledConfigId
189+ ? "border-vscode-focusBorder opacity-70 cursor-pointer hover:opacity-90"
190+ : "border-[rgba(255,255,255,0.08)] opacity-50 cursor-pointer hover:opacity-70"
191+ : "border-[rgba(255,255,255,0.08)] opacity-90 hover:opacity-100 hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)] cursor-pointer" ,
157192 triggerClassName ,
158193 ) } >
159- < span className = "truncate" > { displayName } </ span >
194+ < span className = "truncate flex items-center gap-1" >
195+ { displayName }
196+ { scheduledConfigId && disabled && (
197+ < span className = "codicon codicon-clock text-xs text-vscode-focusBorder" />
198+ ) }
199+ </ span >
160200 </ PopoverTrigger >
161201 </ StandardTooltip >
162202 < PopoverContent
@@ -188,7 +228,11 @@ export const ApiConfigSelector = ({
188228 ) : (
189229 < div className = "p-3 border-b border-vscode-dropdown-border" >
190230 < p className = "text-xs text-vscode-descriptionForeground m-0" >
191- { t ( "prompts:apiConfiguration.select" ) }
231+ { disabled && scheduledConfigId
232+ ? t ( "prompts:apiConfiguration.selectToCancel" )
233+ : disabled
234+ ? t ( "prompts:apiConfiguration.selectToSchedule" )
235+ : t ( "prompts:apiConfiguration.select" ) }
192236 </ p >
193237 </ div >
194238 ) }
0 commit comments