@@ -2,7 +2,11 @@ import Skeleton from "@mui/material/Skeleton";
2
2
import { API } from "api/api" ;
3
3
import { getErrorDetail , getErrorMessage } from "api/errors" ;
4
4
import { disabledRefetchOptions } from "api/queries/util" ;
5
- import type { Template , TemplateVersionExternalAuth } from "api/typesGenerated" ;
5
+ import type {
6
+ Preset ,
7
+ Template ,
8
+ TemplateVersionExternalAuth ,
9
+ } from "api/typesGenerated" ;
6
10
import { ErrorAlert } from "components/Alert/ErrorAlert" ;
7
11
import { Avatar } from "components/Avatar/Avatar" ;
8
12
import { AvatarData } from "components/Avatar/AvatarData" ;
@@ -50,7 +54,7 @@ import { RedoIcon, RotateCcwIcon, SendIcon } from "lucide-react";
50
54
import { AI_PROMPT_PARAMETER_NAME , type Task } from "modules/tasks/tasks" ;
51
55
import { WorkspaceAppStatus } from "modules/workspaces/WorkspaceAppStatus/WorkspaceAppStatus" ;
52
56
import { generateWorkspaceName } from "modules/workspaces/generateWorkspaceName" ;
53
- import { type FC , type ReactNode , useState } from "react" ;
57
+ import { type FC , type ReactNode , useEffect , useState } from "react" ;
54
58
import { Helmet } from "react-helmet-async" ;
55
59
import { useMutation , useQuery , useQueryClient } from "react-query" ;
56
60
import { Link as RouterLink , useNavigate } from "react-router-dom" ;
@@ -210,7 +214,11 @@ const TaskFormSection: FC<{
210
214
) ;
211
215
} ;
212
216
213
- type CreateTaskMutationFnProps = { prompt : string ; templateVersionId : string } ;
217
+ type CreateTaskMutationFnProps = {
218
+ prompt : string ;
219
+ templateVersionId : string ;
220
+ presetId : string | null ;
221
+ } ;
214
222
215
223
type TaskFormProps = {
216
224
templates : Template [ ] ;
@@ -223,6 +231,8 @@ const TaskForm: FC<TaskFormProps> = ({ templates, onSuccess }) => {
223
231
const [ selectedTemplateId , setSelectedTemplateId ] = useState < string > (
224
232
templates [ 0 ] . id ,
225
233
) ;
234
+ const [ presets , setPresets ] = useState < Preset [ ] | null > ( null ) ;
235
+ const [ selectedPresetId , setSelectedPresetId ] = useState < string | null > ( null ) ;
226
236
const selectedTemplate = templates . find (
227
237
( t ) => t . id === selectedTemplateId ,
228
238
) as Template ;
@@ -232,6 +242,28 @@ const TaskForm: FC<TaskFormProps> = ({ templates, onSuccess }) => {
232
242
isPollingExternalAuth,
233
243
isLoadingExternalAuth,
234
244
} = useExternalAuth ( selectedTemplate . active_version_id ) ;
245
+
246
+ // Fetch presets when template changes
247
+ const { data : presetsData } = useQuery < Preset [ ] | null , Error > ( {
248
+ queryKey : [ "template-version-presets" , selectedTemplate . active_version_id ] ,
249
+ queryFn : ( ) =>
250
+ API . getTemplateVersionPresets ( selectedTemplate . active_version_id ) ,
251
+ ...disabledRefetchOptions ,
252
+ } ) ;
253
+
254
+ // Handle preset data changes
255
+ useEffect ( ( ) => {
256
+ if ( presetsData ) {
257
+ setPresets ( presetsData ) ;
258
+ // Set default preset if available
259
+ const defaultPreset = presetsData . find ( ( p : Preset ) => p . Default ) ;
260
+ if ( defaultPreset ) {
261
+ setSelectedPresetId ( defaultPreset . ID ) ;
262
+ } else {
263
+ setSelectedPresetId ( null ) ;
264
+ }
265
+ }
266
+ } , [ presetsData ] ) ;
235
267
const missedExternalAuth = externalAuth ?. filter (
236
268
( auth ) => ! auth . optional && ! auth . authenticated ,
237
269
) ;
@@ -243,8 +275,9 @@ const TaskForm: FC<TaskFormProps> = ({ templates, onSuccess }) => {
243
275
mutationFn : async ( {
244
276
prompt,
245
277
templateVersionId,
278
+ presetId,
246
279
} : CreateTaskMutationFnProps ) =>
247
- data . createTask ( prompt , user . id , templateVersionId ) ,
280
+ data . createTask ( prompt , user . id , templateVersionId , presetId ) ,
248
281
onSuccess : async ( task ) => {
249
282
await queryClient . invalidateQueries ( {
250
283
queryKey : [ "tasks" ] ,
@@ -265,6 +298,7 @@ const TaskForm: FC<TaskFormProps> = ({ templates, onSuccess }) => {
265
298
await createTaskMutation . mutateAsync ( {
266
299
prompt,
267
300
templateVersionId : selectedTemplate . active_version_id ,
301
+ presetId : selectedPresetId ,
268
302
} ) ;
269
303
} catch ( error ) {
270
304
const message = getErrorMessage ( error , "Error creating task" ) ;
@@ -297,27 +331,50 @@ const TaskForm: FC<TaskFormProps> = ({ templates, onSuccess }) => {
297
331
text-sm shadow-sm text-content-primary placeholder:text-content-secondary md:text-sm` }
298
332
/>
299
333
< div className = "flex items-center justify-between pt-2" >
300
- < Select
301
- name = "templateID"
302
- onValueChange = { ( value ) => setSelectedTemplateId ( value ) }
303
- defaultValue = { templates [ 0 ] . id }
304
- required
305
- >
306
- < SelectTrigger className = "w-52 text-xs [&_svg]:size-icon-xs border-0 bg-surface-secondary h-8 px-3" >
307
- < SelectValue placeholder = "Select a template" />
308
- </ SelectTrigger >
309
- < SelectContent >
310
- { templates . map ( ( template ) => {
311
- return (
312
- < SelectItem value = { template . id } key = { template . id } >
313
- < span className = "overflow-hidden text-ellipsis block" >
314
- { template . display_name || template . name }
315
- </ span >
316
- </ SelectItem >
317
- ) ;
318
- } ) }
319
- </ SelectContent >
320
- </ Select >
334
+ < div className = "flex items-center gap-2" >
335
+ < Select
336
+ name = "templateID"
337
+ onValueChange = { ( value ) => setSelectedTemplateId ( value ) }
338
+ defaultValue = { templates [ 0 ] . id }
339
+ required
340
+ >
341
+ < SelectTrigger className = "w-40 text-xs [&_svg]:size-icon-xs border-0 bg-surface-secondary h-8 px-3" >
342
+ < SelectValue placeholder = "Select a template" />
343
+ </ SelectTrigger >
344
+ < SelectContent >
345
+ { templates . map ( ( template ) => {
346
+ return (
347
+ < SelectItem value = { template . id } key = { template . id } >
348
+ < span className = "overflow-hidden text-ellipsis block" >
349
+ { template . display_name || template . name }
350
+ </ span >
351
+ </ SelectItem >
352
+ ) ;
353
+ } ) }
354
+ </ SelectContent >
355
+ </ Select >
356
+
357
+ { presets && presets . length > 0 && (
358
+ < Select
359
+ name = "presetID"
360
+ value = { selectedPresetId === null ? undefined : selectedPresetId }
361
+ onValueChange = { ( value ) => setSelectedPresetId ( value ) }
362
+ >
363
+ < SelectTrigger className = "w-40 text-xs [&_svg]:size-icon-xs border-0 bg-surface-secondary h-8 px-3" >
364
+ < SelectValue placeholder = "Select a preset" />
365
+ </ SelectTrigger >
366
+ < SelectContent >
367
+ { presets . map ( ( preset ) => (
368
+ < SelectItem value = { preset . ID } key = { preset . ID } >
369
+ < span className = "overflow-hidden text-ellipsis block" >
370
+ { preset . Name } { preset . Default && "(Default)" }
371
+ </ span >
372
+ </ SelectItem >
373
+ ) ) }
374
+ </ SelectContent >
375
+ </ Select >
376
+ ) }
377
+ </ div >
321
378
322
379
< div className = "flex items-center gap-2" >
323
380
{ missedExternalAuth && (
@@ -608,13 +665,20 @@ export const data = {
608
665
prompt : string ,
609
666
userId : string ,
610
667
templateVersionId : string ,
668
+ presetId : string | null = null ,
611
669
) : Promise < Task > {
612
- const presets = await API . getTemplateVersionPresets ( templateVersionId ) ;
613
- const defaultPreset = presets ?. find ( ( p ) => p . Default ) ;
670
+ // If no preset is selected, get the default preset
671
+ let preset_id : string | undefined = presetId || undefined ;
672
+ if ( ! preset_id ) {
673
+ const presets = await API . getTemplateVersionPresets ( templateVersionId ) ;
674
+ const defaultPreset = presets ?. find ( ( p ) => p . Default ) ;
675
+ preset_id = defaultPreset ?. ID ;
676
+ }
677
+
614
678
const workspace = await API . createWorkspace ( userId , {
615
679
name : `task-${ generateWorkspaceName ( ) } ` ,
616
680
template_version_id : templateVersionId ,
617
- template_version_preset_id : defaultPreset ?. ID ,
681
+ template_version_preset_id : preset_id || undefined ,
618
682
rich_parameter_values : [
619
683
{ name : AI_PROMPT_PARAMETER_NAME , value : prompt } ,
620
684
] ,
0 commit comments