You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

232 lines
5.9 KiB

package shelves
import (
"git.brettb.xyz/goinv/client/internal/ui/shelves/shlvdialogs"
"sync"
"git.brettb.xyz/goinv/client/internal/api"
"git.brettb.xyz/goinv/client/internal/types"
"git.brettb.xyz/goinv/client/internal/ui/dialogs"
"git.brettb.xyz/goinv/client/internal/ui/style"
"git.brettb.xyz/goinv/client/internal/ui/utils"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
"go.uber.org/zap"
)
const (
status_CONFIRM_DELETE_SHELF = "delete_shelf"
)
type Shelves struct {
*tview.Box
client *api.APIClient
title string
logger *zap.Logger
shelfTable *tview.Table
shelfList shelfListReport
buildingCache buildingListReport
shelfTableHeaders []string
shelfTableExpansions []int
cmdDialog *dialogs.CommandDialog
confirmDialog *dialogs.ConfirmDialog
errorDialog *dialogs.ErrorDialog
progressDialog *dialogs.ProgressDialog
messageDialog *dialogs.MessageDialog
createDialog *shlvdialogs.ShelfCreateDialog
editDialog *shlvdialogs.ShelfEditDialog
allDialogs []dialogs.Dialog
confirmData string
shelfListFunc func() ([]types.ShelfLocation, error)
buildingListFunc func() (map[uint64]types.Building, error)
}
type shelfSelectedItem struct {
id string
name string
building string
roomNumber string
}
type shelfListReport struct {
mu sync.Mutex
report []types.ShelfLocation
dirty bool
}
type buildingListReport struct {
mu sync.Mutex
report map[uint64]types.Building
dirty bool
}
func NewShelves(logger *zap.Logger, client *api.APIClient) *Shelves {
shelves := &Shelves{
Box: tview.NewBox(),
client: client,
title: "shelves",
logger: logger,
shelfTable: tview.NewTable(),
shelfTableHeaders: []string{"id", "name", "building", "room number"},
shelfTableExpansions: []int{1, 4, 2, 2},
confirmDialog: dialogs.NewConfirmDialog(logger),
errorDialog: dialogs.NewErrorDialog(logger),
progressDialog: dialogs.NewProgressDialog(logger),
messageDialog: dialogs.NewMessageDialog(logger, ""),
createDialog: shlvdialogs.NewShelfCreateDialog(logger, client),
editDialog: shlvdialogs.NewShelfEditDialog(logger, client),
}
shelves.shelfTable.SetBackgroundColor(style.BgColor)
shelves.shelfTable.SetBorder(true)
shelves.updateShelfTableTitle(0)
shelves.shelfTable.SetTitleColor(style.FgColor)
shelves.shelfTable.SetBorderColor(style.BorderColor)
shelves.shelfTable.SetFixed(1, 1)
shelves.shelfTable.SetSelectable(true, false)
shelves.writeTableHeaders()
shelves.shelfTable.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
if shelves.shelfTable.GetRowCount() <= 1 {
return nil
}
return event
})
shelves.cmdDialog = dialogs.NewCommandDialog(logger, [][]string{
{"create shelf", "create a new shelf"},
{"edit shelf", "edit the selected shelf"},
{"delete shelf", "delete the selected shelf"},
{"refresh", "refresh the page"},
})
shelves.cmdDialog.SetSelectedFunc(func() {
shelves.cmdDialog.Hide()
shelves.runCommand(shelves.cmdDialog.GetSelectedItem())
}).SetCancelFunc(func() {
shelves.cmdDialog.Hide()
})
shelves.confirmDialog.SetSelectedFunc(func() {
shelves.confirmDialog.Hide()
switch shelves.confirmData {
case status_CONFIRM_DELETE_SHELF:
shelves.delete()
}
}).SetCancelFunc(func() {
shelves.confirmDialog.Hide()
})
shelves.messageDialog.SetCancelFunc(func() {
shelves.messageDialog.Hide()
})
shelves.createDialog.SetCancelFunc(func() {
shelves.createDialog.Hide()
}).SetCreateFunc(func() {
shelves.createDialog.Hide()
shelves.create()
})
shelves.editDialog.SetCancelFunc(func() {
shelves.editDialog.Hide()
}).SetEditFunc(func() {
shelves.editDialog.Hide()
shelves.edit()
})
shelves.SetShelfListFunc(func() ([]types.ShelfLocation, error) {
if shlvr, err := shelves.client.RetrieveAllShelves(); err != nil {
return nil, err
} else {
var shlvo []types.ShelfLocation
for _, shelf := range shlvr {
shlvo = append(shlvo, *shelf)
}
return shlvo, nil
}
})
shelves.SetBuildingListFunc(func() (map[uint64]types.Building, error) {
if resp, err := shelves.client.RetrieveAllBuildings(); err != nil {
return nil, err
} else {
buildings := map[uint64]types.Building{}
for _, a := range resp {
buildings[a.ID] = *a
}
return buildings, nil
}
})
shelves.allDialogs = []dialogs.Dialog{
shelves.errorDialog,
shelves.messageDialog,
shelves.progressDialog,
shelves.confirmDialog,
shelves.createDialog,
shelves.editDialog,
shelves.cmdDialog,
}
return shelves
}
func (a *Shelves) GetTitle() string {
return a.title
}
func (a *Shelves) HasFocus() bool {
return dialogs.CheckDialogFocus(a.allDialogs...) || utils.CheckFocus(a.shelfTable, a.Box)
}
func (a *Shelves) SubDialogHasFocus() bool {
return dialogs.CheckDialogFocus(a.allDialogs...)
}
func (a *Shelves) Focus(delegate func(tview.Primitive)) {
for _, dialog := range a.allDialogs {
if dialog.IsDisplay() {
delegate(dialog)
return
}
}
delegate(a.shelfTable)
}
func (a *Shelves) SetBuildingListFunc(list func() (map[uint64]types.Building, error)) {
a.buildingListFunc = list
}
func (a *Shelves) SetShelfListFunc(list func() ([]types.ShelfLocation, error)) {
a.shelfListFunc = list
}
func (a *Shelves) hideAllDialogs() {
for _, dialog := range a.allDialogs {
dialog.Hide()
}
}
func (a *Shelves) getSelectedItem() *shelfSelectedItem {
selectedItem := shelfSelectedItem{}
if a.shelfTable.GetRowCount() <= 1 {
return nil
}
row, _ := a.shelfTable.GetSelection()
selectedItem.id = a.shelfTable.GetCell(row, 0).Text
selectedItem.name = a.shelfTable.GetCell(row, 1).Text
selectedItem.building = a.shelfTable.GetCell(row, 2).Text
selectedItem.roomNumber = a.shelfTable.GetCell(row, 3).Text
return &selectedItem
}