Skip to content

Commit 9b88603

Browse files
volneikart1ka
andauthored
fix: Remove cancel and reschedule links from email when event type doesn't allow (calcom#22653)
Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
1 parent c88ed8c commit 9b88603

7 files changed

Lines changed: 38 additions & 5 deletions

File tree

packages/emails/src/components/ManageLink.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getCancelLink, getRescheduleLink, getBookingUrl } from "@calcom/lib/CalEventParser";
1+
import { getBookingUrl, getCancelLink, getRescheduleLink } from "@calcom/lib/CalEventParser";
22
import type { CalendarEvent, Person } from "@calcom/types/Calendar";
33

44
export function ManageLink(props: { calEvent: CalendarEvent; attendee: Person }) {
@@ -11,8 +11,8 @@ export function ManageLink(props: { calEvent: CalendarEvent; attendee: Person })
1111

1212
const isOriginalAttendee = props.attendee.email === props.calEvent.attendees[0]?.email;
1313
const isOrganizer = props.calEvent.organizer.email === props.attendee.email;
14-
const hasCancelLink = Boolean(cancelLink);
15-
const hasRescheduleLink = Boolean(rescheduleLink);
14+
const hasCancelLink = Boolean(cancelLink) && !props.calEvent.disableCancelling;
15+
const hasRescheduleLink = Boolean(rescheduleLink) && !props.calEvent.disableRescheduling;
1616
const hasBookingLink = Boolean(bookingLink);
1717
const isRecurringEvent = props.calEvent.recurringEvent;
1818
const shouldDisplayRescheduleLink = Boolean(hasRescheduleLink && !isRecurringEvent);
@@ -39,8 +39,7 @@ export function ManageLink(props: { calEvent: CalendarEvent; attendee: Person })
3939
textAlign: "center",
4040
width: "100%",
4141
}}>
42-
<>{t("need_to_make_a_change")}</>
43-
42+
{(shouldDisplayRescheduleLink || hasCancelLink) && <>{t("need_to_make_a_change")}</>}
4443
{shouldDisplayRescheduleLink && (
4544
<span>
4645
<a

packages/features/CalendarEventBuilder.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,4 +687,26 @@ describe("CalendarEventBuilder", () => {
687687
expect(event.title).toBe("Updated Event");
688688
expect(event.type).toBe("existing-type");
689689
});
690+
691+
it("should propagate disableCancelling and disableRescheduling", () => {
692+
const event = new CalendarEventBuilder()
693+
.withBasicDetails({
694+
bookerUrl: "https://cal.com/user/test-slug",
695+
title: "Test Event",
696+
startTime: mockStartTime,
697+
endTime: mockEndTime,
698+
additionalNotes: "Some notes",
699+
})
700+
.withEventType({
701+
slug: "test-slug",
702+
description: "Test description",
703+
id: 123,
704+
disableCancelling: true,
705+
disableRescheduling: true,
706+
})
707+
.build();
708+
709+
expect(event.disableCancelling).toBe(true);
710+
expect(event.disableRescheduling).toBe(true);
711+
});
690712
});

packages/features/CalendarEventBuilder.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ export class CalendarEventBuilder {
5353
seatsShowAttendees?: boolean | null;
5454
seatsShowAvailabilityCount?: boolean | null;
5555
customReplyToEmail?: string | null;
56+
disableRescheduling?: boolean;
57+
disableCancelling?: boolean;
5658
}) {
5759
this.event = {
5860
...this.event,
@@ -68,6 +70,8 @@ export class CalendarEventBuilder {
6870
seatsShowAttendees: eventType.seatsPerTimeSlot ? eventType.seatsShowAttendees : true,
6971
seatsShowAvailabilityCount: eventType.seatsPerTimeSlot ? eventType.seatsShowAvailabilityCount : true,
7072
customReplyToEmail: eventType.customReplyToEmail,
73+
disableRescheduling: eventType.disableRescheduling ?? false,
74+
disableCancelling: eventType.disableCancelling ?? false,
7175
};
7276
return this;
7377
}

packages/features/bookings/lib/handleNewBooking.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,8 @@ async function handler(
11291129
seatsShowAttendees: eventType.seatsPerTimeSlot ? eventType.seatsShowAttendees : true,
11301130
seatsShowAvailabilityCount: eventType.seatsPerTimeSlot ? eventType.seatsShowAvailabilityCount : true,
11311131
customReplyToEmail: eventType.customReplyToEmail,
1132+
disableRescheduling: eventType.disableRescheduling ?? false,
1133+
disableCancelling: eventType.disableCancelling ?? false,
11321134
})
11331135
.withOrganizer({
11341136
id: organizerUser.id,

packages/features/bookings/lib/handleNewBooking/getEventTypesFromDB.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ export const getEventTypesFromDB = async (eventTypeId: number) => {
2323
disableGuests: true,
2424
restrictionScheduleId: true,
2525
useBookerTimezone: true,
26+
disableRescheduling: true,
27+
disableCancelling: true,
2628
users: {
2729
select: {
2830
credentials: {

packages/lib/builders/CalendarEvent/builder.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ export class CalendarEventBuilder implements ICalendarEventBuilder {
147147
destinationCalendar: true,
148148
hideCalendarNotes: true,
149149
hideCalendarEventDetails: true,
150+
disableCancelling: true,
151+
disableRescheduling: true,
150152
},
151153
});
152154
} catch (error) {

packages/types/Calendar.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ export interface CalendarEvent {
206206
iCalUID?: string | null;
207207
iCalSequence?: number | null;
208208
hideOrganizerEmail?: boolean;
209+
disableCancelling?: boolean;
210+
disableRescheduling?: boolean;
209211

210212
// It has responses to all the fields(system + user)
211213
responses?: CalEventResponses | null;

0 commit comments

Comments
 (0)