Skip to content

Conversation

@jadhavharshh
Copy link
Contributor

What does this PR do?

This PR implements the "Custom calendar event description" feature, allowing users to customize the description text that appears in calendar events created upon booking.

Key Changes:

  • Database: Added calendarEventDescription field to the EventType model.

  • Frontend:

    • Added a new setting in the Advanced tab of Event Types to enable custom calendar descriptions.
    • Implemented CustomCalendarDescriptionModal which provides a UI to draft the description with support for dynamic variables (e.g., {Scheduler}, {Organiser}, {Location}) and real-time preview.
  • Backend:

    • Updated CalendarManager and CalEventParser to prioritize the custom description template (if set) over the default auto-generated rich description.
    • Implemented variable substitution logic for the calendar description, reusing the existing getEventName logic.
  • Fixes Customize the title and description of the calendar events that the client can add to their calendar #25486 (GitHub issue number)

  • Fixes CAL-6839 (Linear issue number - should be visible at the bottom of the GitHub issue description)

Visual Demo (For contributors especially)

A visual demonstration is strongly recommended, for both the original and new change (video / image - any one).

Image Demo (if applicable):

image

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  1. Setup: Ensure you have an Event Type created.
  2. Configuration:
    • Navigate to the Advanced tab of the Event Type settings.
    • Locate the Calendar event description section.
    • Click the pencil icon/edit button to open the customization modal.
    • Enter a custom description using available variables (e.g., "Meeting with {Scheduler} about {Event type title}").
    • Save the Event Type.
  3. Booking Flow:
    • Book a slot for this Event Type.
    • On the booking success page, click on one of the "Add to Calendar" icons (e.g., Google Calendar).
  4. Verification:
    • This will open the calendar provider with the event details pre-filled.
    • Expected: Verify that the event description in the calendar view matches your custom template with variables replaced by actual values.
    • Fallback Test: Clear the custom description and verify the system falls back to the default rich description behavior.

Copilot AI review requested due to automatic review settings December 6, 2025 15:31
@jadhavharshh jadhavharshh requested a review from a team as a code owner December 6, 2025 15:31
@graphite-app graphite-app bot added the community Created by Linear-GitHub Sync label Dec 6, 2025
@vercel
Copy link

vercel bot commented Dec 6, 2025

@jadhavharshh is attempting to deploy a commit to the cal Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions bot added Low priority Created by Linear-GitHub Sync ✨ feature New feature or request ❗️ migrations contains migration files and removed ✨ feature New feature or request Low priority Created by Linear-GitHub Sync labels Dec 6, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Dec 6, 2025

Hey there and thank you for opening this pull request! 👋🏼

We require pull request titles to follow the Conventional Commits specification and it looks like your proposed title needs to be adjusted.

Details:

No release type found in pull request title "   feat: add custom calendar event description #25486". Add a prefix to indicate what kind of release this pull request corresponds to. For reference, see https://www.conventionalcommits.org/

Available types:
 - feat: A new feature
 - fix: A bug fix
 - docs: Documentation only changes
 - style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
 - refactor: A code change that neither fixes a bug nor adds a feature
 - perf: A code change that improves performance
 - test: Adding missing tests or correcting existing tests
 - build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
 - ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
 - chore: Other changes that don't modify src or test files
 - revert: Reverts a previous commit

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 16 files

Prompt for AI agents (all 1 issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="packages/features/eventtypes/components/tabs/advanced/EventAdvancedTab.tsx">

<violation number="1" location="packages/features/eventtypes/components/tabs/advanced/EventAdvancedTab.tsx:251">
P2: Consider using `t()` for the aria-label to ensure proper localization. While this follows the existing pattern for the &#39;edit custom name&#39; button, accessibility text should ideally be localized for screen reader users in different locales.</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Ask questions if you need clarification on any suggestion

Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a custom calendar event description feature that allows users to personalize the description text in calendar events created upon booking. The feature enables dynamic variable substitution (e.g., {Scheduler}, {Location}, {Event type title}) and provides a user-friendly modal interface for configuration.

Key Changes

  • Database Schema: Added calendarEventDescription nullable string field to EventType model
  • Frontend UI: Implemented CustomCalendarDescriptionModal component with variable selector, real-time preview, and validation in the Event Type Advanced tab
  • Backend Processing: Variable substitution logic integrated in CalendarManager, getCalendarLinks, BookingEmailSmsHandler, and email ICS generation to replace template variables with actual booking data

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/prisma/schema.prisma Added calendarEventDescription field to EventType model
packages/prisma/migrations/20251206092554_add_calendar_event_description/migration.sql Database migration for new field
packages/types/Calendar.d.ts Added calendarEventDescription to CalendarEvent type
packages/lib/server/eventTypeSelect.ts Included new field in event type selection queries
packages/features/eventtypes/repositories/eventTypeRepository.ts Added field to repository select queries
packages/features/eventtypes/lib/types.ts Added field to FormValues type definition
packages/features/eventtypes/components/tabs/advanced/EventAdvancedTab.tsx Added UI control and modal trigger for custom calendar descriptions
packages/features/eventtypes/components/tabs/advanced/CustomCalendarDescriptionModal.tsx New modal component for editing calendar descriptions with variable support and preview
packages/features/calendars/lib/CalendarManager.ts Variable substitution logic for calendar event creation
packages/features/bookings/repositories/BookingRepository.ts Added field to booking repository queries
packages/features/bookings/lib/getCalendarLinks.ts Variable substitution for calendar download links
packages/features/bookings/lib/BookingEmailSmsHandler.ts Variable substitution for confirmed booking emails
packages/features/CalendarEventBuilder.ts Added field to event builder
packages/emails/lib/generateIcsString.ts Uses custom description in ICS file generation
apps/web/lib/booking.ts Added field to booking data queries
apps/web/public/static/locales/en/common.json Added localization strings for new feature

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +190 to +195
if (eventType.calendarEventDescription) {
eventDescription = getEventName(
{ ...eventNameObject, eventName: eventType.calendarEventDescription },
true
);
}
Copy link

Copilot AI Dec 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new custom calendar event description feature lacks test coverage. Since getCalendarLinks.test.ts exists with comprehensive tests for this function, consider adding tests to verify:

  1. That custom calendar descriptions are properly substituted with variables
  2. That the function falls back to the regular description when calendarEventDescription is not set
  3. That variable substitution works correctly with various booking field combinations

Example test case:

it("should use custom calendar description with variable substitution", () => {
  const eventType = {
    ...baseMockEventType,
    calendarEventDescription: "Meeting with {Scheduler} about {Event type title}",
  };
  const booking = {
    ...baseMockBooking,
    responses: { name: "John Doe" },
  };
  
  const result = getCalendarLinks({ booking, eventType, t: mockT });
  // Verify that the description contains "Meeting with John Doe about Test Title"
});

Copilot uses AI. Check for mistakes.
productId: "calcom/ics",
title: event.title,
description: getRichDescription(event, t),
description: event.calendarEventDescription || getRichDescription(event, t),
Copy link

Copilot AI Dec 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The custom calendar event description feature lacks test coverage. Since generateIcsString.test.ts exists with comprehensive tests for this function, consider adding a test to verify that calendarEventDescription is used correctly when present.

Example test case:

test("should use custom calendar description when provided", () => {
  const customDescription = "Custom meeting description with details";
  const event = buildCalendarEvent({
    iCalSequence: 0,
    attendees: [buildPerson()],
    calendarEventDescription: customDescription,
  });
  
  const icsString = generateIcsString({
    event: event,
    status: "CONFIRMED",
  });
  
  expect(icsString).toContain(customDescription);
  // Verify it doesn't contain the rich description
});

Copilot uses AI. Check for mistakes.
@jadhavharshh jadhavharshh changed the title feat: add custom calendar event description #25486 feat: add custom calendar event description #25486 Dec 7, 2025
@pull-request-size pull-request-size bot added size/XL and removed size/L labels Dec 7, 2025
@github-actions github-actions bot added Low priority Created by Linear-GitHub Sync ✨ feature New feature or request labels Dec 7, 2025
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (all 1 issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="packages/features/calendars/lib/CalendarManager.ts">

<violation number="1" location="packages/features/calendars/lib/CalendarManager.ts:527">
P2: Reordering the `seatsPerTimeSlot` nullification to after `getRichDescription` changes behavior for seated events in the fallback case (no custom description). Previously, `getRichDescription` received nullified `additionalNotes` and `userFieldsResponses` for seated events - now it receives the actual values, potentially exposing information in calendar descriptions that was previously hidden.

If this is intentional, consider adding a comment explaining the behavior change. If not, consider keeping the nullification before `getRichDescription` for the fallback case while still preserving `responses` for custom description variable substitution.</violation>
</file>

Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR

calendarDescription = getEventName(eventNameObject, true);
}

if (calEvent.seatsPerTimeSlot) {
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Reordering the seatsPerTimeSlot nullification to after getRichDescription changes behavior for seated events in the fallback case (no custom description). Previously, getRichDescription received nullified additionalNotes and userFieldsResponses for seated events - now it receives the actual values, potentially exposing information in calendar descriptions that was previously hidden.

If this is intentional, consider adding a comment explaining the behavior change. If not, consider keeping the nullification before getRichDescription for the fallback case while still preserving responses for custom description variable substitution.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/features/calendars/lib/CalendarManager.ts, line 527:

<comment>Reordering the `seatsPerTimeSlot` nullification to after `getRichDescription` changes behavior for seated events in the fallback case (no custom description). Previously, `getRichDescription` received nullified `additionalNotes` and `userFieldsResponses` for seated events - now it receives the actual values, potentially exposing information in calendar descriptions that was previously hidden.

If this is intentional, consider adding a comment explaining the behavior change. If not, consider keeping the nullification before `getRichDescription` for the fallback case while still preserving `responses` for custom description variable substitution.</comment>

<file context>
@@ -522,13 +516,21 @@ const processEvent = (calEvent: CalendarEvent): CalendarServiceEvent =&gt; {
     calendarDescription = getEventName(eventNameObject, true);
   }
 
+  if (calEvent.seatsPerTimeSlot) {
+    calEvent.responses = null;
+    calEvent.userFieldsResponses = null;
</file context>

✅ Addressed in f5edce1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community Created by Linear-GitHub Sync ✨ feature New feature or request Low priority Created by Linear-GitHub Sync ❗️ migrations contains migration files size/XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Customize the title and description of the calendar events that the client can add to their calendar

1 participant