Phase 1: Workflows UI, Dedup/Merge UI, Import/Export UI, Print/PDF

- Workflows UI: full page with definitions/instances tabs, step editor, instance detail with approve/reject
- Dedup/Merge UI: duplicate detection, side-by-side comparison, field-level merge dialog, merge history
- Import/Export UI: import wizard (dry-run preview), export panel (CSV/XLSX), backend export route added
- Print/PDF: PrintButton component, print.css, integrated in Contacts/Calendar/Reports/ContactDetail
- Backend: GET /api/v1/export endpoint, export_companies_csv() service function
- Routes: /workflows, /contacts/dedup, /import-export registered
- Menu items: Workflows, Import/Export, Duplikate added to automation plugin manifest
- IMPLEMENTATION_PLAN.md: audit-corrected plan for all 14 remaining features
This commit is contained in:
Agent Zero
2026-07-26 02:35:44 +02:00
parent 6d484ed747
commit a3a5a10514
27 changed files with 4288 additions and 5 deletions
+39
View File
@@ -252,3 +252,42 @@ async def export_contacts_csv(
]
)
return output.getvalue()
async def export_companies_csv(
db: AsyncSession,
tenant_id: uuid.UUID,
) -> str:
"""Export companies (Contact.type == 'company') as CSV string."""
q = (
select(Contact)
.where(
Contact.tenant_id == tenant_id,
Contact.deleted_at.is_(None),
Contact.type == "company",
)
.order_by(Contact.name)
)
result = await db.execute(q)
companies = result.scalars().all()
output = io.StringIO()
writer = csv.writer(output)
writer.writerow(
["id", "type", "name", "email", "phone", "website", "city", "postalcode", "country"]
)
for c in companies:
writer.writerow(
[
str(c.id),
c.type or "company",
c.name or "",
c.email_1 or "",
c.phone_1 or "",
c.website or "",
c.mailing_city or "",
c.mailing_postalcode or "",
c.mailing_country or "",
]
)
return output.getvalue()