From ae6cc24317bd6431da1a277190619c243b24c180 Mon Sep 17 00:00:00 2001 From: Ephraim Duncan <55143799+ephraimduncan@users.noreply.github.com> Date: Thu, 6 Mar 2025 01:34:11 +0000 Subject: [PATCH] feat: hide signature ui when theres no signature field (#1676) --- .../src/app/(signing)/sign/[token]/form.tsx | 68 +++++----- .../(signing)/sign/[token]/sign-dialog.tsx | 123 +++++++++++------- .../app/embed/direct/[[...url]]/client.tsx | 66 +++++----- .../src/app/embed/sign/[[...url]]/client.tsx | 66 +++++----- .../document-flow/stepper-component.spec.ts | 6 +- 5 files changed, 186 insertions(+), 143 deletions(-) diff --git a/apps/web/src/app/(signing)/sign/[token]/form.tsx b/apps/web/src/app/(signing)/sign/[token]/form.tsx index 47033cf11..24f65baf2 100644 --- a/apps/web/src/app/(signing)/sign/[token]/form.tsx +++ b/apps/web/src/app/(signing)/sign/[token]/form.tsx @@ -311,7 +311,11 @@ export const SigningForm = ({ <>

- Please review the document before signing. + {recipient.role === RecipientRole.APPROVER && !hasSignatureField ? ( + Please review the document before approving. + ) : ( + Please review the document before signing. + )}


@@ -335,38 +339,40 @@ export const SigningForm = ({ /> -
- + {hasSignatureField && ( +
+ - - - { - setSignatureValid(isValid); - }} - onChange={(value) => { - if (signatureValid) { - setSignature(value); - } - }} - allowTypedSignature={document.documentMeta?.typedSignatureEnabled} - /> - - + + + { + setSignatureValid(isValid); + }} + onChange={(value) => { + if (signatureValid) { + setSignature(value); + } + }} + allowTypedSignature={document.documentMeta?.typedSignatureEnabled} + /> + + - {hasSignatureField && !signatureValid && ( -
- - Signature is too small. Please provide a more complete signature. - -
- )} -
+ {!signatureValid && ( +
+ + Signature is too small. Please provide a more complete signature. + +
+ )} +
+ )}
diff --git a/apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx b/apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx index 1bbffa9e6..3d05ae312 100644 --- a/apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx +++ b/apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx @@ -1,6 +1,7 @@ import { useMemo, useState } from 'react'; import { Trans } from '@lingui/macro'; +import { match } from 'ts-pattern'; import { fieldsContainUnsignedRequiredField } from '@documenso/lib/utils/advanced-fields-helpers'; import type { Field } from '@documenso/prisma/client'; @@ -58,62 +59,88 @@ export const SignDialog = ({ loading={isSubmitting} disabled={disabled} > - {isComplete ? Complete : Next field} + {match({ isComplete, role }) + .with({ isComplete: false }, () => Next field) + .with({ isComplete: true, role: RecipientRole.APPROVER }, () => Approve) + .with({ isComplete: true, role: RecipientRole.VIEWER }, () => ( + Mark as viewed + )) + .with({ isComplete: true }, () => Complete) + .exhaustive()}
- {role === RecipientRole.VIEWER && Complete Viewing} - {role === RecipientRole.SIGNER && Complete Signing} - {role === RecipientRole.APPROVER && Complete Approval} + {match(role) + .with(RecipientRole.VIEWER, () => Complete Viewing) + .with(RecipientRole.SIGNER, () => Complete Signing) + .with(RecipientRole.APPROVER, () => Complete Approval) + .with(RecipientRole.CC, () => Complete Viewing) + .with(RecipientRole.ASSISTANT, () => Complete Assisting) + .exhaustive()}
- {role === RecipientRole.VIEWER && ( - - - - You are about to complete viewing " - - {documentTitle} + {match(role) + .with(RecipientRole.VIEWER, () => ( + + + + You are about to complete viewing " + + {documentTitle} + + ". - ". - -
Are you sure? -
-
- )} - {role === RecipientRole.SIGNER && ( - - - - You are about to complete signing " - - {documentTitle} +
Are you sure? +
+
+ )) + .with(RecipientRole.SIGNER, () => ( + + + + You are about to complete signing " + + {documentTitle} + + ". - ". - -
Are you sure? - - - )} - {role === RecipientRole.APPROVER && ( - - - - You are about to complete approving{' '} - - "{documentTitle}" +
Are you sure? +
+
+ )) + .with(RecipientRole.APPROVER, () => ( + + + + You are about to complete approving{' '} + + "{documentTitle}" + + . - . - -
Are you sure? - - - )} +
Are you sure? + + + )) + .otherwise(() => ( + + + + You are about to complete viewing " + + {documentTitle} + + ". + +
Are you sure? +
+
+ ))}
@@ -138,9 +165,13 @@ export const SignDialog = ({ loading={isSubmitting} onClick={onSignatureComplete} > - {role === RecipientRole.VIEWER && Mark as Viewed} - {role === RecipientRole.SIGNER && Sign} - {role === RecipientRole.APPROVER && Approve} + {match(role) + .with(RecipientRole.VIEWER, () => Mark as Viewed) + .with(RecipientRole.SIGNER, () => Sign) + .with(RecipientRole.APPROVER, () => Approve) + .with(RecipientRole.CC, () => Mark as Viewed) + .with(RecipientRole.ASSISTANT, () => Complete) + .exhaustive()}
diff --git a/apps/web/src/app/embed/direct/[[...url]]/client.tsx b/apps/web/src/app/embed/direct/[[...url]]/client.tsx index 6b6dbc4c7..dbefcc084 100644 --- a/apps/web/src/app/embed/direct/[[...url]]/client.tsx +++ b/apps/web/src/app/embed/direct/[[...url]]/client.tsx @@ -432,40 +432,42 @@ export const EmbedDirectTemplateClientPage = ({ /> -
- + {hasSignatureField && ( +
+ - - - { - setSignature(value); - }} - onValidityChange={(isValid) => { - setSignatureValid(isValid); - }} - allowTypedSignature={Boolean( - metadata && - 'typedSignatureEnabled' in metadata && - metadata.typedSignatureEnabled, - )} - /> - - + + + { + setSignature(value); + }} + onValidityChange={(isValid) => { + setSignatureValid(isValid); + }} + allowTypedSignature={Boolean( + metadata && + 'typedSignatureEnabled' in metadata && + metadata.typedSignatureEnabled, + )} + /> + + - {hasSignatureField && !signatureValid && ( -
- - Signature is too small. Please provide a more complete signature. - -
- )} -
+ {hasSignatureField && !signatureValid && ( +
+ + Signature is too small. Please provide a more complete signature. + +
+ )} +
+ )} diff --git a/apps/web/src/app/embed/sign/[[...url]]/client.tsx b/apps/web/src/app/embed/sign/[[...url]]/client.tsx index 4650f60ab..e5a556077 100644 --- a/apps/web/src/app/embed/sign/[[...url]]/client.tsx +++ b/apps/web/src/app/embed/sign/[[...url]]/client.tsx @@ -436,40 +436,42 @@ export const EmbedSignDocumentClientPage = ({ /> -
- + {hasSignatureField && ( +
+ - - - { - setSignature(value); - }} - onValidityChange={(isValid) => { - setSignatureValid(isValid); - }} - allowTypedSignature={Boolean( - metadata && - 'typedSignatureEnabled' in metadata && - metadata.typedSignatureEnabled, - )} - /> - - + + + { + setSignature(value); + }} + onValidityChange={(isValid) => { + setSignatureValid(isValid); + }} + allowTypedSignature={Boolean( + metadata && + 'typedSignatureEnabled' in metadata && + metadata.typedSignatureEnabled, + )} + /> + + - {hasSignatureField && !signatureValid && ( -
- - Signature is too small. Please provide a more complete signature. - -
- )} -
+ {hasSignatureField && !signatureValid && ( +
+ + Signature is too small. Please provide a more complete signature. + +
+ )} +
+ )} )} diff --git a/packages/app-tests/e2e/document-flow/stepper-component.spec.ts b/packages/app-tests/e2e/document-flow/stepper-component.spec.ts index d53f33d11..ba7c580a6 100644 --- a/packages/app-tests/e2e/document-flow/stepper-component.spec.ts +++ b/packages/app-tests/e2e/document-flow/stepper-component.spec.ts @@ -384,7 +384,9 @@ test('[DOCUMENT_FLOW]: should be able to approve a document', async ({ page }) = await expect(page.locator(`#field-${field.id}`)).toHaveAttribute('data-inserted', 'true'); } - await page.getByRole('button', { name: 'Complete' }).click(); + await page + .getByRole('button', { name: role === RecipientRole.SIGNER ? 'Complete' : 'Approve' }) + .click(); await page .getByRole('button', { name: role === RecipientRole.SIGNER ? 'Sign' : 'Approve' }) .click(); @@ -454,7 +456,7 @@ test('[DOCUMENT_FLOW]: should be able to create, send with redirect url, sign a const { status } = await getDocumentByToken(token); expect(status).toBe(DocumentStatus.PENDING); - await page.getByRole('button', { name: 'Complete' }).click(); + await page.getByRole('button', { name: 'Approve' }).click(); await expect(page.getByRole('dialog').getByText('Complete Approval').first()).toBeVisible(); await page.getByRole('button', { name: 'Approve' }).click();