Compare commits

...

2 Commits

Author SHA1 Message Date
86b80f87f8 fix callbacks 2025-01-05 06:59:34 -06:00
6d3b82ece2 refactor 2025-01-05 06:26:50 -06:00
5 changed files with 39 additions and 34 deletions

View File

@ -4,7 +4,8 @@ import lxml.html
from typing_extensions import Annotated from typing_extensions import Annotated
from .controller import add_task from .controller import add_task
from .import_csv import import_tasks_from_csv from .import_csv import import_tasks_from_csv
from . import tui from .db import initialize_db
from .tui import tasks
app = typer.Typer() app = typer.Typer()
@ -16,6 +17,7 @@ def new(
due: Annotated[str, typer.Option("-d", "--due", help="due")] = "", due: Annotated[str, typer.Option("-d", "--due", help="due")] = "",
url: Annotated[str, typer.Option("-u", "--url", help="URL")] = "", url: Annotated[str, typer.Option("-u", "--url", help="URL")] = "",
): ):
initialize_db()
required = ["name", "category"] required = ["name", "category"]
if url and not name: if url and not name:
@ -42,7 +44,8 @@ def new(
def browse( def browse(
view: Annotated[str, typer.Option("-v", "--view", help="saved view")] = "default", view: Annotated[str, typer.Option("-v", "--view", help="saved view")] = "default",
): ):
tui.run(view) initialize_db()
tasks.run(view)
@app.command() @app.command()

View File

@ -11,8 +11,8 @@ def category_lookup(category):
return category.id return category.id
def get_task(task_id: int) -> Task: def get_task(item_id: int) -> Task:
return Task.get_by_id(task_id) return Task.get_by_id(item_id)
def add_task( def add_task(
@ -35,15 +35,15 @@ def add_task(
def update_task( def update_task(
task_id: int, item_id: int,
**kwargs, **kwargs,
) -> Task: ) -> Task:
with db.atomic(): with db.atomic():
if category := kwargs.pop("category", None): if category := kwargs.pop("category", None):
kwargs["category_id"] = category_lookup(category) kwargs["category_id"] = category_lookup(category)
query = Task.update(kwargs).where(Task.id == task_id) query = Task.update(kwargs).where(Task.id == item_id)
query.execute() query.execute()
task = Task.get_by_id(task_id) task = Task.get_by_id(item_id)
return task return task

View File

@ -7,13 +7,13 @@ from textual.widgets import (
) )
from textual.containers import Container from textual.containers import Container
from .utils import ( from ..utils import (
remove_rich_tag, remove_rich_tag,
filter_to_string, filter_to_string,
advance_enum_val, advance_enum_val,
get_text_from_editor, get_text_from_editor,
) )
from .tui_keybindings import KeyBindingsScreen from .keymodal import KeyModal
class NotifyValidationError(Exception): class NotifyValidationError(Exception):
@ -113,7 +113,7 @@ class TableEditor(App):
def __init__(self, default_view="default"): def __init__(self, default_view="default"):
super().__init__() super().__init__()
self.filters = {} self.filters = {}
self.sort_string = "due,status" self.sort_string = "" # TODO: default sort
self._load_view(default_view) self._load_view(default_view)
self.search_query = "" self.search_query = ""
self.saved_cursor_pos = (1, 0) self.saved_cursor_pos = (1, 0)
@ -192,20 +192,23 @@ class TableEditor(App):
if self.table.cursor_column == 0: if self.table.cursor_column == 0:
cur_row = self.table.cursor_row cur_row = self.table.cursor_row
item_id = int(self.table.get_cell_at((cur_row, 0))) item_id = int(self.table.get_cell_at((cur_row, 0)))
# TODO: deletable items need a delete
self.update_item_callback(item_id, deleted=True) self.update_item_callback(item_id, deleted=True)
self._save_cursor() self._save_cursor()
self.refresh_data() self.refresh_data()
def action_add_item(self): def action_add_item(self):
# if filtering on type, status, or category # the new item should use the selected value if filtered
# the new item should use the selected value
# prepopulate with either the field default or the current filter # prepopulate with either the field default or the current filter
prepopulated = { prepopulated = {}
field.name: self.filters.get(field.name, field.default) for fc in self.TABLE_CONFIG:
for field in self.TABLE_CONFIG val = self.filters.get(fc.field, fc.default)
} if val is not None:
# TODO: need to split type_ and status # enums use comma separated filters
if fc.enum:
prepopulated[fc.field] = val.split(",")[0]
else:
prepopulated[fc.field] = val
new_item = self.add_item_callback(**prepopulated) new_item = self.add_item_callback(**prepopulated)
self.refresh_data(restore_cursor=False) self.refresh_data(restore_cursor=False)
@ -232,6 +235,7 @@ class TableEditor(App):
# trigger item_id to be saved on the next cursor move # trigger item_id to be saved on the next cursor move
# this avoids filtered columns disappearing right away # this avoids filtered columns disappearing right away
# and tons of DB writes # and tons of DB writes
# TODO: status hard coded here
self._register_save_on_move(item_id, status=next_val) self._register_save_on_move(item_id, status=next_val)
def _register_save_on_move(self, item_id, **kwargs): def _register_save_on_move(self, item_id, **kwargs):
@ -245,7 +249,6 @@ class TableEditor(App):
self.update_item_callback(**self.save_on_move) self.update_item_callback(**self.save_on_move)
self._save_cursor() self._save_cursor()
self.refresh_data() self.refresh_data()
# reset status
self.save_on_move = None self.save_on_move = None
def move_cursor_to_item(self, item_id): def move_cursor_to_item(self, item_id):
@ -285,7 +288,7 @@ class TableEditor(App):
cconf = self._active_column_config() cconf = self._active_column_config()
if cconf.filterable: if cconf.filterable:
return return
cur_filter_val = self.filters.get(cconf.name) or "" cur_filter_val = self.filters.get(cconf.field) or ""
self._show_input("filter", cur_filter_val) self._show_input("filter", cur_filter_val)
self.table.cursor_type = "column" self.table.cursor_type = "column"
@ -299,7 +302,7 @@ class TableEditor(App):
if self.table.cursor_row is None or self.table.cursor_column == 0: if self.table.cursor_row is None or self.table.cursor_column == 0:
return return
self._save_crefresh_data() self._save_cursor()
current_value = self.table.get_cell_at( current_value = self.table.get_cell_at(
(self.table.cursor_row, self.table.cursor_column) (self.table.cursor_row, self.table.cursor_column)
) )
@ -334,7 +337,7 @@ class TableEditor(App):
self.refresh_data(restore_cursor=False) self.refresh_data(restore_cursor=False)
elif self.mode == "filter": elif self.mode == "filter":
cconf = self._active_column_config() cconf = self._active_column_config()
self.filters[cconf.name] = event.value self.filters[cconf.field] = event.value
self.refresh_data(restore_cursor=False) self.refresh_data(restore_cursor=False)
self.table.cursor_type = "cel" self.table.cursor_type = "cel"
elif self.mode == "sort": elif self.mode == "sort":
@ -350,12 +353,13 @@ class TableEditor(App):
row, col = self.saved_cursor_pos row, col = self.saved_cursor_pos
item_id = int(self.table.get_cell_at((row, 0))) item_id = int(self.table.get_cell_at((row, 0)))
cconf = self.TABLE_CONFIG[col] cconf = self.TABLE_CONFIG[col]
field = cconf.name field = cconf.field
update_data = {} update_data = {}
# preprocess/validate the field being saved # preprocess/validate the field being saved
try: try:
update_data[field] = cconf.preprocess(new_value) update_data[field] = cconf.preprocessor(new_value)
# raise Exception(update_data)
self.update_item_callback(item_id, **update_data) self.update_item_callback(item_id, **update_data)
self.refresh_data() self.refresh_data()
except NotifyValidationError as e: except NotifyValidationError as e:
@ -367,4 +371,4 @@ class TableEditor(App):
self.action_cancel_edit() self.action_cancel_edit()
def action_show_keys(self): def action_show_keys(self):
self.push_screen(KeyBindingsScreen()) self.push_screen(KeyModal())

View File

@ -3,7 +3,7 @@ from rich.table import Table
from textual.widgets import Static from textual.widgets import Static
class KeyBindingsScreen(ModalScreen): class KeyModal(ModalScreen):
CSS = """ CSS = """
KeyBindingsScreen { KeyBindingsScreen {
align: center middle; align: center middle;

View File

@ -2,7 +2,7 @@ import json
from textual.widgets import Input from textual.widgets import Input
from datetime import datetime from datetime import datetime
from .controller import ( from ..controller import (
get_task, get_task,
get_tasks, get_tasks,
add_task, add_task,
@ -11,13 +11,12 @@ from .controller import (
save_view, save_view,
get_saved_view, get_saved_view,
) )
from .db import initialize_db from ..utils import (
from .utils import (
get_colored_category, get_colored_category,
get_colored_status, get_colored_status,
get_colored_date, get_colored_date,
) )
from .tui_editor import ( from .editor import (
TableEditor, TableEditor,
TableColumnConfig, TableColumnConfig,
NotifyValidationError, NotifyValidationError,
@ -56,9 +55,6 @@ class TT(TableEditor):
TableColumnConfig("due", "Due", default="", preprocessor=due_preprocessor), TableColumnConfig("due", "Due", default="", preprocessor=due_preprocessor),
TableColumnConfig("category", "Category", default="main"), TableColumnConfig("category", "Category", default="main"),
) )
update_item_callback = update_task
update_item_callback = add_task
get_item_callback = get_task
BINDINGS = [ BINDINGS = [
# saved views # saved views
@ -69,6 +65,9 @@ class TT(TableEditor):
def __init__(self, default_view="default"): def __init__(self, default_view="default"):
super().__init__() super().__init__()
self._load_view(default_view) self._load_view(default_view)
self.update_item_callback = update_task
self.add_item_callback = add_task
self.get_item_callback = get_task
def _load_view(self, name): def _load_view(self, name):
try: try:
@ -123,7 +122,6 @@ class TT(TableEditor):
def run(default_view): def run(default_view):
initialize_db()
app = TT(default_view) app = TT(default_view)
app.run() app.run()