from datetime import datetime from peewee import JOIN, fn from textual.binding import Binding from textual.coordinate import Coordinate from textual.widgets import DataTable from hamstertools.db import HamsterActivity, HamsterCategory, HamsterFact from hamstertools.screens.list import ListPane class CategoryList(ListPane): BINDINGS = [ ("s", "sort", "Sort"), ("r", "refresh", "Refresh"), ("/", "filter", "Search"), ("d", "delete", "Delete category"), Binding(key="escape", action="cancelfilter", show=False), ] def _refresh(self): self.table.clear() categories = ( HamsterCategory.select( HamsterCategory, fn.Count(HamsterActivity.id).alias("activities_count"), HamsterFact.start_time, ) .join(HamsterActivity, JOIN.LEFT_OUTER) .join(HamsterFact, JOIN.LEFT_OUTER) .group_by(HamsterCategory) ) filter_search = self.query_one("#filter #search").value if filter_search is not None: categories = categories.where(HamsterCategory.name.contains(filter_search)) filter_date = self.query_one("#filter #date").value if filter_date is not None: try: categories = categories.where( HamsterFact.start_time > datetime.strptime(filter_date, "%Y-%m-%d") ) except ValueError: pass self.table.add_rows( [ [ category.id, category.name, category.activities_count, ] for category in categories ] ) self.table.sort(self.sort) def on_mount(self) -> None: self.table = self.query_one(DataTable) self.table.cursor_type = "row" self.columns = self.table.add_columns("category id", "category", "activities") self.sort = self.columns[1] self._refresh() def action_delete(self) -> None: row_key, _ = self.table.coordinate_to_cell_key(self.table.cursor_coordinate) category_id = self.table.get_cell_at( Coordinate(self.table.cursor_coordinate.row, 0), ) category = HamsterCategory.get(id=category_id) category.delete_instance() self.table.remove_row(row_key)