feat: create new links directly from contact pages

Contact detail: + New Link button redirects to link form with contact context.
Contact create/edit form: inline new link rows (label/url/role) created on submit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 14:45:13 +00:00
parent 2abc87abfc
commit 12ed017033
5 changed files with 68 additions and 1 deletions

View File

@@ -52,6 +52,7 @@ async def create_form(
project_id: Optional[str] = None,
task_id: Optional[str] = None,
meeting_id: Optional[str] = None,
contact_id: Optional[str] = None,
db: AsyncSession = Depends(get_db),
):
sidebar = await get_sidebar_data(db)
@@ -67,6 +68,7 @@ async def create_form(
"prefill_project_id": project_id or "",
"prefill_task_id": task_id or "",
"prefill_meeting_id": meeting_id or "",
"prefill_contact_id": contact_id or "",
})
@@ -75,6 +77,7 @@ async def create_link(
request: Request, label: str = Form(...), url: 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),
contact_id: Optional[str] = Form(None),
description: Optional[str] = Form(None), tags: Optional[str] = Form(None),
db: AsyncSession = Depends(get_db),
):
@@ -99,6 +102,15 @@ async def create_link(
VALUES (:fid, :lid) ON CONFLICT DO NOTHING
"""), {"fid": default_fid, "lid": link["id"]})
# Attach to contact if created from contact context
if contact_id and contact_id.strip():
await db.execute(text("""
INSERT INTO contact_links (contact_id, link_id)
VALUES (:cid, :lid) ON CONFLICT DO NOTHING
"""), {"cid": contact_id, "lid": link["id"]})
await db.commit()
return RedirectResponse(url=f"/contacts/{contact_id}", status_code=303)
# Redirect back to context if created from task/meeting/project
if task_id and task_id.strip():
return RedirectResponse(url=f"/tasks/{task_id}?tab=links", status_code=303)