@@ -82,7 +82,7 @@ export function EditWorkflowModal({ token, repo, onClose, onSave }: Props) {
8282 return (
8383 < div className = "fixed inset-0 z-50 flex items-center justify-center bg-black/60" onClick = { onClose } >
8484 < div
85- className = "w-[480px ] max-h-[90vh] overflow-y-auto rounded-xl border border-neutral-7 bg-neutral-11 p-6 shadow-2xl"
85+ className = "w-[720px ] max-h-[90vh] overflow-y-auto rounded-xl border border-neutral-7 bg-neutral-11 p-6 shadow-2xl"
8686 onClick = { e => e . stopPropagation ( ) }
8787 >
8888 { /* Header */ }
@@ -101,115 +101,121 @@ export function EditWorkflowModal({ token, repo, onClose, onSave }: Props) {
101101 </ div >
102102
103103 < form onSubmit = { handleSubmit } className = "space-y-5" >
104- { /* Workflow kind */ }
105- < div >
106- < div className = "flex items-center justify-between mb-2" >
107- < label className = "text-[13px] font-medium text-neutral-3" > Workflow type</ label >
108- < CategoryBadge kind = { form . kind } />
109- </ div >
110- < div className = "grid grid-cols-2 gap-2" >
111- { WORKFLOW_KINDS . map ( k => (
112- < button
113- key = { k . value }
114- type = "button"
115- onClick = { ( ) => setForm ( f => ( { ...f , kind : k . value } ) ) }
116- className = { `rounded-lg border px-3 py-2.5 text-left transition-colors ${
117- form . kind === k . value
118- ? 'border-accent-6 bg-accent-9/30 ring-1 ring-accent-6/30'
119- : 'border-neutral-7 bg-neutral-10 hover:border-neutral-6'
120- } `}
121- >
122- < span className = { `block text-[15px] font-medium ${
123- form . kind === k . value ? 'text-accent-2' : 'text-neutral-2'
124- } `} >
125- { k . label }
126- </ span >
127- </ button >
128- ) ) }
129- </ div >
130- </ div >
131-
132- { /* Schedule — hidden for event-driven workflows */ }
133- { eventDriven ? (
134- < div className = "rounded-lg border border-purple-700/40 bg-purple-900/20 px-4 py-3" >
135- < span className = "text-[14px] font-medium text-purple-400" >
136- { form . kind === 'pr-review' ? 'Trigger: On pull request' : 'Trigger: On commit' }
137- </ span >
138- < p className = "text-[13px] text-neutral-4 mt-1" >
139- { form . kind === 'pr-review'
140- ? 'Each PR will be reviewed automatically when opened, updated, or reopened. No schedule needed.'
141- : 'Each commit will be reviewed automatically. No schedule needed.' }
142- </ p >
143- </ div >
144- ) : (
104+ { /* Two-column layout: Workflow type | Schedule + Provider */ }
105+ < div className = "grid grid-cols-2 gap-5" >
106+ { /* Left column — Workflow kind */ }
145107 < div >
146- < label className = "block text-[13px] font-medium text-neutral-3 mb-2" > Time</ label >
147- < TimePicker
148- hour = { form . cronHour }
149- minute = { form . cronMinute }
150- onChange = { ( h , m ) => setForm ( f => ( { ...f , cronHour : h , cronMinute : m } ) ) }
151- className = "mb-3"
152- />
153- < label className = "block text-[13px] font-medium text-neutral-3 mb-2" > Frequency</ label >
154- < div className = "flex flex-wrap gap-1.5 mb-2" >
155- { DAY_PRESETS . map ( p => (
156- < button
157- key = { p . dow }
158- type = "button"
159- onClick = { ( ) => setForm ( f => ( { ...f , cronDow : p . dow } ) ) }
160- className = { btnClass ( form . cronDow === p . dow ) }
161- >
162- { p . label }
163- </ button >
164- ) ) }
108+ < div className = "flex items-center justify-between mb-2" >
109+ < label className = "text-[13px] font-medium text-neutral-3" > Workflow type</ label >
110+ < CategoryBadge kind = { form . kind } />
165111 </ div >
166- < div className = "flex gap-1.5 " >
167- { DAY_INDIVIDUAL . map ( p => (
112+ < div className = "grid grid-cols-2 gap-2 " >
113+ { WORKFLOW_KINDS . map ( k => (
168114 < button
169- key = { p . dow }
115+ key = { k . value }
170116 type = "button"
171- onClick = { ( ) => setForm ( f => ( { ...f , cronDow : biweekly ? `biweekly-${ p . dow } ` : p . dow } ) ) }
172- className = { btnClass ( baseDow === p . dow ) }
117+ onClick = { ( ) => setForm ( f => ( { ...f , kind : k . value } ) ) }
118+ className = { `rounded-lg border px-3 py-2.5 text-left transition-colors ${
119+ form . kind === k . value
120+ ? 'border-accent-6 bg-accent-9/30 ring-1 ring-accent-6/30'
121+ : 'border-neutral-7 bg-neutral-10 hover:border-neutral-6'
122+ } `}
173123 >
174- { p . label }
124+ < span className = { `block text-[13px] font-medium ${
125+ form . kind === k . value ? 'text-accent-2' : 'text-neutral-2'
126+ } `} >
127+ { k . label }
128+ </ span >
175129 </ button >
176130 ) ) }
177131 </ div >
178- { isDay && (
179- < div className = "flex gap-1.5 mt-2" >
180- < button type = "button" onClick = { ( ) => setForm ( f => ( { ...f , cronDow : baseDow } ) ) } className = { btnClass ( ! biweekly ) } >
181- Every week
182- </ button >
183- < button type = "button" onClick = { ( ) => setForm ( f => ( { ...f , cronDow : `biweekly-${ baseDow } ` } ) ) } className = { btnClass ( biweekly ) } >
184- Every 2 weeks
185- </ button >
132+ </ div >
133+
134+ { /* Right column — Schedule + Provider */ }
135+ < div className = "space-y-4" >
136+ { /* Schedule — hidden for event-driven workflows */ }
137+ { eventDriven ? (
138+ < div className = "rounded-lg border border-purple-700/40 bg-purple-900/20 px-4 py-3" >
139+ < span className = "text-[14px] font-medium text-purple-400" >
140+ { form . kind === 'pr-review' ? 'Trigger: On pull request' : 'Trigger: On commit' }
141+ </ span >
142+ < p className = "text-[13px] text-neutral-4 mt-1" >
143+ { form . kind === 'pr-review'
144+ ? 'Each PR will be reviewed automatically when opened, updated, or reopened. No schedule needed.'
145+ : 'Each commit will be reviewed automatically. No schedule needed.' }
146+ </ p >
147+ </ div >
148+ ) : (
149+ < div >
150+ < label className = "block text-[13px] font-medium text-neutral-3 mb-2" > Time</ label >
151+ < TimePicker
152+ hour = { form . cronHour }
153+ minute = { form . cronMinute }
154+ onChange = { ( h , m ) => setForm ( f => ( { ...f , cronHour : h , cronMinute : m } ) ) }
155+ className = "mb-3"
156+ />
157+ < label className = "block text-[13px] font-medium text-neutral-3 mb-2" > Frequency</ label >
158+ < div className = "flex flex-wrap gap-1.5 mb-2" >
159+ { DAY_PRESETS . map ( p => (
160+ < button
161+ key = { p . dow }
162+ type = "button"
163+ onClick = { ( ) => setForm ( f => ( { ...f , cronDow : p . dow } ) ) }
164+ className = { btnClass ( form . cronDow === p . dow ) }
165+ >
166+ { p . label }
167+ </ button >
168+ ) ) }
169+ </ div >
170+ < div className = "flex flex-wrap gap-1.5" >
171+ { DAY_INDIVIDUAL . map ( p => (
172+ < button
173+ key = { p . dow }
174+ type = "button"
175+ onClick = { ( ) => setForm ( f => ( { ...f , cronDow : biweekly ? `biweekly-${ p . dow } ` : p . dow } ) ) }
176+ className = { btnClass ( baseDow === p . dow ) }
177+ >
178+ { p . label }
179+ </ button >
180+ ) ) }
181+ </ div >
182+ { isDay && (
183+ < div className = "flex gap-1.5 mt-2" >
184+ < button type = "button" onClick = { ( ) => setForm ( f => ( { ...f , cronDow : baseDow } ) ) } className = { btnClass ( ! biweekly ) } >
185+ Every week
186+ </ button >
187+ < button type = "button" onClick = { ( ) => setForm ( f => ( { ...f , cronDow : `biweekly-${ baseDow } ` } ) ) } className = { btnClass ( biweekly ) } >
188+ Every 2 weeks
189+ </ button >
190+ </ div >
191+ ) }
192+ < div className = "mt-2 text-[13px] text-neutral-5" >
193+ { describeCron ( buildCron ( form . cronHour , form . cronDow , form . cronMinute ) ) }
194+ </ div >
186195 </ div >
187196 ) }
188- < div className = "mt-2 text-[13px] text-neutral-5" >
189- { describeCron ( buildCron ( form . cronHour , form . cronDow , form . cronMinute ) ) }
190- </ div >
191- </ div >
192- ) }
193197
194- { /* Provider + Model selection */ }
195- < ProviderModelSection
196- token = { token }
197- workingDir = { repo . repoPath }
198- provider = { form . provider }
199- model = { form . model }
200- onProviderChange = { provider => setForm ( f => ( { ...f , provider } ) ) }
201- onModelChange = { model => setForm ( f => ( { ...f , model } ) ) }
202- />
198+ { /* Provider + Model selection */ }
199+ < ProviderModelSection
200+ token = { token }
201+ workingDir = { repo . repoPath }
202+ provider = { form . provider }
203+ model = { form . model }
204+ onProviderChange = { provider => setForm ( f => ( { ...f , provider } ) ) }
205+ onModelChange = { model => setForm ( f => ( { ...f , model } ) ) }
206+ />
207+ </ div >
208+ </ div >
203209
204- { /* Custom prompt */ }
210+ { /* Custom prompt — full width */ }
205211 < div >
206212 < label className = "block text-[13px] font-medium text-neutral-3 mb-1.5" >
207213 Focus areas < span className = "text-neutral-5 font-normal" > (optional)</ span >
208214 </ label >
209215 < textarea
210216 value = { form . customPrompt }
211217 onChange = { e => setForm ( f => ( { ...f , customPrompt : e . target . value } ) ) }
212- rows = { 3 }
218+ rows = { 2 }
213219 placeholder = "e.g. Focus on the auth module and payment flows"
214220 className = "w-full rounded-md border border-neutral-7 bg-neutral-10 px-3 py-2 text-[15px] text-neutral-1 placeholder-neutral-5 focus:border-accent-6 focus:outline-none resize-none"
215221 />
0 commit comments