From dd561cd386c8ee0fbb83c377d786785f03acf154 Mon Sep 17 00:00:00 2001 From: Jeremy Kritt <8386890+jmkritt@users.noreply.github.com> Date: Wed, 6 May 2026 14:59:57 -0500 Subject: [PATCH] Render signed signatures and initials with a wrapped credibility treatment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a "wrap" visual treatment to signed signature and initials fields in the result PDF, the live signing UI, and the post-sign view, so recipients see a consistent bracketed layout matching industry-standard signed-document conventions (DocuSign / Adobe Sign etc.). Motivation ---------- Built for a residential real-estate signing workflow where clients and title companies are accustomed to the bracketed signature visual format. The current DocuSeal output is a centered signature image with optional plain-text caption beside or below it; signed initials are a bare image with no caption. This change closes the visual gap as an opt-in style — only renders when with_signature_id is enabled (existing config flag, default false). Sharing in case useful upstream; happy to iterate on the design or split into smaller commits. Change ------ - HexaPDF rendering rewrite in lib/submissions/generate_result_attachments.rb: - Left-side amber bracket via path drawing, height matched to image - Centered signature image - Helvetica-Bold header ("Digitally signed by:" / "Initials:") - Optional caption (name + timestamp) and truncated document ID - Adaptive layout: drops ID line, then caption line, before crushing the image when field is small - Page-derived font sizing so signatures and initials match - Mirrored layout in the live signing UI (app/javascript/submission_form/area.vue) and the post-sign view (app/views/submissions/_value.html.erb) so the signer's review and the completed-submission page match the PDF - Typed initials font alias in lib/submitters/generate_font_image.rb switched from Go Noto Bold to Dancing Script — matches the typed signature font, fixing the visual inconsistency where typed signatures rendered cursive but typed initials rendered sans-serif Trade-offs ---------- - Helvetica vs Go Noto for header/caption: Helvetica is one of the 14 standard PDF fonts, keeps the credibility text crisp. Non-Latin scripts in the bracket text fall back to Helvetica's coverage. The signature image itself still renders correctly using Go Noto. - No data-model change. Pure rendering layer. - Default behavior unchanged for existing users (with_signature_id is still false by default in upstream). Out of scope ------------ - Strikethrough field unhide (separate PR) - Default-flag flips for with_signature_id, with_disclosure (opinionated) --- app/javascript/submission_form/area.vue | 60 +++-- app/views/submissions/_value.html.erb | 63 +++-- .../generate_result_attachments.rb | 236 +++++++++--------- lib/submitters/generate_font_image.rb | 2 +- 4 files changed, 210 insertions(+), 151 deletions(-) diff --git a/app/javascript/submission_form/area.vue b/app/javascript/submission_form/area.vue index 69a453ac84..8e00410f48 100644 --- a/app/javascript/submission_form/area.vue +++ b/app/javascript/submission_form/area.vue @@ -73,11 +73,18 @@ >
+ {{ t('digitally_signed_by') }} · ID {{ String(signature.uuid).slice(0, 8).toUpperCase() }} +
+
@@ -88,28 +95,49 @@
-
- ID: {{ signature.uuid }} -
-
- {{ t('reason') }}: {{ values[field.preferences?.reason_field_uuid] || t('digitally_signed_by') }} {{ submitter.name }} - +
+ ID: {{ String(signature.uuid).slice(0, 8).toUpperCase() }}
-
- {{ new Date(signature.created_at).toLocaleString(undefined, { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', timeZoneName: 'short' }) }} +
+ {{ submitter.name }} + · {{ new Date(signature.created_at).toLocaleString(undefined, { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', timeZoneName: 'short' }) }}
- +
+ ID {{ String(initials.uuid).slice(0, 8).toUpperCase() }} +
+
+ +
+
+ {{ submitter.name }} + · {{ new Date(initials.created_at).toLocaleString(undefined, { year: 'numeric', month: 'short', day: 'numeric' }) }} +
+