fix date modal

This commit is contained in:
jpt 2025-04-13 11:05:25 -05:00
parent 74ed6516b4
commit 547a65e19f
5 changed files with 56 additions and 33 deletions

View File

@ -84,8 +84,8 @@ def get_tasks(
query = query.where(fn.Lower(Task.text).contains(search_text.lower()))
if statuses:
query = query.where(Task.status.in_(statuses))
#if projects:
# query = query.where(Task.project.in_(projects))
if projects:
query = query.where(Task.project.in_(projects))
sort_expressions = _parse_sort_string(sort, statuses)
query = query.order_by(*sort_expressions)

View File

@ -83,7 +83,7 @@ class EnumColumnConfig(TableColumnConfig):
class DateColumnConfig(TableColumnConfig):
def preprocess(self, val):
try:
return datetime.strptime(val, "%Y-%m-%d")
return datetime.datetime.strptime(val, "%Y-%m-%d")
except ValueError:
raise NotifyValidationError("Invalid date format. Use YYYY-MM-DD")

View File

@ -37,6 +37,7 @@ class KeyModal(ModalScreen):
for binding in self.app.BINDINGS:
if binding[0] not in ["h", "j", "k", "l", "g", "G", "escape"]:
table.add_row(binding[0], binding[2])
# TODO: MRO?
yield Static("tt keybindings", classes="title")
yield Static(table)

View File

@ -1,9 +1,10 @@
import datetime
from textual.screen import ModalScreen
from textual.binding import Binding
from textual.widgets import RadioSet, RadioButton, Label
from .. import config
from textual.widgets import Label
from ..utils import get_color_enum
class ConfirmModal(ModalScreen):
CSS = """
ConfirmModal {
@ -42,42 +43,56 @@ class ChoiceModal(ModalScreen):
ChoiceModal Label {
height: 1;
}
ChoiceModal Label#selected {
background: white;
}
"""
BINDINGS = [
("j,tab", "cursor_down", "Down"),
("k", "cursor_up", "Up"),
Binding("enter", "select", "Select", priority=False),
("k,shift+tab", "cursor_up", "Up"),
Binding("enter", "select", "Select", priority=True),
("escape", "cancel", "cancel"),
]
def __init__(self, enum, selected):
self._enum = enum
self.selected = selected
self.enum_by_idx = list(self._enum)
# selection index
self.sel_idx = 0
# convert value back to index for initial selection
for idx, e in enumerate(self._enum):
if e.value == selected:
self.sel_idx = idx
break
super().__init__()
def compose(self):
yield RadioSet(
*[
RadioButton(
get_color_enum(e.value, config.STATUSES), value=self.selected == str(e.value)
)
for e in self._enum
]
for idx, e in enumerate(self._enum):
yield Label(
("> " if idx == self.sel_idx else " ") +
get_color_enum(e.value, self._enum),
classes="selected" if idx == self.sel_idx else "",
)
def _move_cursor(self, dir):
labels = self.query(Label)
# reset old
labels[self.sel_idx].update(" " + get_color_enum(self.enum_by_idx[self.sel_idx], self._enum))
# move cursor
self.sel_idx = (self.sel_idx + dir) % len(self._enum)
# reset new
labels[self.sel_idx].update("> " + get_color_enum(self.enum_by_idx[self.sel_idx], self._enum))
def action_cursor_down(self):
self.query_one(RadioSet).action_next_button()
self._move_cursor(1)
def action_cursor_up(self):
self.query_one(RadioSet).action_previous_button()
self._move_cursor(-1)
def action_select(self):
rs = self.query_one(RadioSet)
# TODO: this doesn't work
#rs.action_toggle_button()
pressed = rs.pressed_button
self.dismiss(str(pressed.label))
async def action_select(self):
self.dismiss(self.enum_by_idx[self.sel_idx])
def action_cancel(self):
self.app.pop_screen()
@ -101,14 +116,18 @@ class DateModal(ModalScreen):
BINDINGS = [
("j", "cursor_down", "Down"),
("k", "cursor_up", "Up"),
("h,tab", "cursor_left", "Left"),
("l", "cursor_right", "Right"),
("h,shift+tab", "cursor_left", "Left"),
("l,tab", "cursor_right", "Right"),
Binding("enter", "select", "Select", priority=True),
("escape", "cancel", "cancel"),
]
def __init__(self, date):
if date:
self.pieces = [int(p) for p in date.split("-")]
else:
today = datetime.date.today()
self.pieces = [today.year, today.month, today.day]
self.selected = 1 # start on month
super().__init__()
@ -178,8 +197,7 @@ class DateModal(ModalScreen):
event.prevent_default()
def action_select(self):
date = "-".join(str(p) for p in self.pieces)
self.dismiss(date)
self.dismiss("-".join(str(p) for p in self.pieces))
def action_cancel(self):
self.app.pop_screen()

View File

@ -56,10 +56,8 @@ class TT(TableEditor):
def refresh_items(self):
items = get_tasks(
self.search_query,
projects=self.filters.get("project", "").split(","),
statuses=self.filters.get("status", "").split(",")
if "status" in self.filters
else None,
projects=self._filters_to_list("project"),
statuses=self._filters_to_list("status"),
sort=self.sort_string,
)
for item in items:
@ -68,6 +66,12 @@ class TT(TableEditor):
key=str(item.id),
)
def _filters_to_list(self, key):
filters = self.filters.get(key)
if filters:
return filters.split(",")
else:
return None
def run(default_view):
app = TT(default_view)