Skip to content

Commit

Permalink
feat: 0.3.4
Browse files Browse the repository at this point in the history
  • Loading branch information
EnhancedJax committed Jan 29, 2025
1 parent dd68392 commit e4c687d
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 48 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 0.3.4

- Added ability to click on accounts in accounts-mode module
- Fix: Focus removed when switching to persons with empty view

## 0.3.2

- Added error message and user prompt when config error
Expand Down
49 changes: 39 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
# Bagels - TUI Expense Tracker
# 🥯 Bagels - TUI Expense Tracker

Powerful expense tracker that lives in your terminal.

![GitHub commit activity](https://img.shields.io/github/commit-activity/t/EnhancedJax/Bagels?style=for-the-badge)
![GitHub License](https://img.shields.io/github/license/EnhancedJax/Bagels?style=for-the-badge)
![PyPI - Downloads](https://img.shields.io/pypi/dm/Bagels?style=for-the-badge)
<a title="This tool is Tool of The Week on Terminal Trove, The $HOME of all things in the terminal" href="https://terminaltrove.com/bagels"><img src="https://cdn.terminaltrove.com/media/badges/tool_of_the_week/svg/terminal_trove_tool_of_the_week_black_on_white_bg.svg" alt="Terminal Trove Tool of The Week" height="28" /></a>

![Bagels](./public/screenshots/thumb1.png)
![Bagels](./public/screenshots/thumb2.png)

Expand All @@ -10,7 +15,7 @@ Bagels expense tracker is a TUI application where you can track and analyse your
> **Why an expense tracker in the terminal?**
> I found it easier to build a habit and keep an accurate track of my expenses if I do it at the end of the day, instead of on the go. So why not in the terminal where it's fast, and I can keep all my data locally?
## Features
## Features

Some notable features include:

Expand All @@ -27,9 +32,12 @@ Some notable features include:
- Spending plottings / graphs with estimated spendings
- Budgetting tool for saving money and limiting unnecessary spendings

## Installation
## 📦 Installation

<details open>
<summary><b>Recommended: By UV</b></summary>

MacOS:
#### Unix / MacOS:

```bash
# install uv (package manager):
Expand All @@ -42,16 +50,36 @@ source $HOME/.local/bin/env # or follow instructions
uv tool install --python 3.13 bagels
```

Windows:
#### Windows:

```bash
# install uv:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
winget install --id=astral-sh.uv -e
# then follow instructions to add uv to path
uv tool install --python 3.13 bagels
```

Usage:
</details>

<details>
<summary>By Pipx</summary>

```bash
pipx install bagels
```

</details>

<details>
<summary>By Conda</summary>

```bash
conda install -c conda-forge bagels
```

</details>

## 🥯 Usage:

```bash
bagels # start bagels
Expand All @@ -62,13 +90,13 @@ bagels locate config # find config file path

> It is recommended, but not required, to use "modern" terminals to run the app. MacOS users are recommended to use Ghostty, and Windows users are recommended to use Windows Terminal.
To upgrade:
To upgrade with uv:

```bash
uv tool upgrade bagels
```

## Development setup
## 🛠️ Development setup

```sh
git clone https://github.com/EnhancedJax/Bagels.git
Expand All @@ -83,12 +111,13 @@ uv run textual console -x SYSTEM -x EVENT -x DEBUG -x INFO # for logging

Please use the black formatter to format the code.

## Roadmap
## 🗺️ Roadmap

- [x] Budgets (Major!)
- [x] More insight displays and analysis (by nature etc.)
- [ ] Daily check-ins
- [ ] Pagination for records on monthly and yearly views.
- [ ] Importing from various formats

Backlog:

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "Bagels"
version = "0.3.3"
version = "0.3.4"
authors = [
{ name = "Jax", email = "[email protected]" }
]
Expand Down
57 changes: 40 additions & 17 deletions src/bagels/components/modules/accountmode.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from textual import events
from textual.app import ComposeResult
from textual.containers import Container, ScrollableContainer
from textual.widgets import Label, Static
from textual.widgets import Label, ListItem, ListView, Static

from bagels.components.indicators import EmptyIndicator
from bagels.config import CONFIG
Expand All @@ -17,6 +17,40 @@
from bagels.modals.input import InputModal


class AccountsList(ListView):
def __init__(self, accounts, *args, **kwargs):
super().__init__(
*[
ListItem(
Container(
Label(
str(account.name),
classes="name",
id=f"account-{account.id}-name",
),
Label(
str(account.description or ""),
classes=f"description{'none' if not account.description else ''}",
id=f"account-{account.id}-description",
),
classes="left-container",
),
Label(
str(account.balance),
classes="balance",
id=f"account-{account.id}-balance",
),
classes="account-container",
id=f"account-{account.id}-container",
)
for account in accounts
],
id="accounts-list",
*args,
**kwargs,
)


class AccountMode(ScrollableContainer):
BINDINGS = [
(CONFIG.hotkeys.new, "new", "New account"),
Expand Down Expand Up @@ -91,6 +125,10 @@ def on_key(self, event: events.Key) -> None:
elif event.key == "down":
self.page_parent.action_select_next_account()

def on_list_view_selected(self, event: ListView.Selected) -> None:
account_id = event.item.id.split("-")[1]
self.page_parent.action_select_account(account_id)

# region cud
# ---------------- cud --------------- #

Expand Down Expand Up @@ -185,19 +223,4 @@ def compose(self) -> ComposeResult:
yield EmptyIndicator("No accounts")
return

for account in accounts:
with Container(
id=f"account-{account.id}-container", classes="account-container"
):
with Container(classes="left-container"):
yield Label(
"", # Will be populated in rebuild()
classes="name",
id=f"account-{account.id}-name",
)
yield Label(
"", # Will be populated in rebuild()
classes="description",
id=f"account-{account.id}-description",
)
yield Label("", classes="balance", id=f"account-{account.id}-balance")
yield AccountsList(accounts)
17 changes: 8 additions & 9 deletions src/bagels/components/modules/records/_cud.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
from datetime import datetime


from bagels.managers.record_templates import create_template_from_record
from bagels.modals.confirmation import ConfirmationModal
from bagels.modals.record import RecordModal
from bagels.modals.transfer import TransferModal
from bagels.modals.input import InputModal
from bagels.forms.form import Form
from bagels.forms.record_forms import RecordForm
from bagels.managers.persons import (
get_person_by_id,
update_person,
)
from bagels.managers.record_templates import create_template_from_record
from bagels.managers.records import (
create_record,
create_record_and_splits,
Expand All @@ -19,9 +16,11 @@
update_record_and_splits,
)
from bagels.managers.splits import get_split_by_id, update_split
from bagels.forms.form import Form
from bagels.modals.confirmation import ConfirmationModal
from bagels.modals.input import InputModal
from bagels.modals.record import RecordModal
from bagels.modals.transfer import TransferModal
from bagels.utils.format import format_date_to_readable
from bagels.forms.record_forms import RecordForm


class RecordCUD:
Expand All @@ -43,7 +42,7 @@ def check_result(result) -> None:
severity="information",
timeout=3,
)
self.page_parent.rebuild()
self.page_parent.rebuild(templates=result["createTemplate"])

date = format_date_to_readable(self.page_parent.mode["date"])
account_name = self.page_parent.mode["accountId"]["default_value_text"]
Expand Down
7 changes: 5 additions & 2 deletions src/bagels/components/modules/records/_table_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,15 @@ def rebuild(self, focus=True) -> None:
case _:
pass

if focus:
table.focus()
if hasattr(self, "current_row_index"):
table.move_cursor(row=self.current_row_index)
empty_indicator.display = not table.rows
table.display = not not table.rows
if focus:
if table.display:
table.focus()
else:
self.focus()

def _fetch_records(self):
params = {
Expand Down
28 changes: 20 additions & 8 deletions src/bagels/home.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,15 @@ def on_mount(self) -> None:

# -------------- Helpers ------------- #

def rebuild(self) -> None:
def rebuild(self, templates=False) -> None:
self.insights_module.rebuild()
self.accounts_module.rebuild()
self.income_mode_module.rebuild()
self.date_mode_module.rebuild()
if self.isReady:
self.record_module.rebuild()
self.templates_module.rebuild(reset_state=True)
if templates:
self.templates_module.rebuild(reset_state=True)

def get_filter_label(self) -> str:
return format_period_to_readable(self.filter)
Expand Down Expand Up @@ -204,25 +205,36 @@ def action_toggle_income_mode(self) -> None:
self.income_mode_module.rebuild()
self.insights_module.rebuild()

def _select_account(self, dir: int) -> None:
if self.accounts_indices["count"] > 0:
def _select_account(self, dir: int = 0, id: int = None) -> None:
if id is not None:
for index, account in enumerate(self.accounts):
if account.id == int(id):
self.accounts_indices["index"] = index
self.mode["accountId"]["default_value"] = account.id
self.mode["accountId"]["default_value_text"] = account.name
break
elif self.accounts_indices["count"] > 0:
new_index = (self.accounts_indices["index"] + dir) % self.accounts_indices[
"count"
]
self.accounts_indices["index"] = new_index
self.mode["accountId"]["default_value"] = self.accounts[new_index].id
self.mode["accountId"]["default_value_text"] = self.accounts[new_index].name
self.accounts_module.rebuild()
self.insights_module.rebuild()
if self.filter["byAccount"]:
self.record_module.rebuild()

self.accounts_module.rebuild()
self.insights_module.rebuild()
if self.filter["byAccount"]:
self.record_module.rebuild()

def action_select_prev_account(self) -> None:
self._select_account(-1)

def action_select_next_account(self) -> None:
self._select_account(1)

def action_select_account(self, account_id: int) -> None:
self._select_account(id=account_id)

def action_toggle_use_account(self) -> None:
self.filter["byAccount"] = not self.filter["byAccount"]
self.insights_module.rebuild()
Expand Down
2 changes: 2 additions & 0 deletions src/bagels/styles/home_modules.tcss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
align-vertical: middle;
padding: 0 1 1 1;
border-top: tall $surface;
width: 1fr;
background: $background;

.left-container {
height: auto;
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e4c687d

Please sign in to comment.