feat: focus item detail page with inline note + checklist
Each standalone focus item now auto-creates a linked note and checklist. Clicking a focus item opens a detail page with side-by-side note editor (left) and checklist (right) with drag-to-reorder. Save & Return writes the note and goes back to the focus list. Added focus_id FK to notes and lists tables, made domain optional when creating from focus context. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -63,6 +63,7 @@ async def create_form(
|
||||
project_id: Optional[str] = None,
|
||||
task_id: Optional[str] = None,
|
||||
meeting_id: Optional[str] = None,
|
||||
focus_id: Optional[str] = None,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
sidebar = await get_sidebar_data(db)
|
||||
@@ -79,6 +80,7 @@ async def create_form(
|
||||
"prefill_project_id": project_id or "",
|
||||
"prefill_task_id": task_id or "",
|
||||
"prefill_meeting_id": meeting_id or "",
|
||||
"prefill_focus_id": focus_id or "",
|
||||
})
|
||||
|
||||
|
||||
@@ -86,10 +88,11 @@ async def create_form(
|
||||
async def create_note(
|
||||
request: Request,
|
||||
title: str = Form(...),
|
||||
domain_id: str = Form(...),
|
||||
domain_id: Optional[str] = Form(None),
|
||||
project_id: Optional[str] = Form(None),
|
||||
task_id: Optional[str] = Form(None),
|
||||
meeting_id: Optional[str] = Form(None),
|
||||
focus_id: Optional[str] = Form(None),
|
||||
body: Optional[str] = Form(None),
|
||||
content_format: str = Form("rich"),
|
||||
tags: Optional[str] = Form(None),
|
||||
@@ -97,15 +100,19 @@ async def create_note(
|
||||
):
|
||||
repo = BaseRepository("notes", db)
|
||||
data = {
|
||||
"title": title, "domain_id": domain_id,
|
||||
"title": title,
|
||||
"body": body, "content_format": content_format,
|
||||
}
|
||||
if domain_id and domain_id.strip():
|
||||
data["domain_id"] = domain_id
|
||||
if project_id and project_id.strip():
|
||||
data["project_id"] = project_id
|
||||
if task_id and task_id.strip():
|
||||
data["task_id"] = task_id
|
||||
if meeting_id and meeting_id.strip():
|
||||
data["meeting_id"] = meeting_id
|
||||
if focus_id and focus_id.strip():
|
||||
data["focus_id"] = focus_id
|
||||
if tags and tags.strip():
|
||||
data["tags"] = [t.strip() for t in tags.split(",") if t.strip()]
|
||||
note = await repo.create(data)
|
||||
@@ -113,6 +120,8 @@ async def create_note(
|
||||
return RedirectResponse(url=f"/tasks/{task_id}?tab=notes", status_code=303)
|
||||
if meeting_id and meeting_id.strip():
|
||||
return RedirectResponse(url=f"/meetings/{meeting_id}?tab=notes", status_code=303)
|
||||
if focus_id and focus_id.strip():
|
||||
return RedirectResponse(url=f"/focus/{focus_id}?tab=notes", status_code=303)
|
||||
return RedirectResponse(url=f"/notes/{note['id']}", status_code=303)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user