Skip to content

Commit 56038fc

Browse files
committed
feat(tui): display endpoint details in selected collection view
1 parent 81cbf9d commit 56038fc

3 files changed

Lines changed: 112 additions & 11 deletions

File tree

internal/tui/app/model.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
7474
m.selectedIndex = m.collectionsView.GetSelectedIndex()
7575
m.mode = SelectedCollectionViewMode
7676
if m.width > 0 && m.height > 0 {
77-
m.selectedCollectionView = views.NewSelectedCollectionViewWithSize(m.ctx.Endpoints, *selectedItem, m.width, m.height)
77+
m.selectedCollectionView = views.NewSelectedCollectionViewWithSize(m.ctx.Endpoints, m.ctx.HTTP, *selectedItem, m.width, m.height)
7878
} else {
79-
m.selectedCollectionView = views.NewSelectedCollectionView(m.ctx.Endpoints, *selectedItem)
79+
m.selectedCollectionView = views.NewSelectedCollectionView(m.ctx.Endpoints, m.ctx.HTTP, *selectedItem)
8080
}
8181
return m, m.selectedCollectionView.Init()
8282
} else {

internal/tui/views/endpoint_sidebar.go

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,30 @@ type EndpointSidebarView struct {
1919
initialized bool
2020
selectedIndex int
2121
endpoints []endpoints.EndpointEntity
22+
focused bool
2223
}
2324

2425
func NewEndpointSidebarView(endpointsManager *endpoints.EndpointsManager, collection collections.CollectionEntity) EndpointSidebarView {
2526
return EndpointSidebarView{
2627
endpointsManager: endpointsManager,
2728
collection: collection,
2829
selectedIndex: 0,
30+
focused: false,
2931
}
3032
}
3133

34+
func (v *EndpointSidebarView) Focus() {
35+
v.focused = true
36+
}
37+
38+
func (v *EndpointSidebarView) Blur() {
39+
v.focused = false
40+
}
41+
42+
func (v EndpointSidebarView) Focused() bool {
43+
return v.focused
44+
}
45+
3246
func (v EndpointSidebarView) Init() tea.Cmd {
3347
return v.loadEndpoints
3448
}
@@ -70,12 +84,38 @@ func (v EndpointSidebarView) Update(msg tea.Msg) (EndpointSidebarView, tea.Cmd)
7084
}
7185
v.initialized = true
7286

87+
// Auto-select first endpoint if available
88+
if len(msg.endpoints) > 0 {
89+
return v, func() tea.Msg {
90+
return EndpointSelectedMsg{Endpoint: msg.endpoints[0]}
91+
}
92+
}
93+
7394
case endpointsLoadError:
7495
v.initialized = true
7596

7697
case tea.KeyMsg:
7798
if v.initialized {
78-
v.list, cmd = v.list.Update(msg)
99+
switch msg.String() {
100+
case "enter":
101+
if selectedEndpoint := v.GetSelectedEndpoint(); selectedEndpoint != nil {
102+
return v, func() tea.Msg {
103+
return EndpointSelectedMsg{Endpoint: *selectedEndpoint}
104+
}
105+
}
106+
default:
107+
// Forward navigation keys to the list even if not explicitly focused
108+
oldIndex := v.list.SelectedIndex()
109+
v.list, cmd = v.list.Update(msg)
110+
newIndex := v.list.SelectedIndex()
111+
112+
// If the selected index changed, auto-select the new endpoint
113+
if oldIndex != newIndex && newIndex >= 0 && newIndex < len(v.endpoints) {
114+
return v, func() tea.Msg {
115+
return EndpointSelectedMsg{Endpoint: v.endpoints[newIndex]}
116+
}
117+
}
118+
}
79119
}
80120
}
81121

internal/tui/views/selected_collection.go

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,37 @@ import (
55
"github.com/charmbracelet/lipgloss"
66
"github.com/maniac-en/req/internal/backend/collections"
77
"github.com/maniac-en/req/internal/backend/endpoints"
8+
"github.com/maniac-en/req/internal/backend/http"
89
"github.com/maniac-en/req/internal/tui/components"
910
"github.com/maniac-en/req/internal/tui/styles"
1011
)
1112

1213
type SelectedCollectionView struct {
1314
layout components.Layout
1415
endpointsManager *endpoints.EndpointsManager
16+
httpManager *http.HTTPManager
1517
collection collections.CollectionEntity
1618
sidebar EndpointSidebarView
19+
selectedEndpoint *endpoints.EndpointEntity
1720
width int
1821
height int
1922
}
2023

21-
func NewSelectedCollectionView(endpointsManager *endpoints.EndpointsManager, collection collections.CollectionEntity) SelectedCollectionView {
24+
func NewSelectedCollectionView(endpointsManager *endpoints.EndpointsManager, httpManager *http.HTTPManager, collection collections.CollectionEntity) SelectedCollectionView {
25+
sidebar := NewEndpointSidebarView(endpointsManager, collection)
26+
sidebar.Focus() // Make sure sidebar starts focused
27+
2228
return SelectedCollectionView{
2329
layout: components.NewLayout(),
2430
endpointsManager: endpointsManager,
31+
httpManager: httpManager,
2532
collection: collection,
26-
sidebar: NewEndpointSidebarView(endpointsManager, collection),
33+
sidebar: sidebar,
34+
selectedEndpoint: nil,
2735
}
2836
}
2937

30-
func NewSelectedCollectionViewWithSize(endpointsManager *endpoints.EndpointsManager, collection collections.CollectionEntity, width, height int) SelectedCollectionView {
38+
func NewSelectedCollectionViewWithSize(endpointsManager *endpoints.EndpointsManager, httpManager *http.HTTPManager, collection collections.CollectionEntity, width, height int) SelectedCollectionView {
3139
layout := components.NewLayout()
3240
layout.SetSize(width, height)
3341

@@ -40,12 +48,15 @@ func NewSelectedCollectionViewWithSize(endpointsManager *endpoints.EndpointsMana
4048
sidebar := NewEndpointSidebarView(endpointsManager, collection)
4149
sidebar.width = sidebarWidth
4250
sidebar.height = innerHeight
51+
sidebar.Focus() // Make sure sidebar starts focused
4352

4453
return SelectedCollectionView{
4554
layout: layout,
4655
endpointsManager: endpointsManager,
56+
httpManager: httpManager,
4757
collection: collection,
4858
sidebar: sidebar,
59+
selectedEndpoint: nil,
4960
width: width,
5061
height: height,
5162
}
@@ -78,18 +89,62 @@ func (v SelectedCollectionView) Update(msg tea.Msg) (SelectedCollectionView, tea
7889
case "esc", "q":
7990
return v, func() tea.Msg { return BackToCollectionsMsg{} }
8091
}
92+
93+
case EndpointSelectedMsg:
94+
// Store the selected endpoint for display
95+
v.selectedEndpoint = &msg.Endpoint
8196
}
8297

98+
// Always forward messages to sidebar for now, but it only handles them when focused
8399
v.sidebar, cmd = v.sidebar.Update(msg)
84100

85101
return v, cmd
86102
}
87103

104+
88105
func (v SelectedCollectionView) View() string {
89106
title := "Collection: " + v.collection.Name
107+
if v.selectedEndpoint != nil {
108+
title += " > " + v.selectedEndpoint.Name
109+
}
90110

91111
sidebarContent := v.sidebar.View()
92-
mainContent := "Endpoint details will be displayed here"
112+
113+
// Simple endpoint information display
114+
var mainContent string
115+
if v.selectedEndpoint != nil {
116+
var lines []string
117+
lines = append(lines, "Selected Endpoint:")
118+
lines = append(lines, "")
119+
lines = append(lines, "Name: "+v.selectedEndpoint.Name)
120+
lines = append(lines, "Method: "+v.selectedEndpoint.Method)
121+
lines = append(lines, "URL: "+v.selectedEndpoint.Url)
122+
123+
if v.selectedEndpoint.Headers != "" {
124+
lines = append(lines, "")
125+
lines = append(lines, "Headers: "+v.selectedEndpoint.Headers)
126+
}
127+
128+
if v.selectedEndpoint.QueryParams != "" {
129+
lines = append(lines, "")
130+
lines = append(lines, "Query Params: "+v.selectedEndpoint.QueryParams)
131+
}
132+
133+
if v.selectedEndpoint.RequestBody != "" {
134+
lines = append(lines, "")
135+
lines = append(lines, "Request Body:")
136+
lines = append(lines, v.selectedEndpoint.RequestBody)
137+
}
138+
139+
mainContent = lipgloss.JoinVertical(lipgloss.Left, lines...)
140+
} else {
141+
// Check if there are no endpoints at all
142+
if len(v.sidebar.endpoints) == 0 {
143+
mainContent = "Create an endpoint to get started"
144+
} else {
145+
mainContent = "Select an endpoint from the sidebar to view details"
146+
}
147+
}
93148

94149
if v.width < 10 || v.height < 10 {
95150
return v.layout.FullView(title, sidebarContent, "esc/q: back to collections")
@@ -103,26 +158,32 @@ func (v SelectedCollectionView) View() string {
103158
sidebarWidth := innerWidth / 4
104159
mainWidth := innerWidth - sidebarWidth - 1
105160

161+
// Sidebar styling
106162
sidebarStyle := styles.SidebarStyle.Copy().
107163
Width(sidebarWidth).
108-
Height(innerHeight)
164+
Height(innerHeight).
165+
BorderForeground(styles.Primary)
109166

110167
mainStyle := styles.MainContentStyle.Copy().
111168
Width(mainWidth).
112-
Height(innerHeight).
113-
Align(lipgloss.Center, lipgloss.Center)
169+
Height(innerHeight)
114170

115171
content := lipgloss.JoinHorizontal(
116172
lipgloss.Top,
117173
sidebarStyle.Render(sidebarContent),
118174
mainStyle.Render(mainContent),
119175
)
120176

121-
instructions := "↑↓: navigate endpoints • esc/q: back to collections"
177+
instructions := "↑↓: navigate endpoints • esc/q: back"
122178

123179
return v.layout.FullView(
124180
title,
125181
content,
126182
instructions,
127183
)
128184
}
185+
186+
// Message types for selected collection view
187+
type EndpointSelectedMsg struct {
188+
Endpoint endpoints.EndpointEntity
189+
}

0 commit comments

Comments
 (0)