mirror of
https://github.com/documenso/documenso.git
synced 2026-07-24 17:04:12 +10:00
feat: signing reminders (#1749)
This commit is contained in:
@@ -66,6 +66,9 @@ export const extractDerivedDocumentMeta = (
|
||||
// Envelope expiration.
|
||||
envelopeExpirationPeriod:
|
||||
meta.envelopeExpirationPeriod ?? settings.envelopeExpirationPeriod ?? null,
|
||||
|
||||
// Reminder settings.
|
||||
reminderSettings: meta.reminderSettings ?? settings.reminderSettings ?? null,
|
||||
} satisfies Omit<DocumentMeta, 'id'>;
|
||||
};
|
||||
|
||||
|
||||
@@ -67,6 +67,9 @@ export const buildEmbeddedFeatures = (
|
||||
allowConfigureExpirationPeriod:
|
||||
features.settings?.allowConfigureExpirationPeriod ??
|
||||
DEFAULT_EMBEDDED_EDITOR_CONFIG.settings.allowConfigureExpirationPeriod,
|
||||
allowConfigureReminders:
|
||||
features.settings?.allowConfigureReminders ??
|
||||
DEFAULT_EMBEDDED_EDITOR_CONFIG.settings.allowConfigureReminders,
|
||||
allowConfigureEmailSender:
|
||||
features.settings?.allowConfigureEmailSender ??
|
||||
DEFAULT_EMBEDDED_EDITOR_CONFIG.settings.allowConfigureEmailSender,
|
||||
|
||||
@@ -252,7 +252,7 @@ export type EnvelopeItemPermissions = {
|
||||
|
||||
export const getEnvelopeItemPermissions = (
|
||||
envelope: Pick<Envelope, 'completedAt' | 'deletedAt' | 'type' | 'status'>,
|
||||
recipients: Recipient[],
|
||||
recipients: Pick<Recipient, 'role' | 'signingStatus' | 'sendStatus'>[],
|
||||
): EnvelopeItemPermissions => {
|
||||
// Always reject completed/rejected/deleted envelopes.
|
||||
if (
|
||||
|
||||
@@ -9,6 +9,7 @@ import type { ORGANISATION_MEMBER_ROLE_MAP } from '@documenso/lib/constants/orga
|
||||
|
||||
import { DEFAULT_DOCUMENT_DATE_FORMAT } from '../constants/date-formats';
|
||||
import { DEFAULT_ENVELOPE_EXPIRATION_PERIOD } from '../constants/envelope-expiration';
|
||||
import { DEFAULT_ENVELOPE_REMINDER_SETTINGS } from '../constants/envelope-reminder';
|
||||
import {
|
||||
LOWEST_ORGANISATION_ROLE,
|
||||
ORGANISATION_MEMBER_ROLE_HIERARCHY,
|
||||
@@ -142,6 +143,8 @@ export const generateDefaultOrganisationSettings = (): Omit<
|
||||
|
||||
envelopeExpirationPeriod: DEFAULT_ENVELOPE_EXPIRATION_PERIOD,
|
||||
|
||||
reminderSettings: DEFAULT_ENVELOPE_REMINDER_SETTINGS,
|
||||
|
||||
aiFeaturesEnabled: false,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import type { Envelope } from '@prisma/client';
|
||||
import { type Field, type Recipient, RecipientRole, SigningStatus } from '@prisma/client';
|
||||
import { type Field, RecipientRole, SigningStatus } from '@prisma/client';
|
||||
|
||||
import { isSignatureFieldType } from '@documenso/prisma/guards/is-signature-field';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '../constants/app';
|
||||
import { AppError, AppErrorCode } from '../errors/app-error';
|
||||
import type { TRecipientLite } from '../types/recipient';
|
||||
import { extractLegacyIds } from '../universal/id';
|
||||
import { zEmail } from './zod';
|
||||
|
||||
@@ -20,7 +21,7 @@ export const RECIPIENT_ROLES_THAT_REQUIRE_FIELDS = [RecipientRole.SIGNER] as con
|
||||
*
|
||||
* Currently only SIGNERs are validated - they must have at least one signature field.
|
||||
*/
|
||||
export const getRecipientsWithMissingFields = <T extends Pick<Recipient, 'id' | 'role'>>(
|
||||
export const getRecipientsWithMissingFields = <T extends Pick<TRecipientLite, 'id' | 'role'>>(
|
||||
recipients: T[],
|
||||
fields: Pick<Field, 'type' | 'recipientId'>[],
|
||||
): T[] => {
|
||||
@@ -42,7 +43,10 @@ export const formatSigningLink = (token: string) => `${NEXT_PUBLIC_WEBAPP_URL()}
|
||||
/**
|
||||
* Whether a recipient can be modified by the document owner.
|
||||
*/
|
||||
export const canRecipientBeModified = (recipient: Recipient, fields: Field[]) => {
|
||||
export const canRecipientBeModified = (
|
||||
recipient: TRecipientLite,
|
||||
fields: Pick<Field, 'recipientId' | 'inserted'>[],
|
||||
) => {
|
||||
if (!recipient) {
|
||||
return false;
|
||||
}
|
||||
@@ -72,7 +76,10 @@ export const canRecipientBeModified = (recipient: Recipient, fields: Field[]) =>
|
||||
* - They are not a Viewer or CCer
|
||||
* - They can be modified (canRecipientBeModified)
|
||||
*/
|
||||
export const canRecipientFieldsBeModified = (recipient: Recipient, fields: Field[]) => {
|
||||
export const canRecipientFieldsBeModified = (
|
||||
recipient: TRecipientLite,
|
||||
fields: Pick<Field, 'recipientId' | 'inserted'>[],
|
||||
) => {
|
||||
if (!canRecipientBeModified(recipient, fields)) {
|
||||
return false;
|
||||
}
|
||||
@@ -81,7 +88,7 @@ export const canRecipientFieldsBeModified = (recipient: Recipient, fields: Field
|
||||
};
|
||||
|
||||
export const mapRecipientToLegacyRecipient = (
|
||||
recipient: Recipient,
|
||||
recipient: TRecipientLite,
|
||||
envelope: Pick<Envelope, 'type' | 'secondaryId'>,
|
||||
) => {
|
||||
const legacyId = extractLegacyIds(envelope);
|
||||
@@ -92,6 +99,7 @@ export const mapRecipientToLegacyRecipient = (
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
export const findRecipientByEmail = <T extends { email: string }>({
|
||||
recipients,
|
||||
userEmail,
|
||||
@@ -102,7 +110,7 @@ export const findRecipientByEmail = <T extends { email: string }>({
|
||||
teamEmail?: string | null;
|
||||
}) => recipients.find((r) => r.email === userEmail || (teamEmail && r.email === teamEmail));
|
||||
|
||||
export const isRecipientEmailValidForSending = (recipient: Pick<Recipient, 'email'>) => {
|
||||
export const isRecipientEmailValidForSending = (recipient: Pick<TRecipientLite, 'email'>) => {
|
||||
return zEmail().safeParse(recipient.email).success;
|
||||
};
|
||||
|
||||
|
||||
@@ -208,6 +208,8 @@ export const generateDefaultTeamSettings = (): Omit<TeamGlobalSettings, 'id' | '
|
||||
|
||||
envelopeExpirationPeriod: null,
|
||||
|
||||
reminderSettings: null,
|
||||
|
||||
aiFeaturesEnabled: null,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user