@@ -44,25 +44,45 @@ func (m *DashboardModel) formatAttributesTable(attributes map[string]string, max
44
44
45
45
// Create table rows
46
46
rows := []table.Row {}
47
+ totalRows := 0
47
48
for _ , key := range keys {
48
49
value := attributes [key ]
49
- // Truncate long values to fit
50
- if len (value ) > valueWidth - 3 {
51
- value = value [:valueWidth - 3 ] + "..."
52
- }
53
- // Truncate long keys to fit
50
+
51
+ // Always truncate long keys to fit (keys are less important to see in full)
54
52
displayKey := key
55
53
if len (displayKey ) > keyWidth - 3 {
56
54
displayKey = displayKey [:keyWidth - 3 ] + "..."
57
55
}
58
- rows = append (rows , table.Row {displayKey , value })
56
+
57
+ // Handle value display based on wrapping setting
58
+ if m .attributeWrappingEnabled && len (value ) > valueWidth {
59
+ // Wrap long values across multiple rows
60
+ wrappedLines := wrapText (value , valueWidth )
61
+ for i , line := range wrappedLines {
62
+ if i == 0 {
63
+ // First line shows the key
64
+ rows = append (rows , table.Row {displayKey , line })
65
+ } else {
66
+ // Subsequent lines have empty key column
67
+ rows = append (rows , table.Row {"" , line })
68
+ }
69
+ totalRows ++
70
+ }
71
+ } else {
72
+ // Truncate long values to fit (default behavior)
73
+ if len (value ) > valueWidth - 3 {
74
+ value = value [:valueWidth - 3 ] + "..."
75
+ }
76
+ rows = append (rows , table.Row {displayKey , value })
77
+ totalRows ++
78
+ }
59
79
}
60
80
61
81
// Create and configure table
62
82
t := table .New (
63
83
table .WithColumns (columns ),
64
84
table .WithRows (rows ),
65
- table .WithHeight (len ( rows ) + 2 ), // +2 for header and padding
85
+ table .WithHeight (totalRows + 2 ), // +2 for header and padding
66
86
table .WithWidth (maxWidth ),
67
87
table .WithFocused (false ), // Disable focus to prevent selection
68
88
)
@@ -155,6 +175,43 @@ func (m *DashboardModel) formatLogDetails(entry LogEntry, maxWidth int) string {
155
175
return details .String ()
156
176
}
157
177
178
+ // wrapText wraps text to fit within the specified width
179
+ func wrapText (text string , width int ) []string {
180
+ if len (text ) <= width {
181
+ return []string {text }
182
+ }
183
+
184
+ var lines []string
185
+ for len (text ) > width {
186
+ // Find the best break point (prefer spaces)
187
+ breakPoint := width
188
+
189
+ // Look for a space near the end to break on word boundary
190
+ for i := width - 1 ; i > width / 2 && i < len (text ); i -- {
191
+ if text [i ] == ' ' {
192
+ breakPoint = i
193
+ break
194
+ }
195
+ }
196
+
197
+ // Add the line (excluding the space if we broke on one)
198
+ if breakPoint < len (text ) && text [breakPoint ] == ' ' {
199
+ lines = append (lines , text [:breakPoint ])
200
+ text = text [breakPoint + 1 :] // Skip the space
201
+ } else {
202
+ lines = append (lines , text [:breakPoint ])
203
+ text = text [breakPoint :]
204
+ }
205
+ }
206
+
207
+ // Add the remaining text
208
+ if len (text ) > 0 {
209
+ lines = append (lines , text )
210
+ }
211
+
212
+ return lines
213
+ }
214
+
158
215
// formatAttributeValuesModal formats the attribute values modal showing individual values and their counts with full width layout
159
216
func (m * DashboardModel ) formatAttributeValuesModal (entry * memory.AttributeStatsEntry , maxWidth int ) string {
160
217
var modal strings.Builder
0 commit comments