- Activity-feed: shared formatting module (src/components/shared/activity-formatting.ts) centralises action verbs, badge variants, entity-type labels, enum-value normalisation, shortValue, and buildDiffLine. The dashboard widget feed and the per-entity audit feed now both consume it - duplicate ~250 lines collapsed, vocabularies aligned, badge palette unified. - Signing order setting becomes tri-state. The new TEMPLATE_DEFAULT value (the new default) skips overriding the template's own signingOrder so each Documenso template's stored setting wins. PARALLEL / SEQUENTIAL keep forcing the override. - Admin Documenso page now ships a Webhook health card backed by /api/v1/admin/documenso-webhook/health (secret status, expected URL, last received event, recent secret rejections) and a "Test now" button that fires a synthetic DOCUMENT_OPENED through /api/v1/admin/documenso-webhook/test against the local receiver to verify the full pipeline without driving a real Documenso event. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
214 lines
11 KiB
TypeScript
214 lines
11 KiB
TypeScript
import { CheckCircle2, Info } from 'lucide-react';
|
|
|
|
import { RegistryDrivenForm } from '@/components/admin/shared/registry-driven-form';
|
|
import { DocumensoTestButton } from '@/components/admin/documenso/documenso-test-button';
|
|
import { EmbeddedSigningCard } from '@/components/admin/documenso/embedded-signing-card';
|
|
import { TemplateSyncButton } from '@/components/admin/documenso/template-sync-button';
|
|
import { WebhookHealthCard } from '@/components/admin/documenso/webhook-health-card';
|
|
import { PageHeader } from '@/components/shared/page-header';
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
|
|
// All field arrays removed - every Documenso setting now flows through
|
|
// `RegistryDrivenForm`, which surfaces the env-fallback / port / global
|
|
// source badge on each field. The settings themselves live in
|
|
// `src/lib/settings/registry.ts` under sections `documenso.api` /
|
|
// `.signers` / `.templates` / `.behavior`.
|
|
|
|
export default function DocumensoSettingsPage() {
|
|
return (
|
|
<div className="space-y-6">
|
|
<PageHeader
|
|
title="Signing service (Documenso)"
|
|
description="API credentials, signer identities, templates, and signing behaviour for every document the CRM puts out for signature (EOI, reservation, contract, custom uploads). Use the test-connection button to verify a saved configuration before relying on it."
|
|
/>
|
|
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="flex items-center gap-2 text-base">
|
|
<Info className="h-4 w-4" aria-hidden="true" />
|
|
v1 vs v2 - what changes when you flip the API version
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-4 text-sm">
|
|
<p className="text-muted-foreground">
|
|
The CRM supports both Documenso 1.13.x (v1) and 2.x (v2). v1 is the default for
|
|
backwards compatibility. v2 is recommended for new ports and unlocks the features below.
|
|
Switching versions does <strong>not</strong> require any code changes - version-aware
|
|
client methods pick the right endpoint per port. Switch, save, then run the
|
|
test-connection button to confirm the chosen instance is actually on the matching
|
|
Documenso version.
|
|
</p>
|
|
|
|
<div className="rounded-md border border-border bg-muted/40 p-3">
|
|
<p className="mb-2 text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
v2-only capabilities the CRM already uses when you pick v2
|
|
</p>
|
|
<ul className="space-y-1.5">
|
|
<li className="flex items-start gap-2">
|
|
<CheckCircle2
|
|
className="mt-0.5 h-4 w-4 shrink-0 text-emerald-600"
|
|
aria-hidden="true"
|
|
/>
|
|
<span>
|
|
<strong>Bulk field placement.</strong> One API call per envelope vs. v1's
|
|
per-field POST loop. Faster contract generation, fewer transient retries on
|
|
multi-field uploaded contracts.
|
|
</span>
|
|
</li>
|
|
<li className="flex items-start gap-2">
|
|
<CheckCircle2
|
|
className="mt-0.5 h-4 w-4 shrink-0 text-emerald-600"
|
|
aria-hidden="true"
|
|
/>
|
|
<span>
|
|
<strong>Percent-based field coordinates.</strong> No page-dimension lookup needed
|
|
- coordinates are portable across page sizes. v1 requires us to assume A4 for
|
|
auto-placed fields.
|
|
</span>
|
|
</li>
|
|
<li className="flex items-start gap-2">
|
|
<CheckCircle2
|
|
className="mt-0.5 h-4 w-4 shrink-0 text-emerald-600"
|
|
aria-hidden="true"
|
|
/>
|
|
<span>
|
|
<strong>Richer field metadata.</strong> TEXT labels & required flags, NUMBER
|
|
min/max + format, CHECKBOX/DROPDOWN/RADIO option lists with defaults - all ignored
|
|
by v1, surfaced by v2 in the signing UI.
|
|
</span>
|
|
</li>
|
|
<li className="flex items-start gap-2">
|
|
<CheckCircle2
|
|
className="mt-0.5 h-4 w-4 shrink-0 text-emerald-600"
|
|
aria-hidden="true"
|
|
/>
|
|
<span>
|
|
<strong>v2-flavoured webhook events.</strong> <code>RECIPIENT_VIEWED</code>,{' '}
|
|
<code>RECIPIENT_SIGNED</code>, <code>DOCUMENT_RECIPIENT_COMPLETED</code>,{' '}
|
|
<code>DOCUMENT_DECLINED</code>, <code>DOCUMENT_REMINDER_SENT</code> - all routed
|
|
through the same dedup + audit pipeline as v1 events.
|
|
</span>
|
|
</li>
|
|
<li className="flex items-start gap-2">
|
|
<CheckCircle2
|
|
className="mt-0.5 h-4 w-4 shrink-0 text-emerald-600"
|
|
aria-hidden="true"
|
|
/>
|
|
<span>
|
|
<strong>Envelope CRUD endpoints.</strong> <code>GET</code>, <code>DELETE</code>,
|
|
<code>POST /envelope/create</code> (multipart),{' '}
|
|
<code>POST /envelope/distribute</code>, <code>POST /envelope/redistribute</code>,{' '}
|
|
<code>GET /envelope/{'{id}'}/download</code> - all routed through{' '}
|
|
<code>/api/v2/envelope/...</code> when v2 is selected. The template-generate path
|
|
is intentionally still v1 (relies on Documenso 2.x's backward-compat window -
|
|
see the deferred-roadmap below).
|
|
</span>
|
|
</li>
|
|
<li className="flex items-start gap-2">
|
|
<CheckCircle2
|
|
className="mt-0.5 h-4 w-4 shrink-0 text-emerald-600"
|
|
aria-hidden="true"
|
|
/>
|
|
<span>
|
|
<strong>One-call send.</strong> v2's <code>/envelope/distribute</code>{' '}
|
|
returns per-recipient <code>signingUrl</code> in the same response - v1 requires a
|
|
separate GET to fetch them. Faster send flow on the rep side.
|
|
</span>
|
|
</li>
|
|
<li className="flex items-start gap-2">
|
|
<CheckCircle2
|
|
className="mt-0.5 h-4 w-4 shrink-0 text-emerald-600"
|
|
aria-hidden="true"
|
|
/>
|
|
<span>
|
|
<strong>Sequential signing enforcement.</strong> Pick SEQUENTIAL in the "v2
|
|
signing behaviour" card below and Documenso 2.x refuses to email recipient
|
|
N+1 until recipient N has signed. Eliminates the "approver signed before the
|
|
developer did" race on EOIs.
|
|
</span>
|
|
</li>
|
|
<li className="flex items-start gap-2">
|
|
<CheckCircle2
|
|
className="mt-0.5 h-4 w-4 shrink-0 text-emerald-600"
|
|
aria-hidden="true"
|
|
/>
|
|
<span>
|
|
<strong>Post-signing redirect URL.</strong> Set in the "v2 signing
|
|
behaviour" card; Documenso redirects the signer to that URL after they
|
|
complete signing. Use to land clients on the marketing site's success page or
|
|
back in the portal instead of Documenso's default thank-you page. (v1 honours
|
|
this too - listed here because the admin setting was added with the v2 work.)
|
|
</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div className="rounded-md border border-amber-200 bg-amber-50/60 p-3 dark:border-amber-900/40 dark:bg-amber-950/30">
|
|
<p className="mb-2 text-xs font-semibold uppercase tracking-wider text-amber-700 dark:text-amber-400">
|
|
v2 capabilities deferred (would need new code paths)
|
|
</p>
|
|
<ul className="space-y-1.5 text-muted-foreground">
|
|
<li>
|
|
<strong>
|
|
Single-shot <code>/template/use</code>
|
|
</strong>{' '}
|
|
with v2 <code>prefillFields</code> by ID - current EOI flow uses{' '}
|
|
<code>/api/v1/templates/{'{id}'}/generate-document</code> with{' '}
|
|
<code>formValues</code> keyed by name. v2 instances accept both during their
|
|
backward-compat window; full migration requires per-template field-ID capture in
|
|
admin settings.
|
|
</li>
|
|
<li>
|
|
<strong>
|
|
Update envelope metadata after creation (<code>/envelope/update</code>)
|
|
</strong>{' '}
|
|
- change title / subject / redirectUrl on a doc already in DRAFT/PENDING without
|
|
re-generating.
|
|
</li>
|
|
<li>
|
|
<strong>Non-SIGNER recipient roles (CC / VIEWER)</strong> - APPROVER role is already
|
|
used by the EOI template; CC + VIEWER not yet exposed in the recipient builder.
|
|
Useful for sales managers who want a copy without a signature slot.
|
|
</li>
|
|
</ul>
|
|
<p className="mt-2 text-xs text-muted-foreground">
|
|
Sequential signing and post-signing redirect URL <strong>are now wired</strong> - see
|
|
the new "v2 signing behaviour" card below to configure them.
|
|
</p>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<RegistryDrivenForm
|
|
title="Documenso API"
|
|
description="Per-port API credentials. AES-encrypted at rest. Leave blank to inherit from the env fallback (badged below each field)."
|
|
sections={['documenso.api']}
|
|
extra={<DocumensoTestButton />}
|
|
/>
|
|
|
|
<RegistryDrivenForm
|
|
sections={['documenso.behavior']}
|
|
title="Signing behaviour"
|
|
description="Cross-cutting settings that apply to EOIs + uploaded contracts/reservations. Sequential signing is v2-only (v1 instances ignore it). Redirect URL is honoured by both v1 and v2 instances."
|
|
/>
|
|
|
|
<RegistryDrivenForm
|
|
sections={['documenso.signers']}
|
|
title="Signers (developer + approver)"
|
|
description="Identity bound to the developer (signing order 2) and approver (signing order 3) slots in your Documenso templates. Leave name + email blank to fall through to whatever you set on the Documenso template itself; set them here to override the template's stored values at send time. Recipient IDs are populated automatically by 'Sync from Documenso' below. Linking a CRM user is optional - when set, the platform fires an in-CRM notification for that user when it's their turn to sign."
|
|
/>
|
|
|
|
<RegistryDrivenForm
|
|
sections={['documenso.templates']}
|
|
title="Templates & signing pathway"
|
|
description="Default pathway, template IDs, and email behaviour for EOIs, reservations, and contracts. Recipient + field discovery happens via 'Sync from Documenso' below - that also populates the EOI template ID for you. Most ports leave the reservation/contract template IDs blank because those are typically drafted per interest and uploaded for signing; set them only if you maintain standardised Documenso templates for them."
|
|
extra={<TemplateSyncButton />}
|
|
/>
|
|
|
|
<EmbeddedSigningCard />
|
|
|
|
<WebhookHealthCard />
|
|
</div>
|
|
);
|
|
}
|