Skip to content

Commit 13124c7

Browse files
committed
fix layout (again)
1 parent 9622dd6 commit 13124c7

3 files changed

Lines changed: 123 additions & 116 deletions

File tree

src/index.tsx

Lines changed: 107 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -481,67 +481,125 @@ function AppContent() {
481481
borderColor="#30363D"
482482
/>
483483

484-
{/* Spans Section - Resizable with drag handle */}
484+
{/* Spans Section - fills remaining space above metrics */}
485+
<box
486+
flexDirection="column"
487+
paddingLeft={1}
488+
paddingRight={1}
489+
flexGrow={1}
490+
minHeight={6}
491+
>
492+
<text style={{ fg: getSectionHeaderColor("spans") }}>
493+
{`Spans (${spanCount()}) - Active: ${store.activeClient
494+
.pipe(Option.map((c) => c.name))
495+
.pipe(Option.getOrElse(() => "None"))}`}
496+
</text>
497+
498+
{/* Span filter input (shown when typing) */}
499+
<Show when={store.ui.showSpanFilter}>
500+
<SpanFilterInput />
501+
</Show>
502+
503+
{/* Active filter indicator (shown when filter closed but query active) */}
504+
<Show
505+
when={
506+
!store.ui.showSpanFilter && store.ui.spanFilterQuery.length > 0
507+
}
508+
>
509+
<box
510+
flexDirection="row"
511+
width="100%"
512+
paddingLeft={1}
513+
paddingBottom={1}
514+
flexShrink={0}
515+
>
516+
<text style={{ fg: "#f7768e" }}>
517+
{`Filter: "${store.ui.spanFilterQuery}" (press / to edit, Esc to clear)`}
518+
</text>
519+
</box>
520+
</Show>
521+
522+
{/* Side-by-side: Span list and details */}
523+
<box flexDirection="row" flexGrow={1}>
524+
{/* Span list - left side */}
525+
<scrollbox
526+
ref={(r) => (spansScrollBoxRef = r)}
527+
width="60%"
528+
marginRight={1}
529+
>
530+
<SpanTreeView
531+
spans={store.spans}
532+
selectedSpanId={store.ui.selectedSpanId}
533+
expandedSpanIds={store.ui.expandedSpanIds}
534+
filterQuery={store.ui.spanFilterQuery || undefined}
535+
/>
536+
</scrollbox>
537+
538+
{/* Span Details - right side */}
539+
<scrollbox
540+
width="40%"
541+
paddingLeft={1}
542+
style={{
543+
rootOptions: {
544+
border: ["left"],
545+
borderColor: "#30363D",
546+
},
547+
}}
548+
>
549+
<Show
550+
when={store.ui.selectedSpanId !== null}
551+
fallback={
552+
<text style={{ fg: "#565f89" }}>
553+
{`Select a span with j/k\nPress → to expand or Enter`}
554+
</text>
555+
}
556+
>
557+
<SpanDetailsPanel
558+
spans={store.spans}
559+
spanId={store.ui.selectedSpanId}
560+
/>
561+
</Show>
562+
</scrollbox>
563+
</box>
564+
</box>
565+
566+
{/* Metrics Section - Resizable with drag handle at top */}
485567
<ResizableBox
486-
height={store.ui.spansHeight}
568+
height={store.ui.metricsHeight}
487569
minHeight={6}
488-
maxHeight={50}
489-
onResize={actions.setSpansHeight}
570+
maxHeight={30}
571+
onResize={actions.setMetricsHeight}
572+
invertDelta
573+
handlePosition="top"
490574
>
491575
<box
492576
flexDirection="column"
493-
paddingLeft={1}
494-
paddingRight={1}
577+
padding={1}
578+
paddingBottom={0}
495579
flexGrow={1}
496580
>
497-
<text style={{ fg: getSectionHeaderColor("spans") }}>
498-
{`Spans (${spanCount()}) - Active: ${store.activeClient
499-
.pipe(Option.map((c) => c.name))
500-
.pipe(Option.getOrElse(() => "None"))}`}
501-
</text>
502-
503-
{/* Span filter input (shown when typing) */}
504-
<Show when={store.ui.showSpanFilter}>
505-
<SpanFilterInput />
506-
</Show>
507-
508-
{/* Active filter indicator (shown when filter closed but query active) */}
509-
<Show
510-
when={
511-
!store.ui.showSpanFilter &&
512-
store.ui.spanFilterQuery.length > 0
513-
}
581+
<text
582+
style={{ fg: getSectionHeaderColor("metrics") }}
583+
marginBottom={1}
514584
>
515-
<box
516-
flexDirection="row"
517-
width="100%"
518-
paddingLeft={1}
519-
paddingBottom={1}
520-
flexShrink={0}
521-
>
522-
<text style={{ fg: "#f7768e" }}>
523-
{`Filter: "${store.ui.spanFilterQuery}" (press / to edit, Esc to clear)`}
524-
</text>
525-
</box>
526-
</Show>
585+
{`Metrics (${metricCount()})`}
586+
</text>
527587

528-
{/* Side-by-side: Span list and details */}
588+
{/* Side-by-side: Metrics list and details */}
529589
<box flexDirection="row" flexGrow={1}>
530-
{/* Span list - left side */}
590+
{/* Metrics list - left side */}
531591
<scrollbox
532-
ref={(r) => (spansScrollBoxRef = r)}
533592
width="60%"
534593
marginRight={1}
594+
focused={store.ui.focusedSection === "metrics"}
535595
>
536-
<SpanTreeView
537-
spans={store.spans}
538-
selectedSpanId={store.ui.selectedSpanId}
539-
expandedSpanIds={store.ui.expandedSpanIds}
540-
filterQuery={store.ui.spanFilterQuery || undefined}
596+
<MetricsView
597+
metrics={store.metrics}
598+
selectedMetricName={store.ui.selectedMetricName}
541599
/>
542600
</scrollbox>
543601

544-
{/* Span Details - right side */}
602+
{/* Metric Details - right side */}
545603
<scrollbox
546604
width="40%"
547605
paddingLeft={1}
@@ -553,80 +611,22 @@ function AppContent() {
553611
}}
554612
>
555613
<Show
556-
when={store.ui.selectedSpanId !== null}
614+
when={store.ui.selectedMetricName !== null}
557615
fallback={
558616
<text style={{ fg: "#565f89" }}>
559-
{`Select a span with j/k\nPress → to expand or Enter`}
617+
{`Select a metric\nwith j/k`}
560618
</text>
561619
}
562620
>
563-
<SpanDetailsPanel
564-
spans={store.spans}
565-
spanId={store.ui.selectedSpanId}
621+
<MetricDetailsPanel
622+
metrics={store.metrics}
623+
metricName={store.ui.selectedMetricName}
566624
/>
567625
</Show>
568626
</scrollbox>
569627
</box>
570628
</box>
571629
</ResizableBox>
572-
573-
{/* Metrics Section - fills remaining space */}
574-
<box
575-
flexDirection="column"
576-
padding={1}
577-
paddingBottom={0}
578-
flexGrow={1}
579-
minHeight={8}
580-
maxHeight={15}
581-
>
582-
<text
583-
style={{ fg: getSectionHeaderColor("metrics") }}
584-
marginBottom={1}
585-
>
586-
{`Metrics (${metricCount()})`}
587-
</text>
588-
589-
{/* Side-by-side: Metrics list and details */}
590-
<box flexDirection="row" flexGrow={1}>
591-
{/* Metrics list - left side */}
592-
<scrollbox
593-
width="60%"
594-
marginRight={1}
595-
focused={store.ui.focusedSection === "metrics"}
596-
>
597-
<MetricsView
598-
metrics={store.metrics}
599-
selectedMetricName={store.ui.selectedMetricName}
600-
/>
601-
</scrollbox>
602-
603-
{/* Metric Details - right side */}
604-
<scrollbox
605-
width="40%"
606-
paddingLeft={1}
607-
style={{
608-
rootOptions: {
609-
border: ["left"],
610-
borderColor: "#30363D",
611-
},
612-
}}
613-
>
614-
<Show
615-
when={store.ui.selectedMetricName !== null}
616-
fallback={
617-
<text style={{ fg: "#565f89" }}>
618-
{`Select a metric\nwith j/k`}
619-
</text>
620-
}
621-
>
622-
<MetricDetailsPanel
623-
metrics={store.metrics}
624-
metricName={store.ui.selectedMetricName}
625-
/>
626-
</Show>
627-
</scrollbox>
628-
</box>
629-
</box>
630630
</Show>
631631

632632
{/* Fix Tab */}

src/resizableBox.tsx

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export interface ResizableBoxProps {
2222
onResize: (height: number) => void;
2323
children: JSX.Element;
2424
invertDelta?: boolean;
25+
handlePosition?: "top" | "bottom";
2526
}
2627

2728
/**
@@ -109,7 +110,10 @@ class DragHandle extends BoxRenderable {
109110
}
110111

111112
/**
112-
* ResizableBox component - renders content with a draggable separator at the bottom
113+
* ResizableBox component - renders content with a draggable separator
114+
*
115+
* Simple approach: uses fixed height (no flexGrow). The parent layout should use
116+
* flexGrow on the sibling elements to fill remaining space.
113117
*/
114118
export function ResizableBox(props: ResizableBoxProps) {
115119
const renderer = useContext(RendererContext);
@@ -119,12 +123,13 @@ export function ResizableBox(props: ResizableBoxProps) {
119123

120124
const minHeight = props.minHeight ?? 5;
121125
const maxHeight = props.maxHeight ?? 100;
126+
const handlePosition = props.handlePosition ?? "bottom";
122127

123128
const dragHandle = new DragHandle(
124129
renderer,
125130
minHeight,
126131
maxHeight,
127-
() => props.height,
132+
() => props.height, // Simple: height IS the actual height
128133
props.onResize,
129134
props.invertDelta,
130135
);
@@ -134,18 +139,20 @@ export function ResizableBox(props: ResizableBoxProps) {
134139
return (
135140
<box
136141
flexDirection="column"
137-
flexGrow={1}
138-
flexShrink={1}
139-
flexBasis={props.height}
142+
height={props.height} // Fixed height - what you set is what you get
140143
minHeight={minHeight}
144+
flexShrink={0} // Don't shrink below our height
141145
>
146+
{/* Drag handle at top if specified */}
147+
{handlePosition === "top" && dragHandle}
148+
142149
{/* Content area */}
143150
<box flexGrow={1} flexDirection="column">
144151
{childrenFn()}
145152
</box>
146153

147-
{/* Drag handle at bottom */}
148-
{dragHandle}
154+
{/* Drag handle at bottom if specified */}
155+
{handlePosition === "bottom" && dragHandle}
149156
</box>
150157
);
151158
}

src/store.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,8 @@ export function StoreProvider(props: ParentProps) {
199199
expandedSpanIds: new Set(),
200200
expandedTraceIds: new Set(),
201201
clientsExpanded: false,
202-
spansHeight: 12, // Default height for spans section (allows metrics to show on short terminals)
203-
metricsHeight: 6,
202+
spansHeight: 25, // Legacy - no longer used for layout
203+
metricsHeight: 12, // Fixed height for metrics section
204204
spanFilterQuery: "",
205205
showSpanFilter: false,
206206

0 commit comments

Comments
 (0)