diff --git a/apps/web/components/eventtype/CustomEventTypeModal.tsx b/apps/web/components/eventtype/CustomEventTypeModal.tsx index 5a6ab8c5c4..441f191301 100644 --- a/apps/web/components/eventtype/CustomEventTypeModal.tsx +++ b/apps/web/components/eventtype/CustomEventTypeModal.tsx @@ -53,8 +53,12 @@ const CustomEventTypeModalForm: FC = (props) => { type="text" placeholder={placeHolder_} {...register("customEventName", { - validate: (value) => - validateCustomEventName(value, t("invalid_event_name_variables"), event.bookingFields), + validate: (value) => { + const validationResult = validateCustomEventName(value, event.bookingFields); + return typeof validationResult === "string" + ? t("invalid_event_name_variables", { item: validationResult }) + : validationResult; + }, })} className="mb-0" /> diff --git a/apps/web/modules/event-types/views/event-types-single-view.tsx b/apps/web/modules/event-types/views/event-types-single-view.tsx index 5e6ea48098..1110a81f5e 100644 --- a/apps/web/modules/event-types/views/event-types-single-view.tsx +++ b/apps/web/modules/event-types/views/event-types-single-view.tsx @@ -384,13 +384,15 @@ const EventTypePage = (props: EventTypeSetupProps & { allActiveWorkflows?: Workf // Make it optional because it's not submitted from all tabs of the page eventName: z .string() - .refine( - (val) => - validateCustomEventName(val, t("invalid_event_name_variables"), bookingFields) === true, - { - message: t("invalid_event_name_variables"), + .superRefine((val, ctx) => { + const validationResult = validateCustomEventName(val, bookingFields); + if (validationResult !== true) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: t("invalid_event_name_variables", { item: validationResult }), + }); } - ) + }) .optional(), length: z.union([z.string().transform((val) => +val), z.number()]).optional(), offsetStart: z.union([z.string().transform((val) => +val), z.number()]).optional(), diff --git a/apps/web/public/static/locales/en/common.json b/apps/web/public/static/locales/en/common.json index 4d0d6bf1ba..73fa6b2594 100644 --- a/apps/web/public/static/locales/en/common.json +++ b/apps/web/public/static/locales/en/common.json @@ -1926,7 +1926,7 @@ "cancel_url_info": "The URL to cancel the booking", "reschedule_url_variable": "Reschedule URL", "reschedule_url_info": "The URL to reschedule the booking", - "invalid_event_name_variables": "There is an invalid variable in your event name", + "invalid_event_name_variables": "{{item}} is an invalid variable in your event name", "select_all": "Select All", "default_conferencing_bulk_title": "Bulk update existing event types", "members_default_schedule": "Member's default schedule", diff --git a/packages/core/event.test.ts b/packages/core/event.test.ts index 4e4195b570..d0580b2f13 100644 --- a/packages/core/event.test.ts +++ b/packages/core/event.test.ts @@ -356,7 +356,7 @@ describe("event tests", () => { describe("fn: validateCustomEventName", () => { it("should be valid when no variables used", () => { - expect(event.validateCustomEventName("foo", "error message")).toBe(true); + expect(event.validateCustomEventName("foo")).toBe(true); }); [ @@ -371,24 +371,24 @@ describe("event tests", () => { "USER", ].forEach((value) => { it(`should support {${value}} variable`, () => { - expect(event.validateCustomEventName(`foo {${value}} bar`, "error message")).toBe(true); + expect(event.validateCustomEventName(`foo {${value}} bar`)).toBe(true); - expect(event.validateCustomEventName(`{${value}} bar`, "error message")).toBe(true); + expect(event.validateCustomEventName(`{${value}} bar`)).toBe(true); - expect(event.validateCustomEventName(`foo {${value}}`, "error message")).toBe(true); + expect(event.validateCustomEventName(`foo {${value}}`)).toBe(true); }); }); it("should support booking field variables", () => { expect( - event.validateCustomEventName("foo{customField}bar", "error message", { + event.validateCustomEventName("foo{customField}bar", { customField: true, }) ).toBe(true); }); - it("should return error when invalid variable used", () => { - expect(event.validateCustomEventName("foo{nonsenseField}bar", "error message")).toBe("error message"); + it("should return variable when invalid variable used", () => { + expect(event.validateCustomEventName("foo{nonsenseField}bar")).toBe("{nonsenseField}"); }); }); }); diff --git a/packages/core/event.ts b/packages/core/event.ts index 0b39a1752a..0383b7ec83 100644 --- a/packages/core/event.ts +++ b/packages/core/event.ts @@ -100,11 +100,7 @@ export function getEventName(eventNameObj: EventNameObjectType, forAttendeeView return dynamicEventName; } -export const validateCustomEventName = ( - value: string, - message: string, - bookingFields?: Prisma.JsonObject -) => { +export const validateCustomEventName = (value: string, bookingFields?: Prisma.JsonObject) => { let customInputVariables: string[] = []; if (bookingFields) { customInputVariables = Object.keys(bookingFields).map((customInput) => { @@ -131,7 +127,7 @@ export const validateCustomEventName = ( if (matches?.length) { for (const item of matches) { if (!validVariables.includes(item)) { - return message; + return item; } } }