feat: Add support for editing status columns
All checks were successful
/ test (pull_request) Successful in 36s
/ lint (pull_request) Successful in 42s

This commit is contained in:
Dan Anglin 2024-01-17 13:43:20 +00:00
parent 46f5f07105
commit 1a85daedc2
Signed by: dananglin
GPG key ID: 0C1D44CFBEE68638
5 changed files with 166 additions and 7 deletions

View file

@ -100,6 +100,8 @@ func (c *column) update(kanban board.Board) error {
}
}
c.statusName = status.Name
c.SetTitle(fmt.Sprintf(" %s (%d) ", c.statusName, numCardIDs))
return nil

View file

@ -97,6 +97,7 @@ func (a *App) initCardView() {
a.cardView.setDoneFunc(doneFunc)
}
// initStatusbar initialises the status bar.
func (a *App) initStatusbar() {
changedFunc := func() {
a.Draw()
@ -104,3 +105,16 @@ func (a *App) initStatusbar() {
a.statusbar.SetChangedFunc(changedFunc)
}
func (a *App) initStatusForm() {
doneFunc := func(name string, success bool) {
if success {
a.editFocusedStatusColumn(name)
}
a.pages.HidePage(statusFormPage)
a.setColumnFocus()
}
a.statusForm.setDoneFunc(doneFunc)
}

View file

@ -8,19 +8,21 @@ import (
func (a *App) inputCapture() func(event *tcell.EventKey) *tcell.EventKey {
return func(event *tcell.EventKey) *tcell.EventKey {
key, letter := event.Key(), event.Rune()
key, character := event.Key(), event.Rune()
switch {
case letter == 'h' || key == tcell.KeyLeft:
case character == 'h' || key == tcell.KeyLeft:
a.shiftColumnFocus(previous)
case letter == 'l' || key == tcell.KeyRight:
case character == 'l' || key == tcell.KeyRight:
a.shiftColumnFocus(next)
case letter == 'c':
case character == 'c':
a.create()
case letter == 'm':
case character == 'm':
a.move()
case letter == 'e':
case character == 'e':
a.edit()
case character == 'b':
a.updateBoardMode(boardEdit)
case key == tcell.KeyCtrlD:
a.delete()
case key == tcell.KeyCtrlQ:
@ -54,7 +56,8 @@ func (a *App) move() {
}
func (a *App) edit() {
if a.mode == normal {
switch a.mode {
case normal:
a.cardForm.mode = edit
card, ok := a.getFocusedCard()
@ -66,6 +69,12 @@ func (a *App) edit() {
a.cardForm.frame.SetTitle(" Edit Card ")
a.pages.ShowPage(cardFormPage)
a.SetFocus(a.cardForm)
case boardEdit:
statusName := a.focusedStatusName()
a.statusForm.updateInputFields(statusName)
a.statusForm.frame.SetTitle(" Edit Status Name ")
a.pages.ShowPage(statusFormPage)
a.SetFocus(a.statusForm)
}
}

103
internal/ui/statusform.go Normal file
View file

@ -0,0 +1,103 @@
package ui
import (
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
)
type statusForm struct {
*tview.Form
frame *tview.Frame
nameLabel string
done func(string, bool)
}
func newStatusForm() *statusForm {
var (
background = tcell.ColorBlack.TrueColor()
buttonBackground = tcell.ColorBlueViolet.TrueColor()
textColour = tcell.ColorWhite.TrueColor()
fieldBackground = tcell.ColorGrey.TrueColor()
labelColour = tcell.ColorGreen.TrueColor()
form = tview.NewForm()
)
obj := statusForm{
Form: form,
frame: tview.NewFrame(form),
done: nil,
nameLabel: "Name",
}
// Stylise the buttons
obj.SetButtonsAlign(tview.AlignCenter).
SetButtonBackgroundColor(buttonBackground).
SetButtonTextColor(textColour).
SetBorderPadding(0, 0, 0, 0)
// Stylise the form
obj.SetLabelColor(labelColour).
SetFieldBackgroundColor(fieldBackground).
SetFieldTextColor(textColour).
SetBackgroundColor(background)
// Stylise the frame around the form
obj.frame.SetBorders(0, 0, 1, 0, 0, 0).
SetBorder(true).
SetBorderColor(tcell.ColorOrangeRed.TrueColor()).
SetBackgroundColor(background).
SetBorderPadding(1, 1, 1, 1)
obj.AddButton("Save", func() {
if obj.done != nil {
name, ok := obj.GetFormItemByLabel(obj.nameLabel).(*tview.InputField)
if !ok {
return
}
obj.done(name.GetText(), true)
}
})
obj.AddButton("Cancel", func() {
if obj.done != nil {
obj.done("", false)
}
})
return &obj
}
func (s *statusForm) updateInputFields(name string) {
s.Clear(false)
s.AddInputField(s.nameLabel, name, 0, nil, nil)
}
func (s *statusForm) setDoneFunc(handler func(string, bool)) *statusForm {
s.done = handler
return s
}
func (s *statusForm) Draw(screen tcell.Screen) {
buttonsWidth := 20
screenWidth, screenHeight := screen.Size()
width := screenWidth / 3
if width < buttonsWidth {
width = buttonsWidth
}
height := 20
width += 4
// Set the form's position and size.
x := (screenWidth - width) / 2
y := (screenHeight - height) / 2
s.SetRect(x, y, width, height)
// Draw the frame.
s.frame.SetRect(x, y, width, height)
s.frame.Draw(screen)
}

View file

@ -23,9 +23,13 @@ const (
cardFormPage string = "card form"
deleteCardModalPage string = "delete card modal"
viewPage string = "view"
statusFormPage string = "status form"
)
const (
normal boardMode = "NORMAL"
selection boardMode = "SELECTION"
boardEdit boardMode = "BOARD EDIT"
)
type App struct {
@ -45,6 +49,7 @@ type App struct {
statusSelection statusSelection
cardView *cardView
statusbar *statusbar
statusForm *statusForm
}
// NewApp returns a new App value.
@ -70,6 +75,7 @@ func NewApp(path string) (App, error) {
statusSelection: statusSelection{0, 0, 0},
cardView: newCardView(),
statusbar: newStatusbar(),
statusForm: newStatusForm(),
}
return app, nil
@ -106,6 +112,9 @@ func (a *App) Init() error {
a.initCardView()
a.pages.AddPage(viewPage, a.cardView, false, false)
a.initStatusForm()
a.pages.AddPage(statusFormPage, a.statusForm, false, false)
a.SetRoot(a.pages, true)
a.refresh(false)
@ -298,3 +307,25 @@ func (a *App) focusedStatusName() string {
func (a *App) closeBoard() {
_ = a.board.Close()
}
// editFocusedStatusColumn updates the status column in focus and saves the changes to the database.
func (a *App) editFocusedStatusColumn(newName string) {
statusID := a.focusedStatusID()
args := board.UpdateStatusArgs{
StatusID: statusID,
StatusArgs: board.StatusArgs{
Name: newName,
},
}
if err := a.board.UpdateStatus(args); err != nil {
a.statusbar.displayMessage(errorLevel, fmt.Sprintf("Failed to edit status: %v.", err))
return
}
a.statusbar.displayMessage(infoLevel, "Status updated successfully.")
a.refresh(true)
}