Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ start: build
./$(BINARY)

debugv3:
rm -f puffin.log
go run . -debug -v3

test:
Expand Down
197 changes: 197 additions & 0 deletions ui/v2/balance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
package ui

import (
"log"

"github.com/charmbracelet/bubbles/table"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/siddhantac/puffin/ui/v2/interfaces"
)

type queryBalanceMsg struct{}
type updateBalanceMsg struct {
rows []table.Row
columns []table.Column
}

func queryBalanceCmd() tea.Msg {
return queryBalanceMsg{}
}

type balanceReports struct {
height, width int
filterGroup *filterGroup
displayOptionsGroup *displayOptionsGroup
dataProvider interfaces.DataProvider
cmdRunner *cmdRunner

assets *customTable
expenses *customTable
}

func newBalanceReports(dataProvider interfaces.DataProvider, cmdRunner *cmdRunner) *balanceReports {
assetsTbl := newCustomTable("assets")
assetsTbl.SetReady(true)
assetsTbl.Focus()

expensesTbl := newCustomTable("expenses")
expensesTbl.SetReady(true)

optionFactory := displayOptionsGroupFactory{}
filterGroupFactory := filterGroupFactory{}
br := &balanceReports{
assets: assetsTbl,
expenses: expensesTbl,
dataProvider: dataProvider,
filterGroup: filterGroupFactory.NewGroupBalance(),
displayOptionsGroup: optionFactory.NewReportsGroup(interfaces.Yearly, 3, interfaces.ByAccount),
cmdRunner: cmdRunner,
}

return br
}

func (b *balanceReports) Init() tea.Cmd {
return tea.Sequence(
b.assets.Init(),
b.expenses.Init(),
queryBalanceCmd,
)
}

func (b *balanceReports) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.WindowSizeMsg:
b.width = msg.Width
b.height = msg.Height

fg, _ := b.filterGroup.Update(msg)
b.filterGroup = fg.(*filterGroup)

b.assets.SetHeight(msg.Height - 11)
b.expenses.SetHeight(msg.Height - 11)

return b, nil

case focusFilterMsg:
log.Printf("balances: msg: %T", msg)
b.filterGroup.Focus()
return b, nil

case blurFilterMsg:
log.Printf("balances: msg: %T", msg)
b.filterGroup.Blur()
return b, nil

case refreshDataMsg:
log.Printf("balances: msg: %T", msg)
b.filterGroup.Blur()
return b, queryBalanceCmd

case tea.KeyMsg:
log.Printf("balances: msg: %T | %v", msg, msg)
if b.filterGroup.Focused() {
fg, cmd := b.filterGroup.Update(msg)
b.filterGroup = fg.(*filterGroup)
return b, cmd
}

dg, cmd := b.displayOptionsGroup.Update(msg)
b.displayOptionsGroup = dg.(*displayOptionsGroup)
if cmd != nil {
return b, cmd
}

b.assets, _ = b.assets.Update(msg)
b.expenses, _ = b.expenses.Update(msg)
return b, nil

case queryBalanceMsg:
b.assets.SetReady(false)
b.expenses.SetReady(false)
f := func() tea.Msg {
return b.balanceData()
}
b.cmdRunner.Run(f)
return b, nil

case updateBalanceMsg:
b.assets.SetRows(nil)
b.assets.SetColumns(msg.columns)
b.assets.SetRows(msg.rows)
b.assets.SetReady(true)
b.assets.SetCursor(0)

b.expenses.SetRows(nil)
b.expenses.SetColumns(msg.columns)
b.expenses.SetRows(msg.rows)
b.expenses.SetReady(true)
b.expenses.SetCursor(0)
return b, nil

default:
var cmd tea.Cmd
b.assets, cmd = b.assets.Update(msg)
b.expenses, cmd = b.expenses.Update(msg)
return b, cmd
}
}

func (b *balanceReports) View() string {
filterView := lipgloss.JoinHorizontal(
lipgloss.Center,
b.filterGroup.View(),
" ",
lipgloss.NewStyle().
Border(lipgloss.RoundedBorder(), false, false, false, true).
BorderForeground(lipgloss.Color("240")).
Render(divider.View()),
" ",
b.displayOptionsGroup.View(),
)
return lipgloss.JoinVertical(
lipgloss.Left,
filterView,
b.assets.View(),
)
}

func (b *balanceReports) balanceData() updateBalanceMsg {
filter := interfaces.Filter{
AccountType: "assets",
Account: b.filterGroup.AccountName(),
DateStart: b.filterGroup.DateStart(),
DateEnd: b.filterGroup.DateEnd(),
}

displayOptions := interfaces.DisplayOptions{
Interval: b.displayOptionsGroup.IntervalValue(),
Depth: b.displayOptionsGroup.DepthValue(),
Sort: b.displayOptionsGroup.SortValue(),
}

balanceData, err := b.dataProvider.Balance(filter, displayOptions)
if err != nil {
panic(err)
}

if len(balanceData) <= 1 {
return updateBalanceMsg{}
}

cols := calculateColumns(balanceData[0], b.width)

cols[0].Title = "account"

data := balanceData[1:]
rows := make([]table.Row, 0, len(data))
for _, row := range data {
rows = append(rows, row)
}

return updateBalanceMsg{
rows: rows,
columns: cols,
}
}
3 changes: 1 addition & 2 deletions ui/v2/command_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ func (cr *cmdRunner) Run(cmd command) {

func (cr *cmdRunner) listen() {
go func() {
log.Printf(">> listening")
log.Println("command runner listening")
for f := range cr.workChan {
if cr.p == nil {
log.Printf(">> program is nil")
continue
}

Expand Down
86 changes: 37 additions & 49 deletions ui/v2/complex_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,20 @@ import (
type complexTable struct {
title, upperTitle, lowerTitle string
bottomBar table.Model
upper, lower table.Model
upper, lower *customTable
focus bool
columns []string
}

func newComplexTable() *complexTable {
return &complexTable{
upper: table.New(),
lower: table.New(),
ct := &complexTable{
upper: newCustomTable(""),
lower: newCustomTable(""),
bottomBar: table.New(),
}
ct.upper.SetReady(true)
ct.lower.SetReady(true)
return ct
}

func (c *complexTable) Focus() {
Expand Down Expand Up @@ -72,9 +75,6 @@ func (c *complexTable) Update(msg tea.Msg) (*complexTable, tea.Cmd) {
}

func (c *complexTable) View() string {
tableStyleActive, styleActive := tblStyleActive()
tableStyleInactive, styleInactive := tblStyleInactive()

nonInteractiveTableStyle := table.DefaultStyles()
nonInteractiveTableStyle.Header = nonInteractiveTableStyle.Header.
BorderStyle(lipgloss.NormalBorder()).
Expand All @@ -83,21 +83,11 @@ func (c *complexTable) View() string {
Bold(false)
c.bottomBar.SetStyles(nonInteractiveTableStyle)

var upper, lower string

if c.upper.Focused() {
c.upper.SetStyles(tableStyleActive)
upper = styleActive.Render(c.upper.View())
upper := c.upper.View()
lower := c.lower.View()

c.lower.SetStyles(tableStyleInactive)
lower = styleInactive.Render(c.lower.View())
} else {
c.upper.SetStyles(tableStyleInactive)
upper = styleInactive.Render(c.upper.View())
_, styleInactive := tableStyleInactive()

c.lower.SetStyles(tableStyleActive)
lower = styleActive.Render(c.lower.View())
}
return lipgloss.JoinVertical(
lipgloss.Left,
lipgloss.JoinVertical(
Expand Down Expand Up @@ -145,49 +135,47 @@ func setColumns(complexTable *complexTable, width int) {
return
}

cols := calculateColumns(complexTable.columns, width)

upperCols := make([]table.Column, len(cols))
copy(upperCols, cols)
upperCols[0].Title = complexTable.upperTitle
complexTable.upper.SetColumns(upperCols)

lowerCols := make([]table.Column, len(cols))
copy(lowerCols, cols)
lowerCols[0].Title = complexTable.lowerTitle
complexTable.lower.SetColumns(lowerCols)

netCols := make([]table.Column, len(cols))
copy(netCols, cols)
netCols[0].Title = "Net"
complexTable.bottomBar.SetColumns(netCols)
}

func calculateColumns(columnData []string, width int) []table.Column {
accountColWidth := percent(width, 20)
commodityColWidth := 10
remainingWidth := width - accountColWidth - commodityColWidth - 2
otherColumnsWidth := remainingWidth/(len(complexTable.columns)-2) - 2
otherColumnsWidth := remainingWidth/(len(columnData)-2) - 2

cols := []table.Column{
{
Title: complexTable.columns[1],
Title: "",
Width: accountColWidth,
},
{
Title: columnData[1],
Width: commodityColWidth,
},
}
for _, c := range complexTable.columns[2:] {
for _, c := range columnData[2:] {
cols = append(cols,
table.Column{
Title: c,
Width: otherColumnsWidth,
})
}

upperCols := make([]table.Column, 0)
upperCols = append(upperCols, table.Column{
Title: complexTable.upperTitle,
Width: accountColWidth,
},
)
upperCols = append(upperCols, cols...)
complexTable.upper.SetColumns(upperCols)

lowerCols := []table.Column{
{
Title: complexTable.lowerTitle,
Width: accountColWidth,
},
}
lowerCols = append(lowerCols, cols...)
complexTable.lower.SetColumns(lowerCols)

netCols := []table.Column{
{
Title: "Net",
Width: accountColWidth,
},
}
netCols = append(netCols, cols...)
complexTable.bottomBar.SetColumns(netCols)
return cols
}
Loading
Loading