feat: move a card between statuses #3
3 changed files with 61 additions and 61 deletions
|
@ -20,8 +20,8 @@ const (
|
||||||
addPage string = "add"
|
addPage string = "add"
|
||||||
)
|
)
|
||||||
|
|
||||||
// App does some magical stuff.
|
// UI does some magical stuff.
|
||||||
type App struct {
|
type UI struct {
|
||||||
*tview.Application
|
*tview.Application
|
||||||
|
|
||||||
columns []column
|
columns []column
|
||||||
|
@ -32,26 +32,26 @@ type App struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// shutdown shuts down the application.
|
// shutdown shuts down the application.
|
||||||
func (a *App) shutdown() {
|
func (u *UI) shutdown() {
|
||||||
a.closeBoard()
|
u.closeBoard()
|
||||||
a.Stop()
|
u.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// closeBoard closes the BoltDB database.
|
// closeBoard closes the BoltDB database.
|
||||||
func (a *App) closeBoard() {
|
func (u *UI) closeBoard() {
|
||||||
_ = a.board.Close()
|
_ = u.board.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// openBoard opens the kanban project.
|
// openBoard opens the kanban project.
|
||||||
func (a *App) openBoard(path string) error {
|
func (u *UI) openBoard(path string) error {
|
||||||
b, err := board.Open(path)
|
b, err := board.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to load board, %w", err)
|
return fmt.Errorf("unable to load board, %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
a.board = b
|
u.board = b
|
||||||
|
|
||||||
if err = a.refresh(); err != nil {
|
if err = u.refresh(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,29 +59,29 @@ func (a *App) openBoard(path string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// refresh refreshes the UI.
|
// refresh refreshes the UI.
|
||||||
func (a *App) refresh() error {
|
func (u *UI) refresh() error {
|
||||||
statusList, err := a.board.StatusList()
|
statusList, err := u.board.StatusList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to get the status list, %w", err)
|
return fmt.Errorf("unable to get the status list, %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
a.updateBoard(statusList)
|
u.updateBoard(statusList)
|
||||||
|
|
||||||
a.setColumnFocus()
|
u.setColumnFocus()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) updateBoard(statusList []board.Status) error {
|
func (u *UI) updateBoard(statusList []board.Status) error {
|
||||||
a.flex.Clear()
|
u.flex.Clear()
|
||||||
|
|
||||||
columns := make([]column, len(statusList))
|
columns := make([]column, len(statusList))
|
||||||
|
|
||||||
for i := range statusList {
|
for i := range statusList {
|
||||||
columns[i] = a.newColumn(statusList[i].ID, statusList[i].Name)
|
columns[i] = u.newColumn(statusList[i].ID, statusList[i].Name)
|
||||||
|
|
||||||
if len(statusList[i].CardIds) > 0 {
|
if len(statusList[i].CardIds) > 0 {
|
||||||
cards, err := a.board.CardList(statusList[i].CardIds)
|
cards, err := u.board.CardList(statusList[i].CardIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to get the card list. %w", err)
|
return fmt.Errorf("unable to get the card list. %w", err)
|
||||||
}
|
}
|
||||||
|
@ -91,49 +91,49 @@ func (a *App) updateBoard(statusList []board.Status) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a.flex.AddItem(columns[i].cards, 0, 1, false)
|
u.flex.AddItem(columns[i].cards, 0, 1, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
a.columns = columns
|
u.columns = columns
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) shiftColumnFocus(s shiftDirection) {
|
func (u *UI) shiftColumnFocus(s shiftDirection) {
|
||||||
switch s {
|
switch s {
|
||||||
case shiftRight:
|
case shiftRight:
|
||||||
if a.focusedColumn == len(a.columns)-1 {
|
if u.focusedColumn == len(u.columns)-1 {
|
||||||
a.focusedColumn = 0
|
u.focusedColumn = 0
|
||||||
} else {
|
} else {
|
||||||
a.focusedColumn++
|
u.focusedColumn++
|
||||||
}
|
}
|
||||||
case shiftLeft:
|
case shiftLeft:
|
||||||
if a.focusedColumn == 0 {
|
if u.focusedColumn == 0 {
|
||||||
a.focusedColumn = len(a.columns) - 1
|
u.focusedColumn = len(u.columns) - 1
|
||||||
} else {
|
} else {
|
||||||
a.focusedColumn--
|
u.focusedColumn--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a.setColumnFocus()
|
u.setColumnFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) setColumnFocus() {
|
func (u *UI) setColumnFocus() {
|
||||||
a.SetFocus(a.columns[a.focusedColumn].cards)
|
u.SetFocus(u.columns[u.focusedColumn].cards)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newCard creates a new card and saves it to the database.
|
// newCard creates a new card and saves it to the database.
|
||||||
func (a *App) newCard(title, content string) error {
|
func (u *UI) newCard(title, content string) error {
|
||||||
args := board.CardArgs{
|
args := board.CardArgs{
|
||||||
NewTitle: title,
|
NewTitle: title,
|
||||||
NewContent: content,
|
NewContent: content,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := a.board.CreateCard(args); err != nil {
|
if err := u.board.CreateCard(args); err != nil {
|
||||||
return fmt.Errorf("unable to create card, %w", err)
|
return fmt.Errorf("unable to create card, %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
a.refresh()
|
u.refresh()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ type column struct {
|
||||||
cards *tview.List
|
cards *tview.List
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) newColumn(statusID int, statusName string) column {
|
func (u *UI) newColumn(statusID int, statusName string) column {
|
||||||
l := tview.NewList()
|
l := tview.NewList()
|
||||||
|
|
||||||
l.SetBorder(true)
|
l.SetBorder(true)
|
||||||
|
@ -23,9 +23,9 @@ func (a *App) newColumn(statusID int, statusName string) column {
|
||||||
|
|
||||||
l.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
|
l.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
|
||||||
if event.Rune() == 'h' || event.Key() == tcell.KeyLeft {
|
if event.Rune() == 'h' || event.Key() == tcell.KeyLeft {
|
||||||
a.shiftColumnFocus(shiftLeft)
|
u.shiftColumnFocus(shiftLeft)
|
||||||
} else if event.Rune() == 'l' || event.Key() == tcell.KeyRight {
|
} else if event.Rune() == 'l' || event.Key() == tcell.KeyRight {
|
||||||
a.shiftColumnFocus(shiftRight)
|
u.shiftColumnFocus(shiftRight)
|
||||||
}
|
}
|
||||||
|
|
||||||
return event
|
return event
|
||||||
|
|
|
@ -6,8 +6,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewApp returns a new App.
|
// NewApp returns a new App.
|
||||||
func NewApp() App {
|
func NewApp() UI {
|
||||||
a := App{
|
a := UI{
|
||||||
Application: tview.NewApplication(),
|
Application: tview.NewApplication(),
|
||||||
pages: tview.NewPages(),
|
pages: tview.NewPages(),
|
||||||
flex: tview.NewFlex(),
|
flex: tview.NewFlex(),
|
||||||
|
@ -20,44 +20,44 @@ func NewApp() App {
|
||||||
}
|
}
|
||||||
|
|
||||||
// initApp initialises App.
|
// initApp initialises App.
|
||||||
func initApp(a *App) {
|
func initApp(u *UI) {
|
||||||
a.pages.AddPage(mainPage, a.flex, true, true)
|
u.pages.AddPage(mainPage, u.flex, true, true)
|
||||||
|
|
||||||
quit := newQuitModal(a)
|
quit := newQuitModal(u)
|
||||||
a.pages.AddPage(quitPage, quit, false, false)
|
u.pages.AddPage(quitPage, quit, false, false)
|
||||||
|
|
||||||
add := newAddForm(a)
|
add := newAddForm(u)
|
||||||
a.pages.AddPage(addPage, add, false, false)
|
u.pages.AddPage(addPage, add, false, false)
|
||||||
|
|
||||||
a.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
|
u.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
|
||||||
if event.Rune() == 'q' {
|
if event.Rune() == 'q' {
|
||||||
a.pages.ShowPage(quitPage)
|
u.pages.ShowPage(quitPage)
|
||||||
a.SetFocus(quit)
|
u.SetFocus(quit)
|
||||||
} else if event.Rune() == 'o' {
|
} else if event.Rune() == 'o' {
|
||||||
a.openBoard("")
|
u.openBoard("")
|
||||||
} else if event.Rune() == 'a' {
|
} else if event.Rune() == 'a' {
|
||||||
a.pages.ShowPage(addPage)
|
u.pages.ShowPage(addPage)
|
||||||
a.SetFocus(add)
|
u.SetFocus(add)
|
||||||
}
|
}
|
||||||
|
|
||||||
return event
|
return event
|
||||||
})
|
})
|
||||||
|
|
||||||
a.SetRoot(a.pages, true)
|
u.SetRoot(u.pages, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newQuitModal returns a new modal for the user's confirmation
|
// newQuitModal returns a new modal for the user's confirmation
|
||||||
// for quitting the application.
|
// for quitting the application.
|
||||||
func newQuitModal(app *App) *tview.Modal {
|
func newQuitModal(u *UI) *tview.Modal {
|
||||||
quit := *tview.NewModal()
|
quit := *tview.NewModal()
|
||||||
|
|
||||||
quitDoneFunc := func(_ int, buttonLabel string) {
|
quitDoneFunc := func(_ int, buttonLabel string) {
|
||||||
switch buttonLabel {
|
switch buttonLabel {
|
||||||
case "Quit":
|
case "Quit":
|
||||||
app.shutdown()
|
u.shutdown()
|
||||||
default:
|
default:
|
||||||
app.pages.SwitchToPage("main")
|
u.pages.SwitchToPage("main")
|
||||||
app.setColumnFocus()
|
u.setColumnFocus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ func newQuitModal(app *App) *tview.Modal {
|
||||||
}
|
}
|
||||||
|
|
||||||
// newAddForm creates a new Form primitive for creating a new card.
|
// newAddForm creates a new Form primitive for creating a new card.
|
||||||
func newAddForm(app *App) *tview.Form {
|
func newAddForm(u *UI) *tview.Form {
|
||||||
add := tview.NewForm()
|
add := tview.NewForm()
|
||||||
|
|
||||||
titleField := "Title"
|
titleField := "Title"
|
||||||
|
@ -79,16 +79,16 @@ func newAddForm(app *App) *tview.Form {
|
||||||
add.AddButton("Save", func() {
|
add.AddButton("Save", func() {
|
||||||
title := add.GetFormItemByLabel(titleField).(*tview.InputField).GetText()
|
title := add.GetFormItemByLabel(titleField).(*tview.InputField).GetText()
|
||||||
// TODO: error value needs handling
|
// TODO: error value needs handling
|
||||||
_ = app.newCard(title, "")
|
_ = u.newCard(title, "")
|
||||||
add.GetFormItemByLabel(titleField).(*tview.InputField).SetText("")
|
add.GetFormItemByLabel(titleField).(*tview.InputField).SetText("")
|
||||||
app.pages.SwitchToPage(mainPage)
|
u.pages.SwitchToPage(mainPage)
|
||||||
app.setColumnFocus()
|
u.setColumnFocus()
|
||||||
})
|
})
|
||||||
|
|
||||||
add.AddButton("Cancel", func() {
|
add.AddButton("Cancel", func() {
|
||||||
app.pages.SwitchToPage(mainPage)
|
u.pages.SwitchToPage(mainPage)
|
||||||
add.GetFormItemByLabel(titleField).(*tview.InputField).SetText("")
|
add.GetFormItemByLabel(titleField).(*tview.InputField).SetText("")
|
||||||
app.setColumnFocus()
|
u.setColumnFocus()
|
||||||
})
|
})
|
||||||
|
|
||||||
add.SetBorder(true)
|
add.SetBorder(true)
|
||||||
|
|
Loading…
Reference in a new issue