improved overview

This commit is contained in:
James Turk 2025-02-10 20:04:31 -06:00
parent ccd0178de1
commit 9de289d43b
3 changed files with 53 additions and 46 deletions

View File

@ -5,8 +5,9 @@ from typing_extensions import Annotated
from .controller.tasks import add_task
from .import_csv import import_tasks_from_csv
from .db import initialize_db
from .tui import tasks
from .tui import recurring
from .tui.tasks import run as tasks_tui
from .tui.overview import run as overview_tui
from .tui.recurring import run as recurring_tui
app = typer.Typer()
@ -42,17 +43,23 @@ def new(
@app.command()
def browse(
def tasks(
view: Annotated[str, typer.Option("-v", "--view", help="saved view")] = "default",
):
initialize_db()
tasks.run(view)
tasks_tui(view)
@app.command()
def generators():
initialize_db()
recurring.run()
recurring_tui()
@app.command()
def overview():
initialize_db()
overview_tui()
@app.command()

View File

@ -140,28 +140,31 @@ def get_due_soon(
"""
now = datetime.now()
# Base query
# unfinished tasks w/ due date
query = (
Task.select(Task, Category.name.alias("category_name"))
Task.select(Task)
.join(Category, JOIN.LEFT_OUTER)
.where(
(~Task.deleted)
& (Task.due.is_null(False))
& (Task.due != "")
& (Task.status != TaskStatus.DONE.value)
)
)
# filter by category
if category:
query = query.where(Category.name == category)
# Handle overdue tasks based on all_overdue parameter
if all_overdue:
# grab all overdue & append a few more on
overdue_tasks = list(query.where(Task.due < now).order_by(Task.due))
upcoming_tasks = list(
query.where(Task.due >= now).order_by(Task.due).limit(num)
)
tasks = overdue_tasks + upcoming_tasks
else:
# just most due tasks
tasks = list(query.order_by(Task.due).limit(num))
return [

View File

@ -1,6 +1,6 @@
from textual.app import App, ComposeResult
from textual.containers import ScrollableContainer, Horizontal
from textual.widgets import DataTable, Static
from textual.widgets import DataTable, Static, Label
from textual.binding import Binding
from datetime import datetime
@ -10,6 +10,16 @@ from ..controller.summaries import (
get_due_soon,
)
####
# Due Soon # Task Summary
# #
# #
##################################
# WIP # Recently active
# #
# #
# #
class CategoryTable(DataTable):
"""Table showing category summaries"""
@ -35,54 +45,46 @@ class CategoryTable(DataTable):
)
class TaskList(DataTable):
"""Base class for task list tables"""
def on_mount(self):
self.add_columns("Task", "Status", "Category", "Due Date")
def format_due_date(self, due_date: datetime | None) -> str:
if not due_date:
return "No due date"
return due_date.strftime("%Y-%m-%d")
def format_due_date(due_date: datetime | None) -> str:
if not due_date:
return "No due date"
return due_date.strftime("%Y-%m-%d")
class DueTaskList(TaskList):
class DueTaskList(DataTable):
"""Table showing upcoming and overdue tasks"""
def on_mount(self):
super().on_mount()
self.add_columns("Task", "Category", "Due Date")
self.refresh_data()
def refresh_data(self):
self.clear()
tasks = get_due_soon(10, all_overdue=True) # Show all overdue + next 10
tasks = get_due_soon(10, all_overdue=True)
for task in tasks:
self.add_row(
task["text"],
task["status"],
task["category"] or "No category",
self.format_due_date(task["due"]),
task["category"],
format_due_date(task["due"]),
key=str(task["id"]),
)
class RecentTaskList(TaskList):
class RecentTaskList(DataTable):
"""Table showing recently active tasks"""
def on_mount(self):
super().on_mount()
self.add_columns("Task", "Category", "Due Date")
self.refresh_data()
def refresh_data(self):
self.clear()
tasks = get_recently_active(10) # Show 10 most recent
tasks = get_recently_active(10)
for task in tasks:
self.add_row(
task["text"],
task["status"],
task["category"] or "No category",
self.format_due_date(task["due"]),
task["category"] or "-",
format_due_date(task["due"]),
key=str(task["id"]),
)
@ -90,27 +92,20 @@ class RecentTaskList(TaskList):
class Overview(App):
"""Task overview application"""
TITLE = "Task Overview"
CSS = """
CategoryTable {
height: 40%;
margin: 1 1;
}
Label {
align: center middle;
background: purple;
}
#lists {
height: 60%;
}
TaskList {
width: 50%;
margin: 1 1;
}
Static {
content-align: center middle;
background: $panel;
padding: 1;
}
"""
BINDINGS = [
@ -119,12 +114,14 @@ class Overview(App):
]
def compose(self) -> ComposeResult:
yield CategoryTable()
yield Static("Upcoming and Recent Tasks")
with Horizontal(id="top"):
yield CategoryTable()
with Horizontal(id="lists"):
with ScrollableContainer():
yield Label("Due Soon")
yield DueTaskList()
with ScrollableContainer():
yield Label("Activity")
yield RecentTaskList()
def action_refresh(self):
@ -134,6 +131,6 @@ class Overview(App):
self.query_one(RecentTaskList).refresh_data()
if __name__ == "__main__":
def run():
app = Overview()
app.run()