diff --git a/apps/web/pages/booking/[uid].tsx b/apps/web/pages/booking/[uid].tsx index 4c5a973214..fe3ab436a9 100644 --- a/apps/web/pages/booking/[uid].tsx +++ b/apps/web/pages/booking/[uid].tsx @@ -165,10 +165,14 @@ export default function Success(props: SuccessProps) { ); } + let evtName = props.eventType.eventName; + if (eventType.isDynamic && bookingInfo.responses?.title) { + evtName = bookingInfo.responses.title as string; + } const eventNameObject = { attendeeName, eventType: props.eventType.title, - eventName: (props.dynamicEventName as string) || props.eventType.eventName, + eventName: evtName, host: props.profile.name || "Nameless", location: location, bookingFields: bookingInfo.responses, diff --git a/apps/web/public/static/locales/en/common.json b/apps/web/public/static/locales/en/common.json index bd0ed3abe5..97abe8df39 100644 --- a/apps/web/public/static/locales/en/common.json +++ b/apps/web/public/static/locales/en/common.json @@ -1962,5 +1962,6 @@ "org_team_names_example_4": "e.g. Engineering Team", "org_team_names_example_5": "e.g. Data Analytics Team", "org_max_team_warnings": "You will be able to add more teams later on.", + "what_is_this_meeting_about": "What is this meeting about?", "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑" } diff --git a/packages/features/bookings/Booker/components/BookEventForm/BookEventForm.tsx b/packages/features/bookings/Booker/components/BookEventForm/BookEventForm.tsx index fdf969deba..baf84e1947 100644 --- a/packages/features/bookings/Booker/components/BookEventForm/BookEventForm.tsx +++ b/packages/features/bookings/Booker/components/BookEventForm/BookEventForm.tsx @@ -172,11 +172,14 @@ export const BookEventForm = ({ onCancel }: BookEventFormProps) => { return defaults; }, [eventType?.bookingFields, formValues, isRescheduling, bookingData, rescheduleUid]); + const disableBookingTitle = !!event.data?.isDynamic; const bookingFormSchema = z .object({ responses: event?.data ? getBookingResponsesSchema({ - eventType: { bookingFields: getBookingFieldsWithSystemFields(event.data) }, + eventType: { + bookingFields: getBookingFieldsWithSystemFields({ ...event.data, disableBookingTitle }), + }, view: rescheduleUid ? "reschedule" : "booking", }) : // Fallback until event is loaded. diff --git a/packages/features/bookings/lib/SystemField.ts b/packages/features/bookings/lib/SystemField.ts index af940a8e2e..3cd28eca72 100644 --- a/packages/features/bookings/lib/SystemField.ts +++ b/packages/features/bookings/lib/SystemField.ts @@ -4,6 +4,7 @@ export const SystemField = z.enum([ "name", "email", "location", + "title", "notes", "guests", "rescheduleReason", diff --git a/packages/features/bookings/lib/getBookingFields.ts b/packages/features/bookings/lib/getBookingFields.ts index d87d15afe0..62e55ec7ec 100644 --- a/packages/features/bookings/lib/getBookingFields.ts +++ b/packages/features/bookings/lib/getBookingFields.ts @@ -56,12 +56,14 @@ export const getSmsReminderNumberSource = ({ export const getBookingFieldsWithSystemFields = ({ bookingFields, disableGuests, + disableBookingTitle, customInputs, metadata, workflows, }: { bookingFields: Fields | EventType["bookingFields"]; disableGuests: boolean; + disableBookingTitle?: boolean; customInputs: EventTypeCustomInput[] | z.infer[]; metadata: EventType["metadata"] | z.infer; workflows: Prisma.EventTypeGetPayload<{ @@ -86,6 +88,7 @@ export const getBookingFieldsWithSystemFields = ({ return ensureBookingInputsHaveSystemFields({ bookingFields: parsedBookingFields, disableGuests, + disableBookingTitle, additionalNotesRequired: parsedMetaData?.additionalNotesRequired || false, customInputs: parsedCustomInputs, workflows, @@ -95,12 +98,14 @@ export const getBookingFieldsWithSystemFields = ({ export const ensureBookingInputsHaveSystemFields = ({ bookingFields, disableGuests, + disableBookingTitle, additionalNotesRequired, customInputs, workflows, }: { bookingFields: Fields; disableGuests: boolean; + disableBookingTitle?: boolean; additionalNotesRequired: boolean; customInputs: z.infer[]; workflows: Prisma.EventTypeGetPayload<{ @@ -119,6 +124,7 @@ export const ensureBookingInputsHaveSystemFields = ({ }>["workflows"]; }) => { // If bookingFields is set already, the migration is done. + const hideBookingTitle = disableBookingTitle ?? true; const handleMigration = !bookingFields.length; const CustomInputTypeToFieldType = { [EventTypeCustomInputType.TEXT]: BookingFieldTypeEnum.text, @@ -208,6 +214,22 @@ export const ensureBookingInputsHaveSystemFields = ({ // These fields should be added after other user fields const systemAfterFields: typeof bookingFields = [ + { + defaultLabel: "what_is_this_meeting_about", + type: "text", + name: "title", + editable: "system-but-optional", + required: true, + hidden: hideBookingTitle, + defaultPlaceholder: "", + sources: [ + { + label: "Default", + id: "default", + type: "default", + }, + ], + }, { defaultLabel: "additional_notes", type: "textarea", diff --git a/packages/features/bookings/lib/handleNewBooking.ts b/packages/features/bookings/lib/handleNewBooking.ts index b57af84ff4..ff5576b172 100644 --- a/packages/features/bookings/lib/handleNewBooking.ts +++ b/packages/features/bookings/lib/handleNewBooking.ts @@ -386,6 +386,7 @@ const getEventTypesFromDB = async (eventTypeId: number) => { customInputs: customInputSchema.array().parse(eventType?.customInputs || []), locations: (eventType?.locations ?? []) as LocationObject[], bookingFields: getBookingFieldsWithSystemFields(eventType || {}), + isDynamic: false, }; }; @@ -973,11 +974,12 @@ async function handler( const responses = "responses" in reqBody ? reqBody.responses : null; + const evtName = !eventType?.isDynamic ? eventType.eventName : responses?.title; const eventNameObject = { //TODO: Can we have an unnamed attendee? If not, I would really like to throw an error here. attendeeName: fullName || "Nameless", eventType: eventType.title, - eventName: eventType.eventName, + eventName: evtName, // we send on behalf of team if >1 round robin attendee | collective teamName: eventType.schedulingType === "COLLECTIVE" || users.length > 1 ? eventType.team?.name : null, // TODO: Can we have an unnamed organizer? If not, I would really like to throw an error here. diff --git a/packages/features/eventtypes/lib/getPublicEvent.ts b/packages/features/eventtypes/lib/getPublicEvent.ts index c601c619de..547870d141 100644 --- a/packages/features/eventtypes/lib/getPublicEvent.ts +++ b/packages/features/eventtypes/lib/getPublicEvent.ts @@ -131,10 +131,10 @@ export const getPublicEvent = async ( enabledLayouts: [...bookerLayoutOptions], defaultLayout: BookerLayouts.MONTH_VIEW, } as BookerLayoutSettings; - + const disableBookingTitle = !defaultEvent.isDynamic; return { ...defaultEvent, - bookingFields: getBookingFieldsWithSystemFields(defaultEvent), + bookingFields: getBookingFieldsWithSystemFields({ ...defaultEvent, disableBookingTitle }), // Clears meta data since we don't want to send this in the public api. users: users.map((user) => ({ ...user, metadata: undefined })), locations: privacyFilteredLocations(locations), @@ -201,6 +201,7 @@ export const getPublicEvent = async ( profile: getProfileFromEvent(event), users, orgDomain: org, + isDynamic: false, }; }; diff --git a/packages/lib/defaultEvents.ts b/packages/lib/defaultEvents.ts index d0f85ce8f1..2a71c28d9c 100644 --- a/packages/lib/defaultEvents.ts +++ b/packages/lib/defaultEvents.ts @@ -101,6 +101,7 @@ const commons = { customInputs: [], // Default value of disableGuests from DB. disableGuests: false, + disableBookingTitle: false, metadata: {}, workflows: [], }),