77 lines
2.4 KiB
Python
77 lines
2.4 KiB
Python
"""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 core.database import get_db
|
|
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,
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
sidebar = await get_sidebar_data(db)
|
|
|
|
result = await db.execute(text("""
|
|
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 t.is_deleted = false
|
|
AND t.status IN ('open', 'in_progress', 'blocked')
|
|
ORDER BY t.priority, t.due_date NULLS LAST, t.title
|
|
"""))
|
|
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": [], # Urgent + Important
|
|
"schedule": [], # Not Urgent + Important
|
|
"delegate": [], # Urgent + Not Important
|
|
"eliminate": [], # Not Urgent + Not Important
|
|
}
|
|
|
|
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())
|
|
|
|
return templates.TemplateResponse("eisenhower.html", {
|
|
"request": request,
|
|
"sidebar": sidebar,
|
|
"quadrants": quadrants,
|
|
"counts": counts,
|
|
"total": total,
|
|
"today": today,
|
|
"page_title": "Eisenhower Matrix",
|
|
"active_nav": "eisenhower",
|
|
})
|