From ce80e004cbd83ff011b144b6a284a9ea9f0c85cb Mon Sep 17 00:00:00 2001 From: James Turk Date: Sat, 4 Jan 2025 00:02:20 -0600 Subject: [PATCH] filtering on category --- src/tt/tui.py | 70 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/src/tt/tui.py b/src/tt/tui.py index dc3870c..0a706cd 100644 --- a/src/tt/tui.py +++ b/src/tt/tui.py @@ -7,7 +7,6 @@ from datetime import datetime from .controller import get_tasks, add_task, update_task, TaskStatus from .db import initialize_db -# TODO: add footer w/ filter status # TODO: toggle status with 't' # TODO: add way to filter on other columns # TODO: safe DB mode @@ -49,8 +48,11 @@ def get_colored_category(category: str) -> str: class TT(App): CSS = """ - #input_bar { + #footer { dock: bottom; + max-height: 2; + } + #input_bar { height: 2; border-top: solid green; layout: grid; @@ -58,7 +60,7 @@ class TT(App): grid-columns: 10 1fr; display: none; } - + #prompt_label { width: 10; content-align: left middle; @@ -69,6 +71,26 @@ class TT(App): margin: 0; border: none; } + + #status_bar { + border-top: solid white; + height: 2; + margin: 0; + layout: grid; + grid-size: 2; + } + + #left_status { + height: 1; + margin: 0; + padding-left: 1; + } + #right_status { + height: 1; + margin: 0; + padding-right: 1; + text-align: right; + } """ BINDINGS = [ @@ -81,6 +103,7 @@ class TT(App): ("G", "cursor_bottom", "Bottom"), # filtering & editing ("/", "start_search", "Search"), + ("f", "start_filter", "Filter"), ("c", "start_edit", "Edit Cell"), ("escape", "cancel_edit", "Cancel Edit"), # other @@ -92,6 +115,7 @@ class TT(App): def __init__(self): super().__init__() self.search_query = "" + self.search_category = "" self.saved_cursor_pos = (0, 0) def compose(self): @@ -100,11 +124,18 @@ class TT(App): self.input_widget = Input(id="input_widget") self.input_label = Static("label", id="prompt_label") self.input_bar = Container(id="input_bar") + self.status_bar = Container(id="status_bar") + self.left_status = Static("LEFT", id="left_status") + self.right_status = Static("RIGHT", id="right_status") yield self.header yield Container(self.table) - with self.input_bar: - yield self.input_label - yield self.input_widget + with Container(id="footer"): + with self.input_bar: + yield self.input_label + yield self.input_widget + with self.status_bar: + yield self.left_status + yield self.right_status def on_mount(self): self.table.add_columns("ID", "Task", "Status", "Type", "Due", "Category") @@ -133,9 +164,10 @@ class TT(App): self.table.move_cursor(row=self.table.row_count - 1) def refresh_tasks(self, *, restore_cursor=True): + # show table self.table.clear() - tasks = get_tasks(self.search_query) + tasks = get_tasks(self.search_query, category=self.search_category) for task in tasks: due_str = task.due.strftime("%Y-%m-%d") if task.due else " - " category = get_colored_category( @@ -152,6 +184,16 @@ class TT(App): category, key=str(task.id), ) + + # update footer + if self.search_query: + self.left_status.update( + f"{len(tasks)} |{' ' if self.search_category else ''}{self.search_category} matching '{self.search_query}'" + ) + else: + self.left_status.update(f"{len(tasks)} | {self.search_category}") + + # restore cursor if restore_cursor: self.table.move_cursor( row=self.saved_cursor_pos[0], column=self.saved_cursor_pos[1] @@ -195,8 +237,12 @@ class TT(App): self.input_widget.value = start_value if mode == "search": self.input_label.update("search: ") - else: + elif mode == "edit": self.input_label.update("edit: ") + elif mode == "filter": + self.input_label.update("filter: ") + else: + raise ValueError(f"unknown mode: {mode}") self.set_focus(self.input_widget) def _hide_input(self): @@ -209,6 +255,9 @@ class TT(App): def action_start_search(self): self._show_input("search", "") + def action_start_filter(self): + self._show_input("filter", self.search_category) + def _save_cursor(self): self.saved_cursor_pos = (self.table.cursor_row, self.table.cursor_column) @@ -227,8 +276,13 @@ class TT(App): if self.mode == "search": self.search_query = event.value self.refresh_tasks(restore_cursor=False) + elif self.mode == "filter": + self.search_category = event.value + self.refresh_tasks(restore_cursor=False) elif self.mode == "edit": self.apply_change(event.value) + else: + raise ValueError(f"unknown mode: {self.mode}") self._hide_input() def apply_change(self, new_value):