@@ -12,6 +12,8 @@ import {
1212 Box ,
1313 Braces ,
1414 CheckSquare ,
15+ ChevronDown ,
16+ ChevronUp ,
1517 FileText ,
1618 Hash ,
1719 Minus ,
@@ -96,7 +98,10 @@ export function StepDetailPanel({ className }: StepDetailPanelProps) {
9698
9799 return (
98100 < div
99- className = { cn ( "flex flex-col h-full bg-sidebar overflow-auto" , className ) }
101+ className = { cn (
102+ "flex flex-col h-full bg-sidebar overflow-hidden" ,
103+ className ,
104+ ) }
100105 >
101106 < StepHeader step = { currentStep } />
102107 < InputSection step = { currentStep } />
@@ -118,7 +123,7 @@ function StepHeader({ step }: { step: Step }) {
118123 const trackingExecutionId = useTrackingExecutionId ( ) ;
119124
120125 return (
121- < div className = "border-b border-border p-5 shrink-0" >
126+ < div className = "border-b border-border p-5 shrink-0 flex flex-col gap-2 " >
122127 < div className = "flex items-center gap-2" >
123128 < IntegrationIcon
124129 icon = { null }
@@ -251,6 +256,7 @@ function InputSection({ step }: { step: Step }) {
251256
252257function OutputSection ( { step } : { step : Step } ) {
253258 const outputSchema = step . outputSchema ;
259+ const [ isOpen , setIsOpen ] = useState ( false ) ;
254260 const trackingExecutionId = useTrackingExecutionId ( ) ;
255261 const { output, error } = useExecutionCompletedStep (
256262 trackingExecutionId ,
@@ -269,50 +275,46 @@ function OutputSection({ step }: { step: Step }) {
269275 const propertyEntries = properties ? Object . entries ( properties ) : [ ] ;
270276
271277 return (
272- < Accordion
273- type = "single"
274- collapsible
275- defaultValue = "output"
276- className = "border-b border-border shrink-0"
278+ < div
279+ className = { cn (
280+ "flex flex-col border-b border-border" ,
281+ isOpen ? "flex-1 min-h-0 overflow-hidden" : "shrink-0" ,
282+ ) }
277283 >
278- < AccordionItem value = "output" className = "border-b-0" >
279- < AccordionTrigger className = "px-5 py-5" >
280- < span className = "text-sm font-medium text-muted-foreground" >
281- Output
282- </ span >
283- </ AccordionTrigger >
284- < AccordionContent className = "px-5 pt-2" >
285- { propertyEntries . length === 0 ? (
286- < div className = "text-sm text-muted-foreground italic" >
287- No output schema defined
288- </ div >
289- ) : content ? (
290- < OutputMonacoEditor output = { content } />
284+ < div
285+ className = "p-5 shrink-0 cursor-pointer hover:bg-accent/50 transition-colors"
286+ onClick = { ( ) => setIsOpen ( ! isOpen ) }
287+ >
288+ < div className = "flex items-center justify-between" >
289+ < h3 className = "text-sm font-medium text-muted-foreground" > Output</ h3 >
290+ { isOpen ? (
291+ < ChevronUp size = { 14 } className = "text-muted-foreground" />
291292 ) : (
292- < div className = "space-y-2" >
293- { propertyEntries . map ( ( [ key , propSchema ] ) => (
294- < OutputProperty
295- key = { key }
296- name = { key }
297- schema = { propSchema as JsonSchema }
298- />
299- ) ) }
300- </ div >
293+ < ChevronDown size = { 14 } className = "text-muted-foreground" />
301294 ) }
302- </ AccordionContent >
303- </ AccordionItem >
304- </ Accordion >
305- ) ;
306- }
307-
308- function OutputMonacoEditor ( { output } : { output : unknown } ) {
309- const code = JSON . stringify ( output , null , 2 ) ;
310- const lineCount = code . split ( "\n" ) . length ;
311- // ~18px per line (fontSize 13 + line spacing) + 24px padding
312- const height = Math . min ( Math . max ( lineCount * 18 + 24 , 80 ) , 400 ) ;
313-
314- return (
315- < MonacoCodeEditor code = { code } language = "json" height = { height } readOnly />
295+ </ div >
296+ </ div >
297+ { isOpen && (
298+ < div className = "flex-1 min-h-0 overflow-auto px-5" >
299+ { trackingExecutionId ? (
300+ < MonacoCodeEditor
301+ code = { JSON . stringify ( content , null , 2 ) }
302+ language = "json"
303+ height = "100%"
304+ readOnly
305+ />
306+ ) : null }
307+ { ! trackingExecutionId &&
308+ propertyEntries . map ( ( [ key , propSchema ] ) => (
309+ < OutputProperty
310+ key = { key }
311+ name = { key }
312+ schema = { propSchema as JsonSchema }
313+ />
314+ ) ) }
315+ </ div >
316+ ) }
317+ </ div >
316318 ) ;
317319}
318320
@@ -484,7 +486,7 @@ export default async function(input: Input): Promise<Output> {
484486
485487 // Has transform code → show editor with Minus to remove
486488 return (
487- < div className = "flex-1 flex flex-col min-h-0" >
489+ < div className = "flex flex-col flex-1 min-h-0 overflow-hidden border-b border-border " >
488490 < div
489491 className = "p-5 shrink-0 cursor-pointer hover:bg-accent/50 transition-colors"
490492 onClick = { handleRemoveTransformCode }
@@ -496,7 +498,7 @@ export default async function(input: Input): Promise<Output> {
496498 < Minus size = { 14 } className = "text-muted-foreground" />
497499 </ div >
498500 </ div >
499- < div className = "flex-1 min-h-120 " >
501+ < div className = "flex-1 min-h-0 " >
500502 < MonacoCodeEditor
501503 key = { `transform-code-${ step . name } -${ trackingExecutionId } ` }
502504 code = { transformCode ! }
@@ -532,7 +534,12 @@ function StepCodeSection({ step }: { step: Step }) {
532534 return null ;
533535 }
534536 return (
535- < div className = "flex-1 flex flex-col min-h-0" >
537+ < div
538+ className = { cn (
539+ "flex flex-col border-b border-border" ,
540+ isOpen ? "flex-1 min-h-0 overflow-hidden" : "shrink-0" ,
541+ ) }
542+ >
536543 < div
537544 className = "p-5 shrink-0 cursor-pointer hover:bg-accent/50 transition-colors"
538545 onClick = { ( ) => setIsOpen ( ! isOpen ) }
@@ -542,14 +549,14 @@ function StepCodeSection({ step }: { step: Step }) {
542549 Step Code
543550 </ h3 >
544551 { isOpen ? (
545- < Minus size = { 14 } className = "text-muted-foreground" />
552+ < ChevronUp size = { 14 } className = "text-muted-foreground" />
546553 ) : (
547- < Plus size = { 14 } className = "text-muted-foreground" />
554+ < ChevronDown size = { 14 } className = "text-muted-foreground" />
548555 ) }
549556 </ div >
550557 </ div >
551558 { isOpen && (
552- < div className = "flex-1 min-h-120 h-full " >
559+ < div className = "flex-1 min-h-0 " >
553560 < MonacoCodeEditor
554561 onSave = { ( code , outputSchema ) => handleCodeSave ( code , outputSchema ) }
555562 key = { `step-code-${ step . name } -${ trackingExecutionId } ` }
0 commit comments