@@ -29,7 +29,7 @@ import {
29
29
} from "components/Tooltip/Tooltip" ;
30
30
import { useAuthenticated } from "hooks/useAuthenticated" ;
31
31
import { useExternalAuth } from "hooks/useExternalAuth" ;
32
- import { ArrowUpIcon , RedoIcon , RotateCcwIcon } from "lucide-react" ;
32
+ import { RedoIcon , RotateCcwIcon , SendIcon } from "lucide-react" ;
33
33
import { AI_PROMPT_PARAMETER_NAME } from "modules/tasks/tasks" ;
34
34
import { type FC , useEffect , useState } from "react" ;
35
35
import { useMutation , useQuery , useQueryClient } from "react-query" ;
@@ -106,8 +106,8 @@ const TaskPromptSkeleton: FC = () => {
106
106
107
107
{ /* Bottom controls skeleton */ }
108
108
< div className = "flex items-center justify-between pt-2" >
109
- < Skeleton className = "w-[160px ] h-8 rounded-full " />
110
- < Skeleton className = "size-8 rounded-full " />
109
+ < Skeleton className = "w-[208px ] h-8" />
110
+ < Skeleton className = "w-[96px] h-8 " />
111
111
</ div >
112
112
</ div >
113
113
</ div >
@@ -160,17 +160,15 @@ const CreateTaskForm: FC<CreateTaskFormProps> = ({ templates, onSuccess }) => {
160
160
} = useExternalAuth ( selectedTemplate . active_version_id ) ;
161
161
162
162
// Fetch presets when template changes
163
- const { data :presets } = useQuery (
163
+ const { data :presets , isLoading : isLoadingPresets } = useQuery (
164
164
templateVersionPresets ( selectedTemplate . active_version_id ) ,
165
165
) ;
166
+ const defaultPreset = presets ?. find ( ( p ) => p . Default ) ;
166
167
167
168
// Handle preset selection when data changes
168
169
useEffect ( ( ) => {
169
- if ( presets && presets . length > 0 ) {
170
- const defaultPreset = presets . find ( ( p ) => p . Default ) || presets [ 0 ] ;
171
- setSelectedPresetId ( defaultPreset . ID ) ;
172
- }
173
- } , [ presets ] ) ;
170
+ setSelectedPresetId ( defaultPreset ?. ID ) ;
171
+ } , [ defaultPreset ?. ID ] ) ;
174
172
175
173
// Extract AI prompt from selected preset
176
174
const selectedPreset = presets ?. find ( ( p ) => p . ID === selectedPresetId ) ;
@@ -227,7 +225,7 @@ const CreateTaskForm: FC<CreateTaskFormProps> = ({ templates, onSuccess }) => {
227
225
{ externalAuthError && < ErrorAlert error = { externalAuthError } /> }
228
226
229
227
< fieldset
230
- className = "border border-border border-solid rounded-3xl p-4"
228
+ className = "border border-border border-solid rounded-lg p-4"
231
229
disabled = { createTaskMutation . isPending }
232
230
>
233
231
< label
@@ -253,22 +251,23 @@ const CreateTaskForm: FC<CreateTaskFormProps> = ({ templates, onSuccess }) => {
253
251
} `}
254
252
/>
255
253
< div className = "flex items-center justify-between pt-2" >
256
- < div className = "flex items-center gap-2" >
257
- < div >
258
- < label htmlFor = "templateID" className = "sr-only" >
254
+ < div className = "flex items-center gap-4" >
255
+ < div className = "flex flex-col gap-1" >
256
+ < label
257
+ htmlFor = "templateID"
258
+ className = "text-xs font-medium text-content-primary"
259
+ >
259
260
Template
260
261
</ label >
261
262
< Select
262
263
name = "templateID"
263
- onValueChange = { ( value ) => {
264
- setSelectedTemplateId ( value ) ;
265
- } }
264
+ onValueChange = { ( value ) => setSelectedTemplateId ( value ) }
266
265
defaultValue = { templates [ 0 ] . id }
267
266
required
268
267
>
269
268
< SelectTrigger
270
269
id = "templateID"
271
- className = "w-fit text-xs [&_svg]:size-icon-xs border-0 bg-surface-secondary h-8 px-3 rounded-full "
270
+ className = "w-80 text-xs [&_svg]:size-icon-xs border-0 bg-surface-secondary h-8 px-3"
272
271
>
273
272
< SelectValue placeholder = "Select a template" />
274
273
</ SelectTrigger >
@@ -286,34 +285,50 @@ const CreateTaskForm: FC<CreateTaskFormProps> = ({ templates, onSuccess }) => {
286
285
</ Select >
287
286
</ div >
288
287
289
- { selectedPresetId && (
290
- < div >
291
- < label htmlFor = "presetID" className = "sr-only" >
288
+ { isLoadingPresets ?(
289
+ < div className = "flex flex-col gap-1" >
290
+ < label
291
+ htmlFor = "presetID"
292
+ className = "text-xs font-medium text-content-primary"
293
+ >
292
294
Preset
293
295
</ label >
294
- < Select
295
- key = { `preset-select-${ selectedTemplate . active_version_id } ` }
296
- name = "presetID"
297
- value = { selectedPresetId }
298
- onValueChange = { setSelectedPresetId }
299
- >
300
- < SelectTrigger
301
- id = "presetID"
302
- className = "w-fit text-xs [&_svg]:size-icon-xs border-0 bg-surface-secondary h-8 px-3 rounded-full"
303
- >
304
- < SelectValue placeholder = "Select a preset" />
305
- </ SelectTrigger >
306
- < SelectContent >
307
- { presets ?. toSorted ( sortByDefault ) . map ( ( preset ) => (
308
- < SelectItem value = { preset . ID } key = { preset . ID } >
309
- < span className = "overflow-hidden text-ellipsis block" >
310
- { preset . Name } { preset . Default && "(Default)" }
311
- </ span >
312
- </ SelectItem >
313
- ) ) }
314
- </ SelectContent >
315
- </ Select >
296
+ < Skeleton className = "w-[320px] h-8" />
316
297
</ div >
298
+ ) :(
299
+ presets &&
300
+ presets . length > 0 && (
301
+ < div className = "flex flex-col gap-1" >
302
+ < label
303
+ htmlFor = "presetID"
304
+ className = "text-xs font-medium text-content-primary"
305
+ >
306
+ Preset
307
+ </ label >
308
+ < Select
309
+ key = { `preset-select-${ selectedTemplate . active_version_id } ` }
310
+ name = "presetID"
311
+ value = { selectedPresetId || undefined }
312
+ onValueChange = { setSelectedPresetId }
313
+ >
314
+ < SelectTrigger
315
+ id = "presetID"
316
+ className = "w-80 text-xs [&_svg]:size-icon-xs border-0 bg-surface-secondary h-8 px-3"
317
+ >
318
+ < SelectValue placeholder = "Select a preset" />
319
+ </ SelectTrigger >
320
+ < SelectContent >
321
+ { presets . toSorted ( sortByDefault ) . map ( ( preset ) => (
322
+ < SelectItem value = { preset . ID } key = { preset . ID } >
323
+ < span className = "overflow-hidden text-ellipsis block" >
324
+ { preset . Name } { preset . Default && "(Default)" }
325
+ </ span >
326
+ </ SelectItem >
327
+ ) ) }
328
+ </ SelectContent >
329
+ </ Select >
330
+ </ div >
331
+ )
317
332
) }
318
333
</ div >
319
334
@@ -325,22 +340,17 @@ const CreateTaskForm: FC<CreateTaskFormProps> = ({ templates, onSuccess }) => {
325
340
/>
326
341
) }
327
342
328
- < Button
329
- size = "icon"
330
- className = "rounded-full"
331
- type = "submit"
332
- disabled = { isMissingExternalAuth }
333
- >
343
+ < Button size = "sm" type = "submit" disabled = { isMissingExternalAuth } >
334
344
< Spinner
335
345
loading = {
336
346
isLoadingExternalAuth ||
337
347
isPollingExternalAuth ||
338
348
createTaskMutation . isPending
339
349
}
340
350
>
341
- < ArrowUpIcon />
351
+ < SendIcon />
342
352
</ Spinner >
343
- < span className = "sr-only" > Run task</ span >
353
+ Run task
344
354
</ Button >
345
355
</ div >
346
356
</ div >
@@ -370,7 +380,6 @@ const ExternalAuthButtons: FC<ExternalAuthButtonProps> = ({
370
380
< div className = "flex items-center gap-2" key = { auth . id } >
371
381
< Button
372
382
variant = "outline"
373
- className = "rounded-full"
374
383
size = "sm"
375
384
disabled = { isPollingExternalAuth || auth . authenticated }
376
385
onClick = { ( ) => {