Working categories page

This commit is contained in:
3wc 2023-10-27 02:26:15 +01:00
parent a0cdf945bf
commit dc30727c62
1 changed files with 145 additions and 30 deletions

View File

@ -1,16 +1,15 @@
from textual.app import App, ComposeResult from textual.app import App, ComposeResult
from textual.widgets import Header, Footer, DataTable from textual.widgets import Header, Footer, DataTable, Placeholder
from textual.coordinate import Coordinate from textual.coordinate import Coordinate
from textual.screen import Screen
class HamsterToolsApp(App): class ActivitiesScreen(Screen):
"""A Textual app to manage stopwatches."""
BINDINGS = [ BINDINGS = [
("q", "quit", "Quit"), ("q", "quit", "Quit"),
("s", "sort", "Sort"), ("s", "sort", "Sort"),
("r", "refresh", "Refresh"), ("r", "refresh", "Refresh"),
("d", "delete_activity", "Delete activity"), ("d", "delete", "Delete activity"),
] ]
def __init__(self, db_cursor, db_connection): def __init__(self, db_cursor, db_connection):
@ -22,28 +21,28 @@ class HamsterToolsApp(App):
self.table.clear() self.table.clear()
sql = ''' sql = '''
SELECT select
categories.id AS category_id, categories.id as category_id,
COALESCE(categories.name, '') AS category_name, coalesce(categories.name, '') as category_name,
activities.id AS activity_id, activities.id as activity_id,
activities.name AS activity_name, activities.name as activity_name,
COALESCE(facts_count, 0) AS total_facts coalesce(facts_count, 0) as total_facts
FROM from
activities activities
LEFT JOIN left join
categories categories
ON on
activities.category_id = categories.id activities.category_id = categories.id
LEFT JOIN ( left join (
SELECT select
activity_id, activity_id,
COUNT(*) AS facts_count count(*) as facts_count
FROM from
facts facts
GROUP BY group by
activity_id activity_id
) AS facts_count_subquery ) as facts_count_subquery
ON on
activities.id = facts_count_subquery.activity_id; activities.id = facts_count_subquery.activity_id;
''' '''
@ -54,7 +53,7 @@ class HamsterToolsApp(App):
self.table.sort(self.columns[1], self.columns[3]) self.table.sort(self.columns[1], self.columns[3])
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
"""Create child widgets for the app.""" """create child widgets for the app."""
yield Header() yield Header()
yield DataTable() yield DataTable()
yield Footer() yield Footer()
@ -62,36 +61,152 @@ class HamsterToolsApp(App):
def on_mount(self) -> None: def on_mount(self) -> None:
self.table = self.query_one(DataTable) self.table = self.query_one(DataTable)
self.table.cursor_type = "row" self.table.cursor_type = "row"
self.columns = self.table.add_columns("category id","category","activity ID","activity","entries") self.columns = self.table.add_columns("category id","category","activity id","activity","entries")
self._refresh() self._refresh()
def action_quit(self) -> None:
self.exit()
def action_refresh(self) -> None: def action_refresh(self) -> None:
self._refresh() self._refresh()
def action_sort(self) -> None: def action_sort(self) -> None:
self.table.cursor_type = "column" self.table.cursor_type = "column"
def action_delete_activity(self) -> None: def action_delete(self) -> None:
# Get the keys for the row and column under the cursor. # get the keys for the row and column under the cursor.
row_key, _ = self.table.coordinate_to_cell_key(self.table.cursor_coordinate) row_key, _ = self.table.coordinate_to_cell_key(self.table.cursor_coordinate)
activity_id = self.table.get_cell_at( activity_id = self.table.get_cell_at(
Coordinate(self.table.cursor_coordinate.row, 2), Coordinate(self.table.cursor_coordinate.row, 2),
) )
sql = 'DELETE FROM activities WHERE id = ?' sql = 'delete from activities where id = ?'
print(Coordinate(2, self.table.cursor_coordinate.row),) print(Coordinate(2, self.table.cursor_coordinate.row),)
print(activity_id) print(activity_id)
self.db_cursor.execute(sql, (activity_id,)) self.db_cursor.execute(sql, (activity_id,))
self.db_connection.commit() self.db_connection.commit()
# Supply the row key to `remove_row` to delete the row. # supply the row key to `remove_row` to delete the row.
self.table.remove_row(row_key) self.table.remove_row(row_key)
def on_data_table_column_selected(self, event): def on_data_table_column_selected(self, event):
event.data_table.sort(event.column_key) event.data_table.sort(event.column_key)
event.data_table.cursor_type = "row" event.data_table.cursor_type = "row"
class CategoriesScreen(Screen):
BINDINGS = [
("s", "sort", "Sort"),
("r", "refresh", "Refresh"),
("d", "delete", "Delete category"),
]
def __init__(self, db_cursor, db_connection):
self.db_cursor = db_cursor
self.db_connection = db_connection
super().__init__()
def _refresh(self):
self.table.clear()
sql = '''
select
categories.id as category_id,
coalesce(categories.name, '') as category_name,
coalesce(activities_count, 0) as total_activities
from
categories
left join (
select
category_id,
count(*) as activities_count
from
activities
group by
category_id
) as activities_count_subquery
on
categories.id = activities_count_subquery.category_id;
'''
results = self.db_cursor.execute(sql)
# results = [[cell or "" for cell in row] for row in self.db_cursor.fetchall()]
self.table.add_rows(results)
self.table.sort(self.columns[1])
def compose(self) -> ComposeResult:
"""create child widgets for the app."""
yield Header()
yield DataTable()
yield Footer()
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._refresh()
def action_refresh(self) -> None:
self._refresh()
def action_sort(self) -> None:
self.table.cursor_type = "column"
def action_delete(self) -> None:
# get the keys for the row and column under the cursor.
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),
)
sql = 'delete from categories where id = ?'
print(Coordinate(2, self.table.cursor_coordinate.row),)
print(category_id)
self.db_cursor.execute(sql, (category_id,))
self.db_connection.commit()
# supply the row key to `remove_row` to delete the row.
self.table.remove_row(row_key)
def on_data_table_column_selected(self, event):
event.data_table.sort(event.column_key)
event.data_table.cursor_type = "row"
# class KimaiScreen(Screen):
# def compose(self) -> ComposeResult:
# yield Placeholder("Help Screen")
# yield Footer()
#
# def __init__(self, db_cursor, db_connection):
# self.db_cursor = db_cursor
# self.db_connection = db_connection
# super().__init__()
class HamsterToolsApp(App):
BINDINGS = [
("a", "switch_mode('activities')", "Activities"),
("c", "switch_mode('categories')", "Categories"),
# ("k", "switch_mode('kimai')", "Kimai"),
("q", "quit", "Quit"),
]
def __init__(self, db_cursor, db_connection):
self.db_cursor = db_cursor
self.db_connection = db_connection
self.MODES = {
"categories": CategoriesScreen(db_cursor, db_connection),
"activities": ActivitiesScreen(db_cursor, db_connection),
# "kimai": KimaiScreen,
}
super().__init__()
def on_mount(self) -> None:
self.switch_mode("activities")
def action_quit(self) -> None:
self.exit()