1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00

Initial commit of gitlab todo module (#830)

This commit is contained in:
Elliot 2020-02-15 12:33:23 -08:00 committed by GitHub
parent e05c21e86f
commit 6c1828234a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 196 additions and 0 deletions

View File

@ -26,6 +26,7 @@ import (
"github.com/wtfutil/wtf/modules/git"
"github.com/wtfutil/wtf/modules/github"
"github.com/wtfutil/wtf/modules/gitlab"
"github.com/wtfutil/wtf/modules/gitlabtodo"
"github.com/wtfutil/wtf/modules/gitter"
"github.com/wtfutil/wtf/modules/googleanalytics"
"github.com/wtfutil/wtf/modules/gspreadsheets"
@ -162,6 +163,9 @@ func MakeWidget(
case "gitlab":
settings := gitlab.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = gitlab.NewWidget(app, pages, settings)
case "gitlabtodo":
settings := gitlabtodo.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = gitlabtodo.NewWidget(app, pages, settings)
case "gitter":
settings := gitter.NewSettingsFromYAML(moduleName, moduleConfig, config)
widget = gitter.NewWidget(app, pages, settings)

View File

@ -0,0 +1,17 @@
package gitlabtodo
import "github.com/gdamore/tcell"
func (widget *Widget) initializeKeyboardControls() {
widget.SetKeyboardChar("/", widget.ShowHelp, "Show/hide this help widget")
widget.SetKeyboardChar("r", widget.Refresh, "Refresh widget")
widget.SetKeyboardChar("j", widget.Next, "Select next item")
widget.SetKeyboardChar("k", widget.Prev, "Select previous item")
widget.SetKeyboardChar("o", widget.openTodo, "Open todo in browser")
widget.SetKeyboardChar("x", widget.markAsDone, "Mark todo as done")
widget.SetKeyboardKey(tcell.KeyDown, widget.Next, "Select next item")
widget.SetKeyboardKey(tcell.KeyUp, widget.Prev, "Select previous item")
widget.SetKeyboardKey(tcell.KeyEnter, widget.openTodo, "Open todo in browser")
widget.SetKeyboardKey(tcell.KeyEsc, widget.Unselect, "Clear selection")
}

View File

@ -0,0 +1,36 @@
package gitlabtodo
import (
"os"
"github.com/olebedev/config"
"github.com/wtfutil/wtf/cfg"
)
const (
defaultFocusable = true
defaultTitle = "GitLab Todos"
)
type Settings struct {
common *cfg.Common
numberOfTodos int `help:"Defines number of stories to be displayed. Default is 10" optional:"true"`
apiKey string `help:"A GitLab personal access token. Requires at least api access."`
domain string `help:"Your GitLab corporate domain."`
showProject bool `help:"Determines whether or not to show the project a given todo is for."`
}
func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings {
settings := Settings{
common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig),
numberOfTodos: ymlConfig.UInt("numberOfTodos", 10),
apiKey: ymlConfig.UString("apiKey", os.Getenv("WTF_GITLAB_TOKEN")),
domain: ymlConfig.UString("domain"),
showProject: ymlConfig.UBool("showProject", true),
}
return &settings
}

View File

@ -0,0 +1,139 @@
package gitlabtodo
import (
"fmt"
"github.com/rivo/tview"
"github.com/wtfutil/wtf/utils"
"github.com/wtfutil/wtf/view"
gitlab "github.com/xanzy/go-gitlab"
)
type Widget struct {
view.KeyboardWidget
view.ScrollableWidget
todos []*gitlab.Todo
gitlabClient *gitlab.Client
settings *Settings
err error
}
func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
widget := &Widget{
KeyboardWidget: view.NewKeyboardWidget(app, pages, settings.common),
ScrollableWidget: view.NewScrollableWidget(app, settings.common),
settings: settings,
}
widget.gitlabClient = gitlab.NewClient(nil, settings.apiKey)
widget.SetRenderFunction(widget.Render)
widget.initializeKeyboardControls()
widget.View.SetInputCapture(widget.InputCapture)
widget.KeyboardWidget.SetView(widget.View)
return widget
}
/* -------------------- Exported Functions -------------------- */
func (widget *Widget) Refresh() {
if widget.Disabled() {
return
}
todos, _ := widget.getTodos(widget.settings.apiKey)
widget.todos = todos
widget.SetItemCount(len(todos))
widget.Render()
}
// Render sets up the widget data for redrawing to the screen
func (widget *Widget) Render() {
widget.Redraw(widget.content)
}
/* -------------------- Unexported Functions -------------------- */
func (widget *Widget) content() (string, string, bool) {
title := fmt.Sprintf("GitLab ToDos (%d)", len(widget.todos))
if widget.err != nil {
return title, widget.err.Error(), true
}
if widget.todos == nil {
return title, "No ToDos to display", false
}
str := widget.contentFrom(widget.todos)
return title, str, false
}
func (widget *Widget) getTodos(apiKey string) ([]*gitlab.Todo, error) {
opts := gitlab.ListTodosOptions{}
todos, _, err := widget.gitlabClient.Todos.ListTodos(&opts)
if err != nil {
return nil, err
}
return todos, nil
}
// trim the todo body so it fits on a single line
func (widget *Widget) trimTodoBody(body string) string {
r := []rune(body)
// Cut at first occurance of a newline
for i, a := range r {
if a == '\n' {
return string(r[:i])
}
}
return body
}
func (widget *Widget) contentFrom(todos []*gitlab.Todo) string {
var str string
for idx, todo := range todos {
row := fmt.Sprintf(`[%s]%2d. `, widget.RowColor(idx), idx+1)
if widget.settings.showProject {
row = fmt.Sprintf(`%s%s `, row, todo.Project.Path)
}
row = fmt.Sprintf(`%s[mediumpurple](%s)[%s] %s`,
row,
todo.Author.Username,
widget.RowColor(idx),
widget.trimTodoBody(todo.Body),
)
str += utils.HighlightableHelper(widget.View, row, idx, len(todo.Body))
}
return str
}
func (widget *Widget) markAsDone() {
sel := widget.GetSelected()
if sel >= 0 && widget.todos != nil && sel < len(widget.todos) {
todo := widget.todos[sel]
widget.gitlabClient.Todos.MarkTodoAsDone(todo.ID)
widget.Refresh()
}
}
func (widget *Widget) openTodo() {
sel := widget.GetSelected()
if sel >= 0 && widget.todos != nil && sel < len(widget.todos) {
todo := widget.todos[sel]
utils.OpenFile(todo.TargetURL)
}
}