Skip to content

Commit e11079e

Browse files
committed
feat: update container info handling to support Docker Compose labels, improve info panel rendering and navigation
1 parent ee0e6a2 commit e11079e

File tree

4 files changed

+105
-47
lines changed

4 files changed

+105
-47
lines changed

internal/docker/client.go

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -484,10 +484,10 @@ func FetchComposeProjects() (map[string]*ComposeProject, error) {
484484
}
485485
}
486486

487-
serviceName := e.Labels["io.podman.compose.service"]
488-
containerNumber := e.Labels["io.podman.compose.container-number"]
489-
configFile := e.Labels["io.podman.compose.project.config_files"]
490-
workingDir := e.Labels["io.podman.compose.project.working_dir"]
487+
serviceName := e.Labels["com.docker.compose.service"]
488+
// containerNumber := e.Labels["io.podman.compose.container-number"]
489+
configFile := e.Labels["com.docker.compose.project.config_files"]
490+
workingDir := e.Labels["com.docker.compose.project.working_dir"]
491491

492492
if projectName == "" {
493493
continue
@@ -515,7 +515,9 @@ func FetchComposeProjects() (map[string]*ComposeProject, error) {
515515
Ports: ports,
516516
ComposeProject: projectName,
517517
ComposeService: serviceName,
518-
ComposeNumber: containerNumber,
518+
// ComposeNumber: containerNumber,
519+
ComposeDirectory: workingDir,
520+
ComposeFileDirectory: (workingDir + "/" + configFile),
519521
}
520522

521523
if state == "running" {
@@ -592,15 +594,17 @@ func FetchComposeProjects() (map[string]*ComposeProject, error) {
592594
}
593595

594596
container := Container{
595-
ID: e.ID,
596-
Names: names,
597-
Image: e.Image,
598-
Status: e.Status,
599-
State: state,
600-
Ports: e.Ports,
601-
ComposeProject: projectName,
602-
ComposeService: serviceName,
603-
ComposeNumber: containerNumber,
597+
ID: e.ID,
598+
Names: names,
599+
Image: e.Image,
600+
Status: e.Status,
601+
State: state,
602+
Ports: e.Ports,
603+
ComposeProject: projectName,
604+
ComposeService: serviceName,
605+
ComposeNumber: containerNumber,
606+
ComposeDirectory: labels["com.docker.compose.project.working_dir"],
607+
ComposeFileDirectory: labels["com.docker.compose.project.config_files"],
604608
}
605609

606610
if state == "running" {

internal/tui/info-panel.go

Lines changed: 62 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package tui
33
import (
44
"fmt"
55
"strings"
6+
7+
"github.com/shubh-io/dockmate/internal/docker"
68
)
79

810
func (m model) renderInfoPanel(width int) string {
@@ -11,18 +13,49 @@ func (m model) renderInfoPanel(width int) string {
1113
b.WriteString(dividerStyle.Render(strings.Repeat("─", width)))
1214
b.WriteString("\n")
1315

16+
id := m.infoContainerID
17+
if id == "" && m.infoContainer != nil {
18+
id = m.infoContainer.ID
19+
}
20+
21+
var container *docker.Container
22+
23+
if id != "" {
24+
25+
for _, p := range m.projects {
26+
for i := range p.Containers {
27+
if p.Containers[i].ID == id {
28+
container = &p.Containers[i]
29+
break
30+
}
31+
}
32+
if container != nil {
33+
break
34+
}
35+
}
36+
if container == nil {
37+
for i := range m.containers {
38+
if m.containers[i].ID == id {
39+
container = &m.containers[i]
40+
break
41+
}
42+
}
43+
}
44+
}
45+
1446
containerName := ""
15-
if m.infoContainer != nil && len(m.infoContainer.Names) > 0 {
16-
containerName = m.infoContainer.Names[0]
47+
if container != nil && len(container.Names) > 0 {
48+
containerName = container.Names[0]
1749
}
50+
1851
infoTitle := fmt.Sprintf("Container Info: %s ", containerName)
1952
if visibleLen(infoTitle) < width {
2053
infoTitle += strings.Repeat(" ", width-visibleLen(infoTitle))
2154
}
2255
b.WriteString(titleStyle.Render(infoTitle))
2356
b.WriteString("\n")
2457

25-
if m.infoContainer == nil {
58+
if container == nil {
2659
noContainerMsg := " No container selected"
2760
if visibleLen(noContainerMsg) < width {
2861
noContainerMsg += strings.Repeat(" ", width-visibleLen(noContainerMsg))
@@ -32,56 +65,61 @@ func (m model) renderInfoPanel(width int) string {
3265
return b.String()
3366
}
3467

35-
c := m.infoContainer
36-
3768
// Display container information fields
3869
infoFields := []struct {
3970
label string
4071
value string
4172
}{
42-
{"Container ID", c.ID},
73+
{"Container ID", container.ID},
4374
{"Name", containerName},
44-
{"Image", c.Image},
45-
{"Status", c.Status},
46-
{"State", c.State},
47-
{"CPU Usage", c.CPU},
48-
{"Memory Usage", c.Memory},
49-
{"Network I/O", c.NetIO},
50-
{"Block I/O", c.BlockIO},
51-
{"Ports", c.Ports},
75+
{"Image", container.Image},
76+
{"Status", container.Status},
77+
{"State", container.State},
78+
{"CPU Usage", container.CPU},
79+
{"Memory Usage", container.Memory},
80+
{"Network I/O", container.NetIO},
81+
{"Block I/O", container.BlockIO},
82+
{"Ports", container.Ports},
83+
// {"Compose Project", container.ComposeProject},
84+
// {"Compose File Directory", container.ComposeFileDirectory},
85+
// {"Compose Directory", container.ComposeDirectory},
86+
// {"Compose Service", container.ComposeService},
5287
}
5388

5489
// Add compose-specific fields if available
55-
if c.ComposeProject != "" {
90+
if container.ComposeProject != "" {
5691
infoFields = append(infoFields, struct {
5792
label string
5893
value string
59-
}{"Compose Project", c.ComposeProject})
94+
}{"Compose Project", container.ComposeProject})
6095
}
61-
if c.ComposeDirectory != "" {
96+
if container.ComposeDirectory != "" {
6297
infoFields = append(infoFields, struct {
6398
label string
6499
value string
65-
}{"Compose Directory", c.ComposeDirectory})
100+
}{"Compose Directory", container.ComposeDirectory})
66101
}
67-
if c.ComposeFileDirectory != "" {
102+
if container.ComposeFileDirectory != "" {
68103
infoFields = append(infoFields, struct {
69104
label string
70105
value string
71-
}{"Compose File Directory", c.ComposeFileDirectory})
106+
}{"Compose File Directory", container.ComposeFileDirectory})
72107
}
73-
if c.ComposeService != "" {
108+
if container.ComposeService != "" {
74109
infoFields = append(infoFields, struct {
75110
label string
76111
value string
77-
}{"Compose Service", c.ComposeService})
112+
}{"Compose Service", container.ComposeService})
113+
}
114+
panelHeight := m.infoPanelHeight
115+
if container != nil && container.ComposeFileDirectory == "" {
116+
panelHeight -= 4
78117
}
79118

80-
maxInfoLines := m.infoPanelHeight - 2 // account for divider and title
119+
maxInfoLines := panelHeight - 2 // account for divider and title
81120
if maxInfoLines < 1 {
82121
maxInfoLines = 1
83122
}
84-
85123
// Render info fields with wrapping
86124
renderedLines := 0
87125
for _, field := range infoFields {

internal/tui/model.go

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ func InitialModel() model {
7575
infoVisible: false,
7676
infoPanelHeight: INFO_PANEL_HEIGHT,
7777
infoContainer: nil,
78+
infoContainerID: "",
7879
sortBy: sortByStatus,
7980
sortAsc: false, // descending
8081
columnMode: false,
@@ -178,7 +179,12 @@ func (m *model) calculateMaxContainers() int {
178179
availableHeight -= m.logPanelHeight
179180
}
180181
if m.infoVisible {
181-
availableHeight -= INFO_PANEL_HEIGHT
182+
// if compose file dir visible:
183+
if m.infoContainer != nil && m.infoContainer.ComposeFileDirectory != "" {
184+
availableHeight -= INFO_PANEL_HEIGHT
185+
} else {
186+
availableHeight -= (INFO_PANEL_HEIGHT - 4)
187+
}
182188
}
183189
maxContainers := availableHeight / CONTAINER_ROW_HEIGHT
184190
if maxContainers < 1 {
@@ -194,17 +200,25 @@ func (m *model) updatePagination() {
194200
m.maxContainersPerPage = 1
195201
}
196202

197-
if len(m.containers) == 0 {
203+
itemCount := len(m.containers)
204+
if m.composeViewMode {
205+
itemCount = len(m.flatList)
206+
}
207+
208+
if itemCount == 0 {
198209
m.cursor = 0
199210
m.page = 0
200211
return
201212
}
202213

203-
if m.cursor >= len(m.containers) {
204-
m.cursor = len(m.containers) - 1
214+
if m.cursor >= itemCount {
215+
m.cursor = itemCount - 1
216+
}
217+
if m.cursor < 0 {
218+
m.cursor = 0
205219
}
206220

207-
maxPage := (len(m.containers) - 1) / m.maxContainersPerPage
221+
maxPage := (itemCount - 1) / m.maxContainersPerPage
208222
if maxPage < 0 {
209223
maxPage = 0
210224
}
@@ -221,7 +235,7 @@ func (m *model) updatePagination() {
221235

222236
// keep persistent page indicator up-to-date
223237
if m.maxContainersPerPage > 0 {
224-
maxPage = (len(m.containers) - 1) / m.maxContainersPerPage
238+
maxPage = (itemCount - 1) / m.maxContainersPerPage
225239
if maxPage < 0 {
226240
maxPage = 0
227241
}
@@ -268,7 +282,6 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
268282
if m.cursor >= len(m.containers) {
269283
m.cursor = max(0, len(m.containers)-1)
270284
}
271-
272285
m.refreshInfoContainer()
273286

274287
m.updatePagination()
@@ -782,7 +795,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
782795
case key.Matches(msg, Keys.Down):
783796
if !m.columnMode {
784797
if m.composeViewMode {
785-
if len(m.flatList) > 0 {
798+
if m.cursor < len(m.flatList)-1 {
786799
m.moveCursorDownTree()
787800
}
788801
} else {
@@ -970,10 +983,12 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
970983
m.infoVisible = !m.infoVisible
971984
if m.infoVisible {
972985
m.infoContainer = selected
986+
m.infoContainerID = selected.ID
973987
m.currentMode = modeInfo
974-
m.statusMessage = "Showing container info"
988+
// m.statusMessage = "Showing container info"
975989
} else {
976990
m.infoContainer = nil
991+
m.infoContainerID = ""
977992
m.currentMode = modeNormal
978993
m.statusMessage = "Info panel closed"
979994
}

internal/tui/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type model struct {
2929
infoVisible bool // info panel visible?
3030
infoPanelHeight int // height of info panel
3131
infoContainer *docker.Container // container for info display
32+
infoContainerID string // info container ID
3233
sortBy sortColumn // which column to sort by
3334
sortAsc bool // sort direction
3435
columnMode bool // column nav mode (vs row nav)

0 commit comments

Comments
 (0)