Update CALCOM-5774 with the requested changes

CALCOM-5774-2^2^2
gitstart-calcom 2023-07-24 21:20:27 +00:00
commit b912eea5c8
6 changed files with 65 additions and 7 deletions

View File

@ -7,6 +7,7 @@ import { isPrismaObjOrUndefined, parseRecurringEvent } from "@calcom/lib";
import { getTranslation } from "@calcom/lib/server/i18n";
import prisma, { bookingMinimalSelect } from "@calcom/prisma";
import { BookingStatus, ReminderType } from "@calcom/prisma/enums";
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
import type { CalendarEvent } from "@calcom/types/Calendar";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
@ -50,6 +51,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
select: {
recurringEvent: true,
bookingFields: true,
metadata: true,
},
},
responses: true,
@ -108,7 +110,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
endTime: booking.endTime.toISOString(),
organizer: {
id: user.id,
email: user.email,
email: EventTypeMetaDataSchema.parse(booking.eventType?.metadata)?.organizerEmail || user.email,
name,
timeZone: user.timeZone,
language: { translate: tOrganizer, locale: user.locale ?? "en" },

View File

@ -445,7 +445,10 @@ export default function Success(props: SuccessProps) {
</span>
<Badge variant="blue">{t("Host")}</Badge>
</div>
<p className="text-default">{bookingInfo.user.email}</p>
<p className="text-default">
{EventTypeMetaDataSchema.parse(bookingInfo.eventType?.metadata)
?.organizerEmail || bookingInfo.user?.email}
</p>
</div>
)}
{bookingInfo?.attendees.map((attendee) => (
@ -1043,6 +1046,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
eventName: true,
slug: true,
timeZone: true,
metadata: true,
},
},
seatsReferences: {

View File

@ -168,6 +168,7 @@ const EventTypePage = (props: EventTypeSetupProps) => {
onlyInstalled: true,
});
const connectedCalendarsQuery = trpc.viewer.connectedCalendars.useQuery();
const { eventType, locationOptions, team, teamMembers, currentUserMembership, destinationCalendar } = props;
const [animationParentRef] = useAutoAnimate<HTMLDivElement>();
@ -458,6 +459,8 @@ const EventTypePage = (props: EventTypeSetupProps) => {
...input
} = values;
let emailMeta;
if (bookingLimits) {
const isValid = validateIntervalLimitOrder(bookingLimits);
if (!isValid) throw new Error(t("event_setup_booking_limits_error"));
@ -480,9 +483,24 @@ const EventTypePage = (props: EventTypeSetupProps) => {
}
}
}
const { availability, ...rest } = input;
if (connectedCalendarsQuery.data?.connectedCalendars.length && input.destinationCalendar) {
const organizerEmail = connectedCalendarsQuery.data?.connectedCalendars
.map((connected) => connected.primary)
.find((cal) => cal?.externalId === input.destinationCalendar.externalId)?.email;
emailMeta = { organizerEmail, isDefaultEmail: false };
}
if (!input.destinationCalendar) {
// when no email is selected, use default email in calendar
emailMeta = {
organizerEmail: connectedCalendarsQuery.data?.destinationCalendar.primaryEmail,
isDefaultEmail: true,
};
}
updateMutation.mutate({
...rest,
...input,
locations,
recurringEvent,
periodStartDate: periodDates.startDate,
@ -495,7 +513,7 @@ const EventTypePage = (props: EventTypeSetupProps) => {
durationLimits,
seatsPerTimeSlot,
seatsShowAttendees,
metadata,
metadata: { ...metadata, ...emailMeta },
customInputs,
});
}}>

View File

@ -28,6 +28,7 @@ import { bookingSuccessRedirect } from "@calcom/lib/bookingSuccessRedirect";
import { MINUTES_TO_BOOK } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { HttpError } from "@calcom/lib/http-error";
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
import { trpc } from "@calcom/trpc";
import { Form, Button, Alert, EmptyScreen } from "@calcom/ui";
import { Calendar } from "@calcom/ui/components/icon";
@ -49,6 +50,9 @@ export const BookEventForm = ({ onCancel }: BookEventFormProps) => {
const removeSelectedSlot = trpc.viewer.public.slots.removeSelectedSlotMark.useMutation({
trpc: { context: { skipBatch: true } },
});
const { data: connectedCalendars, isLoading: connectedCalendarLoading } =
trpc.viewer.connectedCalendars.useQuery();
const updateEventTypeMutation = trpc.viewer.eventTypes.update.useMutation();
const router = useRouter();
const { t, i18n } = useLocale();
const { timezone } = useTimePreferences();
@ -66,6 +70,7 @@ export const BookEventForm = ({ onCancel }: BookEventFormProps) => {
const isRescheduling = !!rescheduleUid && !!bookingData;
const event = useEvent();
const eventType = event.data;
const defaultEmail = connectedCalendars?.destinationCalendar?.primaryEmail;
const reserveSlot = () => {
if (eventType?.id && timeslot && (duration || eventType?.length)) {
@ -321,6 +326,26 @@ export const BookEventForm = ({ onCancel }: BookEventFormProps) => {
),
};
const eventMeta = EventTypeMetaDataSchema.parse(eventType?.metadata);
if (!defaultEmail) {
delete eventMeta?.organizerEmail;
delete eventMeta?.isDefaultEmail;
updateEventTypeMutation.mutate({
metadata: { ...eventMeta },
id: event?.data.id,
});
}
// if email in use is default email and not same with current default email, update organizerEmail
if (eventMeta?.isDefaultEmail && eventMeta?.organizerEmail !== defaultEmail) {
updateEventTypeMutation.mutate({
metadata: { ...eventMeta, organizerEmail: defaultEmail },
id: event?.data.id,
});
}
if (event.data?.recurringEvent?.freq && recurringEventCount) {
createRecurringBookingMutation.mutate(
mapRecurringBookingToMutationInput(bookingInput, recurringEventCount)
@ -382,7 +407,11 @@ export const BookEventForm = ({ onCancel }: BookEventFormProps) => {
<Button
type="submit"
color="primary"
loading={createBookingMutation.isLoading || createRecurringBookingMutation.isLoading}
loading={
createBookingMutation.isLoading ||
createRecurringBookingMutation.isLoading ||
connectedCalendarLoading
}
data-testid={rescheduleUid ? "confirm-reschedule-button" : "confirm-book-button"}>
{rescheduleUid ? t("reschedule") : t("confirm")}
</Button>

View File

@ -1029,7 +1029,10 @@ async function handler(
organizer: {
id: organizerUser.id,
name: organizerUser.name || "Nameless",
email: organizerUser.email || "Email-less",
email:
EventTypeMetaDataSchema.parse(eventType.metadata)?.organizerEmail ||
organizerUser.email ||
"Email-less",
username: organizerUser.username || undefined,
timeZone: organizerUser.timeZone,
language: { translate: tOrganizer, locale: organizerUser.locale ?? "en" },

View File

@ -71,6 +71,8 @@ export const RequiresConfirmationThresholdUnits: z.ZodType<UnitTypeLongPlural> =
export const EventTypeMetaDataSchema = z
.object({
organizerEmail: z.string().optional(),
isDefaultEmail: z.boolean().optional(),
smartContractAddress: z.string().optional(),
blockchainId: z.number().optional(),
multipleDuration: z.number().array().optional(),