feat: add links section to contact create/edit form
Links can now be attached to contacts directly from the create and edit forms with dynamic add/remove rows and role suggestions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -32,10 +32,14 @@ async def list_contacts(request: Request, db: AsyncSession = Depends(get_db)):
|
||||
@router.get("/create")
|
||||
async def create_form(request: Request, db: AsyncSession = Depends(get_db)):
|
||||
sidebar = await get_sidebar_data(db)
|
||||
result = await db.execute(text(
|
||||
"SELECT id, label, url FROM links WHERE is_deleted = false ORDER BY label"
|
||||
))
|
||||
all_links = [dict(r._mapping) for r in result]
|
||||
return templates.TemplateResponse("contact_form.html", {
|
||||
"request": request, "sidebar": sidebar,
|
||||
"page_title": "New Contact", "active_nav": "contacts",
|
||||
"item": None,
|
||||
"item": None, "all_links": all_links,
|
||||
})
|
||||
|
||||
|
||||
@@ -60,8 +64,22 @@ async def create_contact(
|
||||
}
|
||||
if tags and tags.strip():
|
||||
data["tags"] = [t.strip() for t in tags.split(",") if t.strip()]
|
||||
await repo.create(data)
|
||||
return RedirectResponse(url="/contacts", status_code=303)
|
||||
contact = await repo.create(data)
|
||||
|
||||
# Process link attachments from form
|
||||
form_data = await request.form()
|
||||
link_ids = form_data.getlist("link_ids")
|
||||
link_roles = form_data.getlist("link_roles")
|
||||
for i, lid in enumerate(link_ids):
|
||||
if lid and lid.strip():
|
||||
lr = link_roles[i] if i < len(link_roles) else None
|
||||
await db.execute(text("""
|
||||
INSERT INTO contact_links (contact_id, link_id, role)
|
||||
VALUES (:cid, :lid, :role) ON CONFLICT DO NOTHING
|
||||
"""), {"cid": contact["id"], "lid": lid, "role": lr if lr and lr.strip() else None})
|
||||
await db.commit()
|
||||
|
||||
return RedirectResponse(url=f"/contacts/{contact['id']}", status_code=303)
|
||||
|
||||
|
||||
@router.get("/{contact_id}")
|
||||
@@ -104,16 +122,28 @@ async def edit_form(contact_id: str, request: Request, db: AsyncSession = Depend
|
||||
item = await repo.get(contact_id)
|
||||
if not item:
|
||||
return RedirectResponse(url="/contacts", status_code=303)
|
||||
result = await db.execute(text(
|
||||
"SELECT id, label, url FROM links WHERE is_deleted = false ORDER BY label"
|
||||
))
|
||||
all_links = [dict(r._mapping) for r in result]
|
||||
# Existing linked links
|
||||
result = await db.execute(text("""
|
||||
SELECT l.id, l.label, l.url, cl.role
|
||||
FROM links l JOIN contact_links cl ON cl.link_id = l.id
|
||||
WHERE cl.contact_id = :cid AND l.is_deleted = false
|
||||
"""), {"cid": contact_id})
|
||||
linked_links = [dict(r._mapping) for r in result]
|
||||
return templates.TemplateResponse("contact_form.html", {
|
||||
"request": request, "sidebar": sidebar,
|
||||
"page_title": "Edit Contact", "active_nav": "contacts",
|
||||
"item": item,
|
||||
"item": item, "all_links": all_links, "linked_links": linked_links,
|
||||
})
|
||||
|
||||
|
||||
@router.post("/{contact_id}/edit")
|
||||
async def update_contact(
|
||||
contact_id: str,
|
||||
request: Request,
|
||||
first_name: str = Form(...),
|
||||
last_name: Optional[str] = Form(None),
|
||||
company: Optional[str] = Form(None),
|
||||
@@ -135,6 +165,22 @@ async def update_contact(
|
||||
else:
|
||||
data["tags"] = None
|
||||
await repo.update(contact_id, data)
|
||||
|
||||
# Sync link attachments
|
||||
form_data = await request.form()
|
||||
link_ids = form_data.getlist("link_ids")
|
||||
link_roles = form_data.getlist("link_roles")
|
||||
# Clear existing and re-insert
|
||||
await db.execute(text("DELETE FROM contact_links WHERE contact_id = :cid"), {"cid": contact_id})
|
||||
for i, lid in enumerate(link_ids):
|
||||
if lid and lid.strip():
|
||||
lr = link_roles[i] if i < len(link_roles) else None
|
||||
await db.execute(text("""
|
||||
INSERT INTO contact_links (contact_id, link_id, role)
|
||||
VALUES (:cid, :lid, :role) ON CONFLICT DO NOTHING
|
||||
"""), {"cid": contact_id, "lid": lid, "role": lr if lr and lr.strip() else None})
|
||||
await db.commit()
|
||||
|
||||
return RedirectResponse(url=f"/contacts/{contact_id}", status_code=303)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user