diff --git a/tuiexporter/internal/tui/component/page.go b/tuiexporter/internal/tui/component/page.go index a4bebec..14dd304 100644 --- a/tuiexporter/internal/tui/component/page.go +++ b/tuiexporter/internal/tui/component/page.go @@ -2,6 +2,7 @@ package component import ( "log" + "regexp" "strings" "github.com/gdamore/tcell/v2" @@ -17,6 +18,8 @@ const ( PAGE_DEBUG_LOG = "DebugLog" ) +var keyMapRegex = regexp.MustCompile(`Rune|\[|\]`) + type KeyMaps map[tcell.EventKey]string type TUIPages struct { @@ -179,7 +182,7 @@ func (p *TUIPages) createTracePage(store *telemetry.Store) *tview.Flex { *tcell.NewEventKey(tcell.KeyRune, '/', tcell.ModNone): "Search traces", *tcell.NewEventKey(tcell.KeyEsc, ' ', tcell.ModNone): "(search) Cancel", *tcell.NewEventKey(tcell.KeyEnter, ' ', tcell.ModNone): "(search) Confirm", - *tcell.NewEventKey(tcell.KeyCtrlL, ' ', tcell.ModNone): "Clear all data", + *tcell.NewEventKey(tcell.KeyRune, 'L', tcell.ModCtrl): "Clear all data", }) page = attatchTab(page, PAGE_TRACES) @@ -343,7 +346,7 @@ func (p *TUIPages) createLogPage(store *telemetry.Store) *tview.Flex { *tcell.NewEventKey(tcell.KeyRune, '/', tcell.ModNone): "Search logs", *tcell.NewEventKey(tcell.KeyEsc, ' ', tcell.ModNone): "(search) Cancel", *tcell.NewEventKey(tcell.KeyEnter, ' ', tcell.ModNone): "(search) Confirm", - *tcell.NewEventKey(tcell.KeyCtrlL, ' ', tcell.ModNone): "Clear all data", + *tcell.NewEventKey(tcell.KeyRune, 'L', tcell.ModCtrl): "Clear all data", *tcell.NewEventKey(tcell.KeyRune, 'y', tcell.ModNone): "Copy Log to clipboard", }) pageContainer = attatchTab(pageContainer, PAGE_LOGS) @@ -389,7 +392,7 @@ func attatchTab(p tview.Primitive, name string) *tview.Flex { func attatchCommandList(p tview.Primitive, keys KeyMaps) *tview.Flex { keytexts := []string{} for k, v := range keys { - keytexts = append(keytexts, k.Name()+": "+v) + keytexts = append(keytexts, keyMapRegex.ReplaceAllString(k.Name(), "")+": "+v) } command := tview.NewTextView().SetText(strings.Join(keytexts, ", ")) diff --git a/tuiexporter/internal/tui/component/timeline.go b/tuiexporter/internal/tui/component/timeline.go index ddf5661..9d37f96 100644 --- a/tuiexporter/internal/tui/component/timeline.go +++ b/tuiexporter/internal/tui/component/timeline.go @@ -12,8 +12,10 @@ import ( ) const ( - TIMELINE_DETAILS_IDX = 1 // index of details in the base flex container - TIMELINE_TREE_TITLE = "Details (d)" + TIMELINE_DETAILS_IDX = 1 // index of details in the base flex container + TIMELINE_TREE_TITLE = "Details (d)" + SPAN_NAME_COLUMN_WIDTH_RESIZE_UNIT = 5 + SPAN_NAME_COLUMN_WIDTH_DEFAULT = 30 ) var colors = []tcell.Color{ @@ -77,8 +79,9 @@ func DrawTimeline(traceID string, tcache *telemetry.TraceCache, lcache *telemetr }) // place spans on the timeline + snameWidth := SPAN_NAME_COLUMN_WIDTH_DEFAULT grid := tview.NewGrid(). - SetColumns(30, 0). // TODO: dynamic width + SetColumns(snameWidth, 0). // TODO: dynamic width SetBorders(true). AddItem(title, 0, 0, 1, 1, 0, 0, false). AddItem(timeline, 0, 1, 1, 1, 0, 0, false) @@ -139,6 +142,15 @@ func DrawTimeline(traceID string, tcache *telemetry.TraceCache, lcache *telemetr traceContainer.AddItem(details, 0, 3, false) } return nil + case tcell.KeyCtrlL: + _, _, w, _ := grid.GetInnerRect() + snameWidth = widenInLimit(SPAN_NAME_COLUMN_WIDTH_RESIZE_UNIT, snameWidth, w) + grid.SetColumns(snameWidth, 0) + return nil + case tcell.KeyCtrlH: + snameWidth = narrowInLimit(SPAN_NAME_COLUMN_WIDTH_RESIZE_UNIT, snameWidth, SPAN_NAME_COLUMN_WIDTH_DEFAULT) + grid.SetColumns(snameWidth, 0) + return nil } return event }) @@ -179,7 +191,23 @@ func DrawTimeline(traceID string, tcache *telemetry.TraceCache, lcache *telemetr return base, KeyMaps{ *tcell.NewEventKey(tcell.KeyUp, ' ', tcell.ModNone): "Move up", *tcell.NewEventKey(tcell.KeyDown, ' ', tcell.ModNone): "Move down", + *tcell.NewEventKey(tcell.KeyRune, 'L', tcell.ModCtrl): "Widen side col", + *tcell.NewEventKey(tcell.KeyRune, 'H', tcell.ModCtrl): "Narrow side col", + } +} + +func narrowInLimit(step, curr, limit int) int { + if curr-step >= limit { + return curr - step + } + return curr +} + +func widenInLimit(step, curr, limit int) int { + if curr+step <= limit { + return curr + step } + return curr } func calculateTimelineUnit(duration time.Duration) (unit time.Duration, count int) { diff --git a/tuiexporter/internal/tui/component/timeline_test.go b/tuiexporter/internal/tui/component/timeline_test.go index cbb2d69..be9c54e 100644 --- a/tuiexporter/internal/tui/component/timeline_test.go +++ b/tuiexporter/internal/tui/component/timeline_test.go @@ -103,3 +103,67 @@ func TestRoundDownDuration(t *testing.T) { }) } } + +func TestNarrowInLimit(t *testing.T) { + tests := []struct { + name string + step int + curr int + limit int + want int + }{ + { + name: "Modified", + step: 5, + curr: 35, + limit: 30, + want: 30, + }, + { + name: "No_Effect_Limit_Over", + step: 5, + curr: 34, + limit: 30, + want: 34, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := narrowInLimit(tt.step, tt.curr, tt.limit) + assert.Equal(t, tt.want, got) + }) + } +} + +func TestWidenInLimit(t *testing.T) { + tests := []struct { + name string + step int + curr int + limit int + want int + }{ + { + name: "Modified", + step: 5, + curr: 35, + limit: 40, + want: 40, + }, + { + name: "No_Effect_Limit_Over", + step: 5, + curr: 30, + limit: 34, + want: 30, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := widenInLimit(tt.step, tt.curr, tt.limit) + assert.Equal(t, tt.want, got) + }) + } +}