From 68d40cabbe295d614ae568cd1b6f5a96dae90713 Mon Sep 17 00:00:00 2001
From: Somay Chauhan
Date: Wed, 20 Dec 2023 21:21:42 +0530
Subject: [PATCH] fix: Organization's Team invite emails (#12843)
Co-authored-by: Hariom
---
apps/web/public/static/locales/en/common.json | 3 ++
.../emails/src/templates/TeamInviteEmail.tsx | 28 +++++++++++++------
.../emails/templates/team-invite-email.ts | 21 ++++++++------
.../inviteMember/inviteMember.handler.ts | 1 +
.../viewer/teams/inviteMember/utils.ts | 6 +++-
.../viewer/teams/resendInvitation.handler.ts | 3 +-
6 files changed, 43 insertions(+), 19 deletions(-)
diff --git a/apps/web/public/static/locales/en/common.json b/apps/web/public/static/locales/en/common.json
index 4fb8a6f3a8..e553cc233f 100644
--- a/apps/web/public/static/locales/en/common.json
+++ b/apps/web/public/static/locales/en/common.json
@@ -143,6 +143,7 @@
"request_another_invitation_email": "If you prefer not to use {{toEmail}} as your {{appName}} email or already have a {{appName}} account, please request another invitation to that email.",
"you_have_been_invited": "You have been invited to join the team {{teamName}}",
"user_invited_you": "{{user}} invited you to join the {{entity}} {{team}} on {{appName}}",
+ "user_invited_you_to_subteam": "{{user}} invited you to join the team {{team}} of organization {{parentTeamName}} on {{appName}}",
"hidden_team_member_title": "You are hidden in this team",
"hidden_team_member_message": "Your seat is not paid for, either Upgrade to PRO or let the team owner know they can pay for your seat.",
"hidden_team_owner_message": "You need a pro account to use teams, you are hidden until you upgrade.",
@@ -1746,9 +1747,11 @@
"organizer_timezone": "Organizer timezone",
"email_user_cta": "View Invitation",
"email_no_user_invite_heading_team": "You’ve been invited to join a {{appName}} team",
+ "email_no_user_invite_heading_subteam": "You’ve been invited to join a team of {{parentTeamName}} organization",
"email_no_user_invite_heading_org": "You’ve been invited to join a {{appName}} organization",
"email_no_user_invite_subheading": "{{invitedBy}} has invited you to join their team on {{appName}}. {{appName}} is the event-juggling scheduler that enables you and your team to schedule meetings without the email tennis.",
"email_user_invite_subheading_team": "{{invitedBy}} has invited you to join their team `{{teamName}}` on {{appName}}. {{appName}} is the event-juggling scheduler that enables you and your team to schedule meetings without the email tennis.",
+ "email_user_invite_subheading_subteam": "{{invitedBy}} has invited you to join the team `{{teamName}}` in their organization {{parentTeamName}} on {{appName}}. {{appName}} is the event-juggling scheduler that enables you and your team to schedule meetings without the email tennis.",
"email_user_invite_subheading_org": "{{invitedBy}} has invited you to join their organization `{{teamName}}` on {{appName}}. {{appName}} is the event-juggling scheduler that enables you and your organization to schedule meetings without the email tennis.",
"email_no_user_invite_steps_intro": "We’ll walk you through a few short steps and you’ll be enjoying stress free scheduling with your {{entity}} in no time.",
"email_no_user_step_one": "Choose your username",
diff --git a/packages/emails/src/templates/TeamInviteEmail.tsx b/packages/emails/src/templates/TeamInviteEmail.tsx
index 4edc91c4e6..6742fb5e73 100644
--- a/packages/emails/src/templates/TeamInviteEmail.tsx
+++ b/packages/emails/src/templates/TeamInviteEmail.tsx
@@ -12,6 +12,7 @@ type TeamInvite = {
joinLink: string;
isCalcomMember: boolean;
isOrg: boolean;
+ parentTeamName: string | undefined;
};
export const TeamInviteEmail = (
@@ -19,17 +20,22 @@ export const TeamInviteEmail = (
) => {
return (
<>
- {props.language(`email_no_user_invite_heading_${props.isOrg ? "org" : "team"}`, {
- appName: APP_NAME,
- })}
+ {props.language(
+ `email_no_user_invite_heading_${props.isOrg ? "org" : props.parentTeamName ? "subteam" : "team"}`,
+ {
+ appName: APP_NAME,
+ parentTeamName: props.parentTeamName,
+ }
+ )}
>
<>
- {props.language(`email_user_invite_subheading_${props.isOrg ? "org" : "team"}`, {
- invitedBy: props.from,
- appName: APP_NAME,
- teamName: props.teamName,
- })}
+ {props.language(
+ `email_user_invite_subheading_${props.isOrg ? "org" : props.parentTeamName ? "subteam" : "team"}`,
+ {
+ invitedBy: props.from,
+ appName: APP_NAME,
+ teamName: props.teamName,
+ parentTeamName: props.parentTeamName,
+ }
+ )}
>
diff --git a/packages/emails/templates/team-invite-email.ts b/packages/emails/templates/team-invite-email.ts
index 6d272bd225..1c589ceec1 100644
--- a/packages/emails/templates/team-invite-email.ts
+++ b/packages/emails/templates/team-invite-email.ts
@@ -13,6 +13,7 @@ export type TeamInvite = {
joinLink: string;
isCalcomMember: boolean;
isOrg: boolean;
+ parentTeamName: string | undefined;
};
export default class TeamInviteEmail extends BaseEmail {
@@ -28,14 +29,18 @@ export default class TeamInviteEmail extends BaseEmail {
return {
to: this.teamInviteEvent.to,
from: `${APP_NAME} <${this.getMailerOptions().from}>`,
- subject: this.teamInviteEvent.language("user_invited_you", {
- user: this.teamInviteEvent.from,
- team: this.teamInviteEvent.teamName,
- appName: APP_NAME,
- entity: this.teamInviteEvent
- .language(this.teamInviteEvent.isOrg ? "organization" : "team")
- .toLowerCase(),
- }),
+ subject: this.teamInviteEvent.language(
+ `user_invited_you${this.teamInviteEvent.parentTeamName ? "_to_subteam" : ""}`,
+ {
+ user: this.teamInviteEvent.from,
+ team: this.teamInviteEvent.teamName,
+ appName: APP_NAME,
+ parentTeamName: this.teamInviteEvent.parentTeamName,
+ entity: this.teamInviteEvent
+ .language(this.teamInviteEvent.isOrg ? "organization" : "team")
+ .toLowerCase(),
+ }
+ ),
html: await renderEmail("TeamInviteEmail", this.teamInviteEvent),
text: "",
};
diff --git a/packages/trpc/server/routers/viewer/teams/inviteMember/inviteMember.handler.ts b/packages/trpc/server/routers/viewer/teams/inviteMember/inviteMember.handler.ts
index 0d7378c449..3796ebbef2 100644
--- a/packages/trpc/server/routers/viewer/teams/inviteMember/inviteMember.handler.ts
+++ b/packages/trpc/server/routers/viewer/teams/inviteMember/inviteMember.handler.ts
@@ -145,6 +145,7 @@ export const inviteMemberHandler = async ({ ctx, input }: InviteMemberOptions) =
language: translation,
isOrg: input.isOrg,
teamId: team.id,
+ currentUserParentTeamName: team?.parent?.name,
});
}
}
diff --git a/packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts b/packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
index 696576ef5e..5768055791 100644
--- a/packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
+++ b/packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
@@ -368,10 +368,11 @@ export async function sendVerificationEmail({
language: translation,
from: ctx.user.name || `${team.name}'s admin`,
to: usernameOrEmail,
- teamName: team?.parent?.name || team.name,
+ teamName: team.name,
joinLink: `${WEBAPP_URL}/signup?token=${token}&callbackUrl=/getting-started`,
isCalcomMember: false,
isOrg: input.isOrg,
+ parentTeamName: team?.parent?.name,
});
} else {
await sendOrganizationAutoJoinEmail({
@@ -478,12 +479,14 @@ export const sendTeamInviteEmails = async ({
language,
currentUserTeamName,
currentUserName,
+ currentUserParentTeamName,
isOrg,
teamId,
}: {
language: TFunction;
existingUsersWithMembersips: UserWithMembership[];
currentUserTeamName?: string;
+ currentUserParentTeamName: string | undefined;
currentUserName?: string | null;
isOrg: boolean;
teamId: number;
@@ -529,6 +532,7 @@ export const sendTeamInviteEmails = async ({
teamName: currentUserTeamName,
...inviteTeamOptions,
isOrg: isOrg,
+ parentTeamName: currentUserParentTeamName,
});
}
});
diff --git a/packages/trpc/server/routers/viewer/teams/resendInvitation.handler.ts b/packages/trpc/server/routers/viewer/teams/resendInvitation.handler.ts
index e7a58bd9ca..a3390fb8eb 100644
--- a/packages/trpc/server/routers/viewer/teams/resendInvitation.handler.ts
+++ b/packages/trpc/server/routers/viewer/teams/resendInvitation.handler.ts
@@ -51,9 +51,10 @@ export const resendInvitationHandler = async ({ ctx, input }: InviteMemberOption
language: translation,
from: ctx.user.name || `${team.name}'s admin`,
to: input.email,
- teamName: team?.parent?.name || team.name,
+ teamName: team.name,
...inviteTeamOptions,
isOrg: input.isOrg,
+ parentTeamName: team?.parent?.name,
});
return input;