diff --git a/maker/widget_maker.go b/maker/widget_maker.go index 521559a1..4e460d2e 100644 --- a/maker/widget_maker.go +++ b/maker/widget_maker.go @@ -90,7 +90,7 @@ func MakeWidget( widget = cryptolive.NewWidget(app, settings) case "datadog": settings := datadog.NewSettingsFromYAML(widgetName, moduleConfig, globalConfig) - widget = datadog.NewWidget(app, settings) + widget = datadog.NewWidget(app, pages, settings) case "gcal": settings := gcal.NewSettingsFromYAML(widgetName, moduleConfig, globalConfig) widget = gcal.NewWidget(app, settings) diff --git a/modules/datadog/keyboard.go b/modules/datadog/keyboard.go new file mode 100644 index 00000000..af9b18e5 --- /dev/null +++ b/modules/datadog/keyboard.go @@ -0,0 +1,17 @@ +package datadog + +import ( + "github.com/gdamore/tcell" +) + +func (widget *Widget) initializeKeyboardControls() { + widget.SetKeyboardChar("/", widget.ShowHelp) + widget.SetKeyboardChar("j", widget.next) + widget.SetKeyboardChar("k", widget.prev) + widget.SetKeyboardChar("o", widget.openItem) + + widget.SetKeyboardKey(tcell.KeyDown, widget.next) + widget.SetKeyboardKey(tcell.KeyEnter, widget.openItem) + widget.SetKeyboardKey(tcell.KeyEsc, widget.unselect) + widget.SetKeyboardKey(tcell.KeyUp, widget.prev) +} diff --git a/modules/datadog/widget.go b/modules/datadog/widget.go index c8a9665c..c15592be 100644 --- a/modules/datadog/widget.go +++ b/modules/datadog/widget.go @@ -2,27 +2,56 @@ package datadog import ( "fmt" + "strconv" "github.com/rivo/tview" "github.com/wtfutil/wtf/wtf" datadog "github.com/zorkian/go-datadog-api" ) +const HelpText = ` + Keyboard commands for Datadog: + + /: Show/hide this help window + j: Select the next item in the list + k: Select the previous item in the list + + arrow down: Select the next item in the list + arrow up: Select the previous item in the list + + return: Open the selected issue in a browser +` + type Widget struct { + wtf.HelpfulWidget wtf.TextWidget + wtf.KeyboardWidget app *tview.Application + selected int + monitors []datadog.Monitor settings *Settings } -func NewWidget(app *tview.Application, settings *Settings) *Widget { +func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { widget := Widget{ - TextWidget: wtf.NewTextWidget(app, settings.common, false), + HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), + KeyboardWidget: wtf.NewKeyboardWidget(), + TextWidget: wtf.NewTextWidget(app, settings.common, true), app: app, settings: settings, } + widget.initializeKeyboardControls() + widget.View.SetInputCapture(widget.InputCapture) + + widget.unselect() + + widget.View.SetScrollable(true) + widget.View.SetRegions(true) + widget.HelpfulWidget.SetView(widget.View) + return &widget } @@ -35,22 +64,12 @@ func (widget *Widget) Refresh() { if monitorErr != nil { widget.View.SetWrap(true) content = monitorErr.Error() - } else { - widget.View.SetWrap(false) - content = widget.contentFrom(monitors) + widget.app.QueueUpdateDraw(func() { + widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) + widget.View.SetText(content) + }) + return } - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) - widget.View.Clear() - widget.View.SetText(content) - }) -} - -/* -------------------- Unexported Functions -------------------- */ - -func (widget *Widget) contentFrom(monitors []datadog.Monitor) string { - var str string - triggeredMonitors := []datadog.Monitor{} for _, monitor := range monitors { @@ -60,13 +79,39 @@ func (widget *Widget) contentFrom(monitors []datadog.Monitor) string { triggeredMonitors = append(triggeredMonitors, monitor) } } + widget.monitors = triggeredMonitors + + widget.display() +} + +func (widget *Widget) display() { + content := widget.contentFrom(widget.monitors) + widget.app.QueueUpdateDraw(func() { + widget.View.SetWrap(false) + widget.View.Clear() + widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) + widget.View.SetText(content) + widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() + }) +} + +/* -------------------- Unexported Functions -------------------- */ + +func (widget *Widget) contentFrom(triggeredMonitors []datadog.Monitor) string { + var str string + if len(triggeredMonitors) > 0 { str = str + fmt.Sprintf( " %s\n", "[red]Triggered Monitors[white]", ) - for _, triggeredMonitor := range triggeredMonitors { - str = str + fmt.Sprintf("[red] %s\n", *triggeredMonitor.Name) + for idx, triggeredMonitor := range triggeredMonitors { + str = str + fmt.Sprintf(`["%d"][%s][red] %s[%s][""]`, + idx, + widget.rowColor(idx), + *triggeredMonitor.Name, + widget.rowColor(idx), + ) + "\n" } } else { str = str + fmt.Sprintf( @@ -77,3 +122,41 @@ func (widget *Widget) contentFrom(monitors []datadog.Monitor) string { return str } + +func (widget *Widget) unselect() { + widget.selected = -1 + widget.display() +} + +func (widget *Widget) next() { + widget.selected++ + if widget.monitors != nil && widget.selected >= len(widget.monitors) { + widget.selected = 0 + } + widget.display() +} + +func (widget *Widget) prev() { + widget.selected-- + if widget.selected < 0 && widget.monitors != nil { + widget.selected = len(widget.monitors) - 1 + } + widget.display() +} + +func (widget *Widget) openItem() { + + sel := widget.selected + if sel >= 0 && widget.monitors != nil && sel < len(widget.monitors) { + item := &widget.monitors[widget.selected] + wtf.OpenFile(fmt.Sprintf("https://app.datadoghq.com/monitors/%d?q=*", *item.Id)) + } +} + +func (widget *Widget) rowColor(idx int) string { + if widget.View.HasFocus() && (idx == widget.selected) { + widget.settings.common.DefaultFocussedRowColor() + } + + return widget.settings.common.RowColor(idx) +}