mirror of
https://github.com/documenso/documenso.git
synced 2025-11-10 04:22:32 +10:00
Compare commits
5 Commits
v1.12.0
...
feat/team-
| Author | SHA1 | Date | |
|---|---|---|---|
| 03a433e6bb | |||
| d32474a318 | |||
| 1f832657bc | |||
| f2c3371a99 | |||
| 7562a68cca |
@ -196,6 +196,7 @@ export const MenuSwitcher = ({ user, teams: initialTeamsData }: MenuSwitcherProp
|
||||
}
|
||||
avatarFallback={formatAvatarFallback(team.name)}
|
||||
primaryText={team.name}
|
||||
textSectionClassName="w-[200px]"
|
||||
secondaryText={
|
||||
<div className="relative w-full">
|
||||
<motion.span
|
||||
|
||||
@ -12,6 +12,8 @@ export interface TemplateDocumentInviteProps {
|
||||
assetBaseUrl: string;
|
||||
role: RecipientRole;
|
||||
selfSigner: boolean;
|
||||
isTeamInvite: boolean;
|
||||
teamName?: string;
|
||||
}
|
||||
|
||||
export const TemplateDocumentInvite = ({
|
||||
@ -21,6 +23,8 @@ export const TemplateDocumentInvite = ({
|
||||
assetBaseUrl,
|
||||
role,
|
||||
selfSigner,
|
||||
isTeamInvite,
|
||||
teamName,
|
||||
}: TemplateDocumentInviteProps) => {
|
||||
const { actionVerb, progressiveVerb } = RECIPIENT_ROLES_DESCRIPTION[role];
|
||||
|
||||
@ -36,6 +40,12 @@ export const TemplateDocumentInvite = ({
|
||||
<br />
|
||||
{`"${documentName}"`}
|
||||
</>
|
||||
) : isTeamInvite ? (
|
||||
<>
|
||||
{`${inviterName} on behalf of ${teamName} has invited you to ${actionVerb.toLowerCase()}`}
|
||||
<br />
|
||||
{`"${documentName}"`}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{`${inviterName} has invited you to ${actionVerb.toLowerCase()}`}
|
||||
|
||||
@ -91,6 +91,9 @@ export const ConfirmTeamEmailTemplate = ({
|
||||
<li className="mt-1 text-sm">
|
||||
Allow document recipients to reply directly to this email address
|
||||
</li>
|
||||
<li className="mt-1 text-sm">
|
||||
Send documents on behalf of the team using the email address
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<Text className="mt-2 text-sm">
|
||||
|
||||
@ -23,6 +23,9 @@ export type DocumentInviteEmailTemplateProps = Partial<TemplateDocumentInvitePro
|
||||
customBody?: string;
|
||||
role: RecipientRole;
|
||||
selfSigner?: boolean;
|
||||
isTeamInvite?: boolean;
|
||||
teamName?: string;
|
||||
teamEmail?: string;
|
||||
};
|
||||
|
||||
export const DocumentInviteEmailTemplate = ({
|
||||
@ -34,11 +37,18 @@ export const DocumentInviteEmailTemplate = ({
|
||||
customBody,
|
||||
role,
|
||||
selfSigner = false,
|
||||
isTeamInvite = false,
|
||||
teamName,
|
||||
teamEmail,
|
||||
}: DocumentInviteEmailTemplateProps) => {
|
||||
const action = RECIPIENT_ROLES_DESCRIPTION[role].actionVerb.toLowerCase();
|
||||
|
||||
const previewText = selfSigner
|
||||
? `Please ${action} your document ${documentName}`
|
||||
: isTeamInvite
|
||||
? `${inviterName} on behalf of ${teamName}${
|
||||
teamEmail ? ` (${teamEmail})` : ''
|
||||
} has invited you to ${action} ${documentName}`
|
||||
: `${inviterName} has invited you to ${action} ${documentName}`;
|
||||
|
||||
const getAssetUrl = (path: string) => {
|
||||
@ -76,6 +86,8 @@ export const DocumentInviteEmailTemplate = ({
|
||||
assetBaseUrl={assetBaseUrl}
|
||||
role={role}
|
||||
selfSigner={selfSigner}
|
||||
isTeamInvite={isTeamInvite}
|
||||
teamName={teamName}
|
||||
/>
|
||||
</Section>
|
||||
</Container>
|
||||
@ -83,9 +95,14 @@ export const DocumentInviteEmailTemplate = ({
|
||||
<Container className="mx-auto mt-12 max-w-xl">
|
||||
<Section>
|
||||
<Text className="my-4 text-base font-semibold">
|
||||
{inviterName}{' '}
|
||||
<Link className="font-normal text-slate-400" href="mailto:{inviterEmail}">
|
||||
({inviterEmail})
|
||||
{isTeamInvite && teamName
|
||||
? `${inviterName} on behalf of ${teamName}`
|
||||
: inviterName}{' '}
|
||||
<Link
|
||||
className="font-normal text-slate-400"
|
||||
href={`mailto:${teamEmail || inviterEmail}`}
|
||||
>
|
||||
({teamEmail || inviterEmail})
|
||||
</Link>
|
||||
</Text>
|
||||
|
||||
@ -93,7 +110,9 @@ export const DocumentInviteEmailTemplate = ({
|
||||
{customBody ? (
|
||||
<pre className="font-sans text-base text-slate-400">{customBody}</pre>
|
||||
) : (
|
||||
`${inviterName} has invited you to ${action} the document "${documentName}".`
|
||||
`${inviterName} ${
|
||||
isTeamInvite ? `on behalf of ${teamName}` : ''
|
||||
} has invited you to ${action} the document "${documentName}".`
|
||||
)}
|
||||
</Text>
|
||||
</Section>
|
||||
|
||||
@ -58,6 +58,12 @@ export const SEND_SIGNING_EMAIL_JOB_DEFINITION = {
|
||||
},
|
||||
include: {
|
||||
documentMeta: true,
|
||||
team: {
|
||||
select: {
|
||||
teamEmail: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
prisma.recipient.findFirstOrThrow({
|
||||
@ -67,7 +73,7 @@ export const SEND_SIGNING_EMAIL_JOB_DEFINITION = {
|
||||
}),
|
||||
]);
|
||||
|
||||
const { documentMeta } = document;
|
||||
const { documentMeta, team } = document;
|
||||
|
||||
if (recipient.role === RecipientRole.CC) {
|
||||
return;
|
||||
@ -75,6 +81,7 @@ export const SEND_SIGNING_EMAIL_JOB_DEFINITION = {
|
||||
|
||||
const customEmail = document?.documentMeta;
|
||||
const isDirectTemplate = document.source === DocumentSource.TEMPLATE_DIRECT_LINK;
|
||||
const isTeamDocument = document.teamId !== null;
|
||||
|
||||
const recipientEmailType = RECIPIENT_ROLE_TO_EMAIL_TYPE[recipient.role];
|
||||
|
||||
@ -96,6 +103,11 @@ export const SEND_SIGNING_EMAIL_JOB_DEFINITION = {
|
||||
emailSubject = `Please ${recipientActionVerb} this document created by your direct template`;
|
||||
}
|
||||
|
||||
if (isTeamDocument && team) {
|
||||
emailSubject = `${team.name} invited you to ${recipientActionVerb} a document`;
|
||||
emailMessage = `${user.name} on behalf of ${team.name} has invited you to ${recipientActionVerb} the document "${document.title}".`;
|
||||
}
|
||||
|
||||
const customEmailTemplate = {
|
||||
'signer.name': name,
|
||||
'signer.email': email,
|
||||
@ -114,6 +126,9 @@ export const SEND_SIGNING_EMAIL_JOB_DEFINITION = {
|
||||
customBody: renderCustomEmailTemplate(emailMessage, customEmailTemplate),
|
||||
role: recipient.role,
|
||||
selfSigner,
|
||||
isTeamInvite: isTeamDocument,
|
||||
teamName: team?.name,
|
||||
teamEmail: team?.teamEmail?.email,
|
||||
});
|
||||
|
||||
await io.runTask('send-signing-email', async () => {
|
||||
|
||||
@ -58,10 +58,17 @@ export const resendDocument = async ({
|
||||
},
|
||||
},
|
||||
documentMeta: true,
|
||||
team: {
|
||||
select: {
|
||||
teamEmail: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const customEmail = document?.documentMeta;
|
||||
const isTeamDocument = document?.team !== null;
|
||||
|
||||
if (!document) {
|
||||
throw new Error('Document not found');
|
||||
@ -90,9 +97,21 @@ export const resendDocument = async ({
|
||||
const { email, name } = recipient;
|
||||
const selfSigner = email === user.email;
|
||||
|
||||
const selfSignerCustomEmail = `You have initiated the document ${`"${document.title}"`} that requires you to ${RECIPIENT_ROLES_DESCRIPTION[
|
||||
recipient.role
|
||||
].actionVerb.toLowerCase()} it.`;
|
||||
const { actionVerb } = RECIPIENT_ROLES_DESCRIPTION[recipient.role];
|
||||
const recipientActionVerb = actionVerb.toLowerCase();
|
||||
|
||||
let emailMessage = customEmail?.message || '';
|
||||
let emailSubject = `Reminder: Please ${recipientActionVerb} this document`;
|
||||
|
||||
if (selfSigner) {
|
||||
emailMessage = `You have initiated the document ${`"${document.title}"`} that requires you to ${recipientActionVerb} it.`;
|
||||
emailSubject = `Reminder: Please ${recipientActionVerb} your document`;
|
||||
}
|
||||
|
||||
if (isTeamDocument && document.team) {
|
||||
emailSubject = `Reminder: ${document.team.name} invited you to ${recipientActionVerb} a document`;
|
||||
emailMessage = `${user.name} on behalf of ${document.team.name} has invited you to ${recipientActionVerb} the document "${document.title}".`;
|
||||
}
|
||||
|
||||
const customEmailTemplate = {
|
||||
'signer.name': name,
|
||||
@ -109,20 +128,14 @@ export const resendDocument = async ({
|
||||
inviterEmail: user.email,
|
||||
assetBaseUrl,
|
||||
signDocumentLink,
|
||||
customBody: renderCustomEmailTemplate(
|
||||
selfSigner && !customEmail?.message ? selfSignerCustomEmail : customEmail?.message || '',
|
||||
customEmailTemplate,
|
||||
),
|
||||
customBody: renderCustomEmailTemplate(emailMessage, customEmailTemplate),
|
||||
role: recipient.role,
|
||||
selfSigner,
|
||||
isTeamInvite: isTeamDocument,
|
||||
teamName: document.team?.name,
|
||||
teamEmail: document.team?.teamEmail?.email,
|
||||
});
|
||||
|
||||
const { actionVerb } = RECIPIENT_ROLES_DESCRIPTION[recipient.role];
|
||||
|
||||
const emailSubject = selfSigner
|
||||
? `Reminder: Please ${actionVerb.toLowerCase()} your document`
|
||||
: `Reminder: Please ${actionVerb.toLowerCase()} this document`;
|
||||
|
||||
await prisma.$transaction(
|
||||
async (tx) => {
|
||||
await mailer.sendMail({
|
||||
|
||||
Reference in New Issue
Block a user