Initial commit
This commit is contained in:
120
routers/eisenhower.py
Normal file
120
routers/eisenhower.py
Normal file
@@ -0,0 +1,120 @@
|
||||
"""Eisenhower Matrix: read-only 2x2 priority/urgency grid of open tasks."""
|
||||
|
||||
from fastapi import APIRouter, Request, Depends
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import text
|
||||
from typing import Optional
|
||||
|
||||
from core.database import get_db
|
||||
from core.base_repository import BaseRepository
|
||||
from core.sidebar import get_sidebar_data
|
||||
|
||||
router = APIRouter(prefix="/eisenhower", tags=["eisenhower"])
|
||||
templates = Jinja2Templates(directory="templates")
|
||||
|
||||
|
||||
@router.get("/")
|
||||
async def eisenhower_matrix(
|
||||
request: Request,
|
||||
domain_id: Optional[str] = None,
|
||||
project_id: Optional[str] = None,
|
||||
status: Optional[str] = None,
|
||||
context: Optional[str] = None,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
sidebar = await get_sidebar_data(db)
|
||||
|
||||
where_clauses = [
|
||||
"t.is_deleted = false",
|
||||
"t.status IN ('open', 'in_progress', 'blocked')",
|
||||
]
|
||||
params = {}
|
||||
|
||||
if domain_id:
|
||||
where_clauses.append("t.domain_id = :domain_id")
|
||||
params["domain_id"] = domain_id
|
||||
if project_id:
|
||||
where_clauses.append("t.project_id = :project_id")
|
||||
params["project_id"] = project_id
|
||||
if status:
|
||||
where_clauses.append("t.status = :status")
|
||||
params["status"] = status
|
||||
if context:
|
||||
where_clauses.append("t.context = :context")
|
||||
params["context"] = context
|
||||
|
||||
where_sql = " AND ".join(where_clauses)
|
||||
|
||||
result = await db.execute(text(f"""
|
||||
SELECT t.id, t.title, t.priority, t.status, t.due_date,
|
||||
t.context, t.estimated_minutes,
|
||||
p.name as project_name,
|
||||
d.name as domain_name, d.color as domain_color
|
||||
FROM tasks t
|
||||
LEFT JOIN projects p ON t.project_id = p.id
|
||||
LEFT JOIN domains d ON t.domain_id = d.id
|
||||
WHERE {where_sql}
|
||||
ORDER BY t.priority, t.due_date NULLS LAST, t.title
|
||||
"""), params)
|
||||
tasks = [dict(r._mapping) for r in result]
|
||||
|
||||
# Classify into quadrants
|
||||
from datetime import date, timedelta
|
||||
today = date.today()
|
||||
urgent_cutoff = today + timedelta(days=7)
|
||||
|
||||
quadrants = {
|
||||
"do_first": [],
|
||||
"schedule": [],
|
||||
"delegate": [],
|
||||
"eliminate": [],
|
||||
}
|
||||
|
||||
for t in tasks:
|
||||
important = t["priority"] in (1, 2)
|
||||
urgent = (
|
||||
t["due_date"] is not None
|
||||
and t["due_date"] <= urgent_cutoff
|
||||
)
|
||||
|
||||
if important and urgent:
|
||||
quadrants["do_first"].append(t)
|
||||
elif important and not urgent:
|
||||
quadrants["schedule"].append(t)
|
||||
elif not important and urgent:
|
||||
quadrants["delegate"].append(t)
|
||||
else:
|
||||
quadrants["eliminate"].append(t)
|
||||
|
||||
counts = {k: len(v) for k, v in quadrants.items()}
|
||||
total = sum(counts.values())
|
||||
|
||||
# Filter options
|
||||
domains_repo = BaseRepository("domains", db)
|
||||
domains = await domains_repo.list()
|
||||
projects_repo = BaseRepository("projects", db)
|
||||
projects = await projects_repo.list()
|
||||
|
||||
result = await db.execute(text(
|
||||
"SELECT value, label FROM context_types WHERE is_deleted = false ORDER BY sort_order"
|
||||
))
|
||||
context_types = [dict(r._mapping) for r in result]
|
||||
|
||||
return templates.TemplateResponse("eisenhower.html", {
|
||||
"request": request,
|
||||
"sidebar": sidebar,
|
||||
"quadrants": quadrants,
|
||||
"counts": counts,
|
||||
"total": total,
|
||||
"today": today,
|
||||
"domains": domains,
|
||||
"projects": projects,
|
||||
"context_types": context_types,
|
||||
"current_domain_id": domain_id or "",
|
||||
"current_project_id": project_id or "",
|
||||
"current_status": status or "",
|
||||
"current_context": context or "",
|
||||
"page_title": "Eisenhower Matrix",
|
||||
"active_nav": "eisenhower",
|
||||
})
|
||||
Reference in New Issue
Block a user