Skip to content

Commit 8c443a7

Browse files
committed
add more reponsive layout to fix panel
1 parent 56af7fd commit 8c443a7

File tree

3 files changed

+107
-30
lines changed

3 files changed

+107
-30
lines changed

src/DependencyGraphView.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
import { createMemo, For, Show } from "solid-js";
8+
import { useTerminalDimensions } from "@opentui/solid";
89
import { theme } from "./theme";
910
import { useStore } from "./store";
1011
import type { LayerDefinition } from "./layerResolverCore";
@@ -15,12 +16,12 @@ import {
1516
findOrphans,
1617
} from "./dependencyGraph";
1718

18-
1919
interface DependencyGraphViewProps {
2020
layers: LayerDefinition[];
2121
selectedNode?: string;
2222
onSelectNode?: (name: string) => void;
2323
focused?: boolean;
24+
maxWidth?: number;
2425
}
2526

2627
/**
@@ -117,9 +118,11 @@ export function DependencyGraphView(props: DependencyGraphViewProps) {
117118
if (!layout) {
118119
return ["Failed to layout graph"];
119120
}
121+
// Use provided maxWidth or default to 72 for narrow terminals
122+
const width = props.maxWidth ?? 72;
120123
return renderToAscii(layout, {
121124
selectedNode: props.selectedNode,
122-
maxWidth: 72, // Conservative width for typical 80-col terminals with padding
125+
maxWidth: width,
123126
});
124127
});
125128

@@ -160,9 +163,23 @@ export function DependencyGraphView(props: DependencyGraphViewProps) {
160163
*/
161164
export function DependencyGraphPanel() {
162165
const { store } = useStore();
166+
const dimensions = useTerminalDimensions();
163167

164168
const isFocused = createMemo(() => store.ui.fixTabFocusedPanel === "graph");
165169

170+
// Calculate dynamic max width based on terminal size
171+
// In wide mode (>120), graph takes 60% of width
172+
// In narrow mode, use full width minus padding
173+
const graphMaxWidth = createMemo(() => {
174+
const termWidth = dimensions().width;
175+
if (termWidth > 120) {
176+
// Wide mode: graph is 60% of terminal, minus padding (4 chars)
177+
return Math.floor(termWidth * 0.6) - 4;
178+
}
179+
// Narrow mode: full width minus padding
180+
return termWidth - 4;
181+
});
182+
166183
const layers = createMemo((): LayerDefinition[] => {
167184
// Get layers from analysis results if available
168185
const results = store.ui.layerAnalysisResults;
@@ -215,7 +232,11 @@ export function DependencyGraphPanel() {
215232
</box>
216233
}
217234
>
218-
<DependencyGraphView layers={layers()} focused={isFocused()} />
235+
<DependencyGraphView
236+
layers={layers()}
237+
focused={isFocused()}
238+
maxWidth={graphMaxWidth()}
239+
/>
219240
</Show>
220241
);
221242
}

src/LayerCandidatesPanel.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ import { Show, For, createMemo } from "solid-js";
88
import { theme } from "./theme";
99
import { useStore } from "./store";
1010

11+
interface LayerCandidatesPanelProps {
12+
showLeftBorder?: boolean;
13+
}
1114

12-
export function LayerCandidatesPanel() {
15+
export function LayerCandidatesPanel(props: LayerCandidatesPanelProps) {
1316
const { store } = useStore();
1417

1518
const results = createMemo(() => store.ui.layerAnalysisResults);
@@ -30,13 +33,16 @@ export function LayerCandidatesPanel() {
3033
() => store.ui.fixTabFocusedPanel === "candidates",
3134
);
3235

36+
// Default to showing left border (for narrow horizontal layout)
37+
const showBorder = () => props.showLeftBorder ?? true;
38+
3339
return (
3440
<box
3541
flexDirection="column"
3642
flexGrow={1}
3743
paddingLeft={1}
3844
paddingRight={1}
39-
border={["left"]}
45+
border={showBorder() ? ["left"] : []}
4046
borderColor={theme.border}
4147
>
4248
<text

src/fixTab.tsx

Lines changed: 75 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22
* Fix Tab Component
33
*
44
* Displays the layer analyzer and code fix UI.
5-
* Layout: Graph on top (toggleable), service list and candidates below.
5+
* Responsive layout:
6+
* - Wide (>120 cols): Graph on left, services/candidates stacked on right
7+
* - Narrow (<=120 cols): Graph on top, services/candidates side-by-side below
68
* Note: Status bar is handled by the parent index.tsx component.
79
*/
810

911
import { Show, createMemo } from "solid-js";
12+
import { useTerminalDimensions } from "@opentui/solid";
1013
import { theme } from "./theme";
1114
import { useStore } from "./store";
1215
import { AnalysisStatusView } from "./AnalysisStatusView";
@@ -18,12 +21,16 @@ import { DependencyGraphPanel } from "./DependencyGraphView";
1821
/**
1922
* Main Fix Tab component
2023
*
21-
* Layout when results available:
22-
* - Top: Graph view (toggleable with 'g')
23-
* - Bottom: Services list (left) | Layer candidates (right)
24+
* Responsive layout when results available:
25+
* - Wide (>120 cols): Graph on left (60%), services/candidates stacked on right (40%)
26+
* - Narrow (<=120 cols): Graph on top (60% height), services/candidates side-by-side below
2427
*/
2528
export function FixTab() {
2629
const { store } = useStore();
30+
const dimensions = useTerminalDimensions();
31+
32+
// Responsive breakpoint - matches OpenCode's pattern
33+
const isWide = createMemo(() => dimensions().width > 120);
2734

2835
const showGraph = createMemo(() => store.ui.showDependencyGraph);
2936
const hasPreviousResults = createMemo(
@@ -63,7 +70,7 @@ export function FixTab() {
6370
{/* Results view: graph + service panels */}
6471
<Show when={showResultsView()}>
6572
<box flexGrow={1} flexDirection="column" width="100%">
66-
{/* Re-analyzing indicator - shown above graph when re-analyzing */}
73+
{/* Re-analyzing indicator - shown at top when re-analyzing */}
6774
<Show when={isReAnalyzing()}>
6875
<box
6976
flexDirection="row"
@@ -82,31 +89,74 @@ export function FixTab() {
8289
</box>
8390
</Show>
8491

85-
{/* Graph view (toggleable) */}
86-
<Show when={showGraph()}>
92+
{/* Wide layout: horizontal split (graph left, panels right) */}
93+
<Show when={isWide()}>
94+
<box flexDirection="row" flexGrow={1} width="100%">
95+
{/* Graph on the left - 60% width */}
96+
<Show when={showGraph()}>
97+
<box
98+
flexDirection="column"
99+
width="60%"
100+
height="100%"
101+
border={["right"]}
102+
borderColor={theme.bgSelected}
103+
>
104+
<DependencyGraphPanel />
105+
</box>
106+
</Show>
107+
108+
{/* Services and candidates stacked on the right */}
109+
<box
110+
flexDirection="column"
111+
flexGrow={1}
112+
height="100%"
113+
paddingLeft={2}
114+
paddingRight={2}
115+
paddingTop={1}
116+
>
117+
<box
118+
flexDirection="column"
119+
height="50%"
120+
border={["bottom"]}
121+
borderColor={theme.border}
122+
>
123+
<ServicesListPanel />
124+
</box>
125+
<box flexDirection="column" flexGrow={1} paddingTop={1}>
126+
<LayerCandidatesPanel showLeftBorder={false} />
127+
</box>
128+
</box>
129+
</box>
130+
</Show>
131+
132+
{/* Narrow layout: vertical split (graph top, panels bottom) */}
133+
<Show when={!isWide()}>
134+
{/* Graph view (toggleable) */}
135+
<Show when={showGraph()}>
136+
<box
137+
flexDirection="column"
138+
height="60%"
139+
width="100%"
140+
border={["bottom"]}
141+
borderColor={theme.bgSelected}
142+
>
143+
<DependencyGraphPanel />
144+
</box>
145+
</Show>
146+
147+
{/* Service list and candidates side-by-side */}
87148
<box
88-
flexDirection="column"
89-
height="60%"
149+
flexDirection="row"
150+
flexGrow={1}
90151
width="100%"
91-
border={["bottom"]}
92-
borderColor={theme.bgSelected}
152+
paddingLeft={2}
153+
paddingRight={2}
154+
paddingTop={1}
93155
>
94-
<DependencyGraphPanel />
156+
<ServicesListPanel />
157+
<LayerCandidatesPanel />
95158
</box>
96159
</Show>
97-
98-
{/* Service list and candidates - always visible when results available */}
99-
<box
100-
flexDirection="row"
101-
flexGrow={1}
102-
width="100%"
103-
paddingLeft={2}
104-
paddingRight={2}
105-
paddingTop={1}
106-
>
107-
<ServicesListPanel />
108-
<LayerCandidatesPanel />
109-
</box>
110160
</box>
111161
</Show>
112162
</box>

0 commit comments

Comments
 (0)