Skip to content

Commit a54697f

Browse files
authored
Merge pull request #157 from ilmanzo/enable_pagination
Add pagination on TUI
2 parents 3468b60 + 32e5244 commit a54697f

File tree

7 files changed

+84
-43
lines changed

7 files changed

+84
-43
lines changed

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,7 @@ uninstall:
3434

3535
test:
3636
go test ./...
37+
38+
clean:
39+
go clean
40+
rm openqa-mon openqa-mq openqa-revtui

cmd/openqa-mon/openqa-mon.go

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
"unicode"
1616

1717
"github.com/grisu48/gopenqa"
18-
"github.com/grisu48/openqa-mon/internal"
18+
"github.com/os-autoinst/openqa-mon/internal"
1919
)
2020

2121
var config Config
@@ -735,6 +735,7 @@ func main() {
735735
if len(remotes) == 1 {
736736
remotesString = remotes[0].URI
737737
}
738+
tui.remotes=remotesString
738739
tui.SetHeader(fmt.Sprintf("openqa-mon v%s - Monitoring %s", internal.VERSION, remotesString))
739740
tui.Model.HideStates = config.HideStates
740741
tui.Update()
@@ -861,6 +862,7 @@ func singleCall(remotes []Remote) {
861862
}
862863
}
863864

865+
864866
func continuousMonitoring(remotes []Remote) {
865867
var err error
866868
// Ensure cursor is visible after termination
@@ -880,47 +882,50 @@ func continuousMonitoring(remotes []Remote) {
880882

881883
// Keybress callback
882884
tui.Keypress = func(b byte) {
883-
if b == 'q' {
885+
switch b {
886+
case 'q':
884887
tui.LeaveAltScreen()
885888
os.Exit(0)
886-
} else if b == 'r' {
889+
case 'r':
887890
// Refresh
888891
refreshSignal <- 1
889892
return
890-
} else if b == '?' {
893+
case '?':
891894
tui.SetShowHelp(!tui.DoShowHelp())
892-
} else if b == 'h' {
895+
case 'h':
893896
tui.SetHideStates(!tui.DoHideStates())
894-
} else if b == 'p' {
897+
case 'p':
895898
config.Paused = !config.Paused
896899
if config.Paused {
897900
SetStatus()
898901
} else {
899902
refreshSignal <- 1
900903
}
901904
return
902-
} else if b == 'd' || b == 'n' {
905+
case 'd','n':
903906
config.Notify = !config.Notify
904907
SetStatus()
905-
} else if b == 'b' {
908+
case 'b':
906909
config.Bell = !config.Bell
907910
SetStatus()
908-
} else if b == 'm' {
911+
case 'm':
909912
config.Notify = false
910913
config.Bell = false
911914
SetStatus()
912-
} else if b == 'l' {
915+
case 'l':
913916
config.Notify = true
914917
config.Bell = true
915918
SetStatus()
916-
} else if b == '+' {
919+
case '+':
917920
config.Continuous++
918921
SetStatus()
919-
} else if b == '-' {
922+
case '-':
920923
if config.Continuous > 1 {
921924
config.Continuous--
922925
}
923926
SetStatus()
927+
case '>': tui.NextPage()
928+
case '<': tui.PrevPage()
924929
}
925930
tui.Update()
926931
}

cmd/openqa-mon/tui.go

Lines changed: 55 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"unsafe"
1313

1414
"github.com/grisu48/gopenqa"
15+
"github.com/os-autoinst/openqa-mon/internal"
1516
"golang.org/x/crypto/ssh/terminal"
1617
)
1718

@@ -38,11 +39,14 @@ type TUI struct {
3839

3940
Keypress KeyPressCallback
4041

41-
header string
42-
status string // Additional status text
43-
showStatus bool // Show status line
44-
showHelp bool // Show help line
45-
hideEnable bool // If hideStates will be considered
42+
header string // program version, remote servers and current/total page
43+
status string // Additional status text
44+
remotes string // address of the openQA server or number of monitored instances
45+
showStatus bool // Show status line
46+
showHelp bool // Show help line
47+
hideEnable bool // If hideStates will be considered
48+
currentPage int // the page we are displaying (0=first)
49+
totalPages int // how many pages are there to display
4650
}
4751

4852
/* The model that will be displayed in the TUI */
@@ -97,6 +101,8 @@ func CreateTUI() TUI {
97101
tui.status = ""
98102
tui.showStatus = true
99103
tui.hideEnable = true
104+
tui.currentPage = 0
105+
tui.totalPages = 1
100106
return tui
101107
}
102108

@@ -263,6 +269,24 @@ func (tui *TUI) SetHideStates(enabled bool) {
263269
tui.Update()
264270
}
265271

272+
func (tui *TUI) NextPage() {
273+
tui.Model.mutex.Lock()
274+
defer tui.Model.mutex.Unlock()
275+
if tui.currentPage < tui.totalPages-1 {
276+
tui.currentPage++
277+
tui.header = fmt.Sprintf("openqa-mon v%s - Monitoring %s - Page %d/%d", internal.VERSION, tui.remotes, 1+tui.currentPage, tui.totalPages)
278+
}
279+
}
280+
281+
func (tui *TUI) PrevPage() {
282+
tui.Model.mutex.Lock()
283+
defer tui.Model.mutex.Unlock()
284+
if tui.currentPage > 0 {
285+
tui.currentPage--
286+
tui.header = fmt.Sprintf("openqa-mon v%s - Monitoring %s - Page %d/%d", internal.VERSION, tui.remotes, 1+tui.currentPage, tui.totalPages)
287+
}
288+
}
289+
266290
func (tui *TUI) DoHideStates() bool {
267291
return tui.hideEnable
268292
}
@@ -295,6 +319,10 @@ func (tui *TUI) doHideJob(j gopenqa.Job) bool {
295319

296320
// Redraw tui
297321
func (tui *TUI) Update() {
322+
if len(tui.Model.jobs) == 0 {
323+
// no jobs fetched yet, nothing to display
324+
return
325+
}
298326
width, height := terminalSize()
299327

300328
tui.Clear()
@@ -304,48 +332,48 @@ func (tui *TUI) Update() {
304332
lines++
305333
}
306334
if tui.showHelp {
307-
help := "?:Toggle help r: Refresh d:Toggle notifications b:Toggle bell +/-:Modify refresh time p:Toggle pause"
335+
help := "?:Toggle help r:Refresh d:Toggle notifications b:Toggle bell +/-:Modify refresh time p:Toggle pause <>:Page"
308336
if len(tui.Model.HideStates) > 0 {
309-
help += " h:Toggle hide"
337+
help += " h:Toggle hide"
310338
}
311-
help += " q:Quit"
339+
help += " q:Quit"
312340
PrintLine(help, width)
313341
lines++
314342
}
315-
fmt.Println()
316-
lines++
317-
318-
offset := 0
319-
maxHeight := height
343+
pageHeight := height - 1
320344
if tui.showStatus {
321-
maxHeight -= 2
345+
pageHeight--
346+
}
347+
// ensure to always have something to display without exceeding the slice limits
348+
startIdx := min(tui.currentPage*pageHeight, len(tui.Model.jobs))
349+
endIdx := min(startIdx+pageHeight, len(tui.Model.jobs))
350+
tui.totalPages = len(tui.Model.jobs) / pageHeight
351+
if len(tui.Model.jobs)%pageHeight > 0 {
352+
tui.totalPages++ // one more page for any partial-page leftover
322353
}
323-
for _, job := range tui.Model.jobs {
354+
for _, job := range tui.Model.jobs[startIdx:endIdx] {
324355
if tui.hideEnable && tui.doHideJob(job) {
325356
continue
326357
}
327-
// Ignore offset jobs (for scrolling)
328-
if offset > 0 {
329-
offset--
330-
continue
331-
}
332358
PrintJob(job, true, width)
333359
lines++
334-
if lines >= maxHeight {
335-
return
336-
}
360+
}
361+
362+
// print some empty lines if needed to fill last page and make footer always on last line
363+
for lines <= pageHeight {
364+
fmt.Println()
365+
lines++
337366
}
338367

339368
// Status line
340369
if tui.showStatus {
341370
// Add footer, if possible
342371
status := tui.status
343-
footer := "openqa-mon (https://github.com/grisu48/openqa-mon)"
372+
footer := "openqa-mon (https://github.com/os-autoinst/openqa-mon)"
344373
if width >= len(status)+len(footer)+5 {
345-
spaces := strings.Repeat(" ", width-len(status)-len(footer))
374+
spaces := strings.Repeat(" ", width-len(status)-len(footer)-1)
346375
status += spaces + footer
347376
}
348-
fmt.Println("")
349-
fmt.Println(status)
377+
fmt.Print(status)
350378
}
351379
}

cmd/openqa-mq/openqa-mq.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"strings"
88
"syscall"
99

10-
"github.com/grisu48/openqa-mon/internal"
10+
"github.com/os-autoinst/openqa-mon/internal"
1111
amqp "github.com/rabbitmq/amqp091-go"
1212
)
1313

cmd/openqa-revtui/openqa-revtui.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"time"
99

1010
"github.com/grisu48/gopenqa"
11-
"github.com/grisu48/openqa-mon/internal"
11+
"github.com/os-autoinst/openqa-mon/internal"
1212
)
1313

1414
var knownJobs []gopenqa.Job

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
module github.com/grisu48/openqa-mon
1+
module github.com/os-autoinst/openqa-mon
22

3-
go 1.20
3+
go 1.21
44

55
require (
66
github.com/BurntSushi/toml v1.4.0

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
22
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
33
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
4+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
45
github.com/grisu48/gopenqa v0.7.4 h1:E2IXKid1SJ2ndtzs3KNmYhFGcl8IX8eh2A2pYWD1CgU=
56
github.com/grisu48/gopenqa v0.7.4/go.mod h1:+gXgBF7HsC/JjqQM5iSTEy9Ws9OlvJivALVYJRtXH+8=
67
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
8+
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
79
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
810
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
911
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
12+
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
1013
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
1114
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
1215
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
1316
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
1417
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
1518
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
1619
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
20+
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=

0 commit comments

Comments
 (0)