filtering

This commit is contained in:
James Turk 2025-01-04 02:35:25 -06:00
parent cd112d0b4c
commit 34220a5ea6
2 changed files with 42 additions and 15 deletions

View File

@ -14,6 +14,7 @@ from .controller import get_tasks, add_task, update_task, TaskStatus
from .db import initialize_db
from .utils import (
remove_rich_tag,
filter_to_string,
advance_enum_val,
get_colored_category,
get_colored_status,
@ -21,7 +22,6 @@ from .utils import (
)
# Parity
# TODO: add filtering on status
# TODO: saved searches
# Nice to Have
# TODO: CLI
@ -32,11 +32,12 @@ from .utils import (
COLUMNS = ("ID", "Task", "Status", "Type", "Due", "Category")
column_to_field = {
0: "ID",
1: "text",
2: "status",
3: "type",
4: "due",
5: "category_name",
5: "category",
}
@ -113,7 +114,7 @@ class TT(App):
def __init__(self):
super().__init__()
self.search_query = ""
self.search_category = ""
self.filters = {}
self.sort_string = "due,status"
self.saved_cursor_pos = (0, 0)
self.save_on_move = None
@ -174,7 +175,12 @@ class TT(App):
self.table.clear()
tasks = get_tasks(
self.search_query, category=self.search_category, sort=self.sort_string
self.search_query,
category=self.filters.get("category"),
statuses=self.filters.get("status", "").split(",")
if "status" in self.filters
else None,
sort=self.sort_string,
)
for task in tasks:
category = get_colored_category(
@ -194,12 +200,8 @@ class TT(App):
)
# 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}")
filter_display = filter_to_string(self.filters, self.search_query)
self.left_status.update(f"{len(tasks)} |{filter_display}")
# restore cursor
if restore_cursor:
@ -288,12 +290,21 @@ class TT(App):
def action_cancel_edit(self):
self._hide_input()
self.table.cursor_type = "cell"
def action_start_search(self):
self._show_input("search", "")
def action_start_filter(self):
self._show_input("filter", self.search_category)
# filter the currently selected column
cur_col = self.table.cursor_column
active_col_name = column_to_field[cur_col]
# # only allow filtering these columns
if active_col_name not in ("status", "type", "due", "category"):
return
cur_filter_val = self.filters.get(active_col_name) or ""
self._show_input("filter", cur_filter_val)
self.table.cursor_type = "column"
def action_start_sort(self):
self._show_input("sort", self.sort_string)
@ -317,8 +328,11 @@ class TT(App):
self.search_query = event.value
self.refresh_tasks(restore_cursor=False)
elif self.mode == "filter":
self.search_category = event.value
cur_col = self.table.cursor_column
active_col_name = column_to_field[cur_col]
self.filters[active_col_name] = event.value
self.refresh_tasks(restore_cursor=False)
self.table.cursor_type = "cel"
elif self.mode == "sort":
self.sort_string = event.value
self.refresh_tasks(restore_cursor=False)
@ -356,6 +370,7 @@ class TT(App):
except Exception as e:
self.notify(f"Error updating task: {str(e)}")
finally:
# no longer in edit mode
self.action_cancel_edit()
def action_show_keys(self):

View File

@ -1,6 +1,18 @@
import re
import datetime
from rich.text import Text
def filter_to_string(filters, search_query):
pieces = []
category = filters.get("category")
status = filters.get("status")
if category:
pieces += [f" category:{category}"]
if status:
pieces += [f" status:{status}"]
if search_query:
pieces += [f" search:'{search_query}"]
return "".join(pieces)
def remove_rich_tag(text):
@ -40,14 +52,14 @@ def get_colored_date(date: datetime.date) -> str:
as_str = date.strftime("%Y-%m-%d")
today = datetime.date.today()
if date.date() < today:
return Text(as_str, style="black on red")
return f"[#eeeeee on #dd1111]{as_str}[/]"
else:
# Calculate weeks into future
delta = date.date() - today
weeks = delta.days // 7
colors = [
"#FF4000",
# "#FF4000",
"#FF8000",
"#FFA533",
"#FFD24D",