Skip to content

Commit c9bd18e

Browse files
emrysaldevin-ai-integration[bot]cubic-dev-ai[bot]
authored
chore: Disables syncing of calendarList on overlay calendar fetch (calcom#27020)
* chore: Disables syncing of calendarList on overlay calendar fetch * Unwrap ToggledConnectedCalendars * Pick the right type for connectedCalendars * further type amends * Type fixes, tons of em * Some further fixups consistent with what was before * fix: resolve type incompatibility in getConnectedDestinationCalendars return type Co-Authored-By: alex@cal.com <me@alexvanandel.com> * fix: update DestinationCalendarProps to accept tRPC handler return type Co-Authored-By: alex@cal.com <me@alexvanandel.com> * fix: use generic type for DestinationCalendarProps to accept tRPC enriched types Co-Authored-By: alex@cal.com <me@alexvanandel.com> * fix: simplify DestinationCalendarProps type for better compatibility Co-Authored-By: alex@cal.com <me@alexvanandel.com> * fix: export ConnectedCalendar type for consistent type inference Co-Authored-By: alex@cal.com <me@alexvanandel.com> * fix: use permissive type for connectedCalendars to accept tRPC enriched types Co-Authored-By: alex@cal.com <me@alexvanandel.com> * fix: export ConnectedCalendar and ConnectedDestinationCalendars types from platform-libraries Co-Authored-By: alex@cal.com <me@alexvanandel.com> * fix: update ConnectedCalendar type to use boolean | null for primary field Co-Authored-By: alex@cal.com <me@alexvanandel.com> * Update ConnectedCalendarItem * Undo some of Devins fixes, more fixes * Fixup the destination calendar return type, historically not null * Change init to undefined to deal with null * Approach to connect selected calendars with the right credential * This return type is used way too much everywhere, not refactoring * Add the selectedCalendars to the type * Actually fix overlay calendar * set calendarsToLoad param as required * Apply suggestion from @cubic-dev-ai[bot] Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> * Add new translation for 'Calendar Settings' --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
1 parent c62f333 commit c9bd18e

22 files changed

Lines changed: 485 additions & 427 deletions

File tree

apps/web/components/apps/DestinationCalendarSettingsWebWrapper.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export const DestinationCalendarSettingsWebWrapper = ({
5050
};
5151

5252
const validatedReminderValue = reminderSchema.safeParse(
53-
calendars.data.destinationCalendar.customCalendarReminder
53+
calendars.data.destinationCalendar?.customCalendarReminder
5454
);
5555
let reminderValue: ReminderMinutes = null;
5656
if (validatedReminderValue.success) {
@@ -63,7 +63,7 @@ export const DestinationCalendarSettingsWebWrapper = ({
6363
connectedCalendars={calendars.data.connectedCalendars}
6464
isPending={mutation.isPending}
6565
destinationCalendar={calendars.data.destinationCalendar}
66-
value={calendars.data.destinationCalendar.externalId}
66+
value={calendars.data.destinationCalendar?.externalId}
6767
hidePlaceholder
6868
onChange={mutation.mutate}
6969
onReminderChange={handleReminderChange}

apps/web/components/getting-started/components/ConnectedCalendarItem.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ interface IConnectedCalendarItem {
66
externalId?: string;
77
integrationType: string;
88
calendars?: {
9-
primary: true | null;
9+
primary: boolean | null;
1010
isSelected: boolean;
1111
credentialId: number;
1212
name?: string | undefined;
@@ -18,15 +18,15 @@ interface IConnectedCalendarItem {
1818
}[];
1919
}
2020

21-
const ConnectedCalendarItem = (prop: IConnectedCalendarItem) => {
21+
const ConnectedCalendarItem = (prop: IConnectedCalendarItem): JSX.Element => {
2222
const { name, logo, externalId, calendars, integrationType } = prop;
2323

2424
return (
2525
<>
2626
<div className="flex flex-row items-center p-4">
2727
<img src={logo} alt={name} className="m-1 h-8 w-8" />
2828
<div className="mx-4">
29-
<p className="font-sans text-sm font-bold leading-5">
29+
<p className="font-bold font-sans text-sm leading-5">
3030
{name}
3131
{/* Temporarily removed till we use it on another place */}
3232
{/* <span className="mx-1 rounded-[4px] bg-cal-success py-[2px] px-[6px] font-sans text-xs font-medium text-green-600">
@@ -36,7 +36,7 @@ const ConnectedCalendarItem = (prop: IConnectedCalendarItem) => {
3636
<div className="fle-row flex">
3737
<span
3838
title={externalId}
39-
className="max-w-44 text-subtle mt-1 overflow-hidden text-ellipsis whitespace-nowrap font-sans text-sm">
39+
className="mt-1 max-w-44 overflow-hidden text-ellipsis whitespace-nowrap font-sans text-sm text-subtle">
4040
{externalId}{" "}
4141
</span>
4242
</div>
@@ -49,7 +49,7 @@ const ConnectedCalendarItem = (prop: IConnectedCalendarItem) => {
4949
{t("edit")}
5050
</Button> */}
5151
</div>
52-
<div className="border-subtle h-px w-full border-b" />
52+
<div className="h-px w-full border-subtle border-b" />
5353
<div>
5454
<ul className="p-4">
5555
{calendars?.map((calendar, i) => (

apps/web/modules/bookings/components/Booker.tsx

Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ const BookerComponent = ({
9393
roundRobinHideOrgAndTeam,
9494
hideOrgTeamAvatar,
9595
showNoAvailabilityDialog,
96-
}: BookerProps & WrappedBookerProps) => {
96+
}: BookerProps & WrappedBookerProps): JSX.Element | null => {
9797
const searchParams = useCompatSearchParams();
9898
const isPlatformBookerEmbed = useIsPlatformBookerEmbed();
9999
const [bookerState, setBookerState] = useBookerStoreContext(
@@ -180,13 +180,7 @@ const BookerComponent = ({
180180
isVerificationCodeSending,
181181
} = verifyEmail;
182182

183-
const {
184-
overlayBusyDates,
185-
isOverlayCalendarEnabled,
186-
connectedCalendars,
187-
loadingConnectedCalendar,
188-
onToggleCalendar,
189-
} = calendars;
183+
const { overlayBusyDates, isOverlayCalendarEnabled, connectedCalendars, onToggleCalendar } = calendars;
190184

191185
const scrolledToTimeslotsOnce = useRef(false);
192186
const embedUiConfig = useEmbedUiConfig();
@@ -276,7 +270,11 @@ const BookerComponent = ({
276270
renderConfirmNotVerifyEmailButtonCond ? handleBookEvent(timeSlot) : handleVerifyEmail();
277271

278272
const EventBooker = useMemo(() => {
279-
return bookerState === "booking" ? (
273+
if (bookerState !== "booking") {
274+
return null;
275+
}
276+
277+
return (
280278
<BookEventForm
281279
key={key}
282280
timeslot={selectedTimeslot}
@@ -312,22 +310,18 @@ const BookerComponent = ({
312310
backButton: customClassNames?.confirmStep?.backButton,
313311
}}
314312
isPlatform={isPlatform}>
315-
<>
316-
{!isPlatform && (
317-
<RedirectToInstantMeetingModal
318-
expiryTime={expiryTime}
319-
bookingId={parseInt(getQueryParam("bookingId") || "0")}
320-
instantVideoMeetingUrl={instantVideoMeetingUrl}
321-
onGoBack={() => {
322-
onGoBackInstantMeeting();
323-
}}
324-
orgName={event.data?.entity?.name}
325-
/>
326-
)}
327-
</>
313+
{!isPlatform && (
314+
<RedirectToInstantMeetingModal
315+
expiryTime={expiryTime}
316+
bookingId={parseInt(getQueryParam("bookingId") || "0")}
317+
instantVideoMeetingUrl={instantVideoMeetingUrl}
318+
onGoBack={() => {
319+
onGoBackInstantMeeting();
320+
}}
321+
orgName={event.data?.entity?.name}
322+
/>
323+
)}
328324
</BookEventForm>
329-
) : (
330-
<></>
331325
);
332326
}, [
333327
bookerFormErrorRef,
@@ -418,27 +412,23 @@ const BookerComponent = ({
418412
extraDays={layout === BookerLayouts.COLUMN_VIEW ? columnViewExtraDays.current : extraDays}
419413
isMobile={isMobile}
420414
nextSlots={nextSlots}
421-
renderOverlay={() =>
422-
isEmbed ? (
423-
<></>
424-
) : (
425-
<>
426-
<OverlayCalendar
427-
isOverlayCalendarEnabled={isOverlayCalendarEnabled}
428-
connectedCalendars={connectedCalendars}
429-
loadingConnectedCalendar={loadingConnectedCalendar}
430-
overlayBusyDates={overlayBusyDates}
431-
onToggleCalendar={onToggleCalendar}
432-
hasSession={hasSession}
433-
handleClickContinue={onClickOverlayContinue}
434-
handleSwitchStateChange={onOverlaySwitchStateChange}
435-
handleClickNoCalendar={() => {
436-
onOverlayClickNoCalendar();
437-
}}
438-
/>
439-
</>
440-
)
441-
}
415+
renderOverlay={() => {
416+
if (isEmbed) return null;
417+
return (
418+
<OverlayCalendar
419+
isOverlayCalendarEnabled={isOverlayCalendarEnabled}
420+
connectedCalendars={connectedCalendars}
421+
overlayBusyDates={overlayBusyDates}
422+
onToggleCalendar={onToggleCalendar}
423+
hasSession={hasSession}
424+
handleClickContinue={onClickOverlayContinue}
425+
handleSwitchStateChange={onOverlaySwitchStateChange}
426+
handleClickNoCalendar={() => {
427+
onOverlayClickNoCalendar();
428+
}}
429+
/>
430+
);
431+
}}
442432
/>
443433
)}
444434
</BookerSection>

apps/web/modules/bookings/components/BookerWebWrapper.tsx

Lines changed: 18 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
"use client";
22

3-
import { useSession } from "next-auth/react";
4-
import { useSearchParams, usePathname, useRouter } from "next/navigation";
5-
import { useMemo, useCallback, useEffect } from "react";
6-
import React from "react";
7-
import { shallow } from "zustand/shallow";
8-
93
import { sdkActionManager, useIsEmbed } from "@calcom/embed-core/embed-iframe";
104
import { useBookerEmbedEvents } from "@calcom/embed-core/src/embed-iframe/react-hooks";
115
import type { BookerProps } from "@calcom/features/bookings/Booker";
126
import {
137
BookerStoreProvider,
14-
useInitializeBookerStoreContext,
158
useBookerStoreContext,
9+
useInitializeBookerStoreContext,
1610
} from "@calcom/features/bookings/Booker/BookerStoreProvider";
1711
import { useBookerLayout } from "@calcom/features/bookings/Booker/components/hooks/useBookerLayout";
1812
import { useBookingForm } from "@calcom/features/bookings/Booker/components/hooks/useBookingForm";
@@ -22,27 +16,23 @@ import { useSlots } from "@calcom/features/bookings/Booker/components/hooks/useS
2216
import { useVerifyCode } from "@calcom/features/bookings/Booker/components/hooks/useVerifyCode";
2317
import { useVerifyEmail } from "@calcom/features/bookings/Booker/components/hooks/useVerifyEmail";
2418
import { useInitializeBookerStore } from "@calcom/features/bookings/Booker/store";
25-
import {
26-
useEvent,
27-
useScheduleForEvent,
28-
} from "@calcom/features/bookings/Booker/utils/event";
19+
import { useEvent, useScheduleForEvent } from "@calcom/features/bookings/Booker/utils/event";
2920
import { useBrandColors } from "@calcom/features/bookings/Booker/utils/use-brand-colors";
3021
import type { getPublicEvent } from "@calcom/features/eventtypes/lib/getPublicEvent";
31-
import {
32-
DEFAULT_LIGHT_BRAND_COLOR,
33-
DEFAULT_DARK_BRAND_COLOR,
34-
WEBAPP_URL,
35-
} from "@calcom/lib/constants";
22+
import { DEFAULT_DARK_BRAND_COLOR, DEFAULT_LIGHT_BRAND_COLOR, WEBAPP_URL } from "@calcom/lib/constants";
3623
import { useRouterQuery } from "@calcom/lib/hooks/useRouterQuery";
3724
import { localStorage } from "@calcom/lib/webstorage";
38-
25+
import { usePathname, useRouter, useSearchParams } from "next/navigation";
26+
import { useSession } from "next-auth/react";
27+
import { useCallback, useEffect, useMemo } from "react";
28+
import { shallow } from "zustand/shallow";
3929
import { Booker as BookerComponent } from "./Booker";
4030

4131
export type BookerWebWrapperAtomProps = BookerProps & {
4232
eventData?: NonNullable<Awaited<ReturnType<typeof getPublicEvent>>>;
4333
};
4434

45-
const BookerWebWrapperComponent = (props: BookerWebWrapperAtomProps) => {
35+
const BookerWebWrapperComponent = (props: BookerWebWrapperAtomProps): JSX.Element => {
4636
const router = useRouter();
4737
const pathname = usePathname();
4838
const searchParams = useSearchParams();
@@ -64,17 +54,11 @@ const BookerWebWrapperComponent = (props: BookerWebWrapperAtomProps) => {
6454
const isRedirect = searchParams?.get("redirected") === "true" || false;
6555
const fromUserNameRedirected = searchParams?.get("username") || "";
6656
const rescheduleUid =
67-
typeof window !== "undefined"
68-
? new URLSearchParams(window.location.search).get("rescheduleUid")
69-
: null;
57+
typeof window !== "undefined" ? new URLSearchParams(window.location.search).get("rescheduleUid") : null;
7058
const rescheduledBy =
71-
typeof window !== "undefined"
72-
? new URLSearchParams(window.location.search).get("rescheduledBy")
73-
: null;
59+
typeof window !== "undefined" ? new URLSearchParams(window.location.search).get("rescheduledBy") : null;
7460
const bookingUid =
75-
typeof window !== "undefined"
76-
? new URLSearchParams(window.location.search).get("bookingUid")
77-
: null;
61+
typeof window !== "undefined" ? new URLSearchParams(window.location.search).get("bookingUid") : null;
7862
const timezone = searchParams?.get("cal.tz") || null;
7963

8064
useEffect(() => {
@@ -102,10 +86,7 @@ const BookerWebWrapperComponent = (props: BookerWebWrapperAtomProps) => {
10286
timezone,
10387
});
10488

105-
const [dayCount] = useBookerStoreContext(
106-
(state) => [state.dayCount, state.setDayCount],
107-
shallow
108-
);
89+
const [dayCount] = useBookerStoreContext((state) => [state.dayCount, state.setDayCount], shallow);
10990

11091
const { data: session } = useSession();
11192
const routerQuery = useRouterQuery();
@@ -117,20 +98,16 @@ const BookerWebWrapperComponent = (props: BookerWebWrapperAtomProps) => {
11798
.reduce(
11899
(metadata, key) => ({
119100
...metadata,
120-
[key.substring("metadata[".length, key.length - 1)]:
121-
searchParams?.get(key),
101+
[key.substring("metadata[".length, key.length - 1)]: searchParams?.get(key),
122102
}),
123103
{}
124104
);
125105
const prefillFormParams = useMemo(() => {
126106
return {
127107
name:
128108
searchParams?.get("name") ||
129-
(firstNameQueryParam
130-
? `${firstNameQueryParam} ${lastNameQueryParam}`
131-
: null),
132-
guests:
133-
(searchParams?.getAll("guests") || searchParams?.getAll("guest")) ?? [],
109+
(firstNameQueryParam ? `${firstNameQueryParam} ${lastNameQueryParam}` : null),
110+
guests: (searchParams?.getAll("guests") || searchParams?.getAll("guest")) ?? [],
134111
};
135112
}, [searchParams, firstNameQueryParam, lastNameQueryParam]);
136113

@@ -147,13 +124,10 @@ const BookerWebWrapperComponent = (props: BookerWebWrapperAtomProps) => {
147124
const verifyEmail = useVerifyEmail({
148125
email: bookerForm.formEmail,
149126
name: bookerForm.formName,
150-
requiresBookerEmailVerification:
151-
event?.data?.requiresBookerEmailVerification,
127+
requiresBookerEmailVerification: event?.data?.requiresBookerEmailVerification,
152128
onVerifyEmail: bookerForm.beforeVerifyEmail,
153129
});
154-
const slots = useSlots(
155-
event?.data ? { id: event.data.id, length: event.data.length } : null
156-
);
130+
const slots = useSlots(event?.data ? { id: event.data.id, length: event.data.length } : null);
157131

158132
const isEmbed = useIsEmbed();
159133

@@ -217,8 +191,7 @@ const BookerWebWrapperComponent = (props: BookerWebWrapperAtomProps) => {
217191
);
218192
useBrandColors({
219193
brandColor: event.data?.profile.brandColor ?? DEFAULT_LIGHT_BRAND_COLOR,
220-
darkBrandColor:
221-
event.data?.profile.darkBrandColor ?? DEFAULT_DARK_BRAND_COLOR,
194+
darkBrandColor: event.data?.profile.darkBrandColor ?? DEFAULT_DARK_BRAND_COLOR,
222195
theme: event.data?.profile.theme,
223196
});
224197

apps/web/modules/bookings/components/OverlayCalendar/OverlayCalendar.tsx

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
1-
import { useEffect } from "react";
2-
31
import { useIsPlatform } from "@calcom/atoms/hooks/useIsPlatform";
4-
5-
import type { UseCalendarsReturnType } from "@calcom/features/bookings/Booker/components/hooks/useCalendars";
62
import { useOverlayCalendar } from "@calcom/features/bookings/Booker/components/hooks/useOverlayCalendar";
3+
import type { WrappedBookerPropsMain } from "@calcom/features/bookings/Booker/types";
4+
import { useEffect } from "react";
75
import { OverlayCalendarContinueModal } from "./OverlayCalendarContinueModal";
86
import { OverlayCalendarSettingsModal } from "./OverlayCalendarSettingsModal";
97
import { OverlayCalendarSwitch } from "./OverlayCalendarSwitch";
108

119
type OverlayCalendarProps = Pick<
12-
UseCalendarsReturnType,
13-
| "connectedCalendars"
14-
| "overlayBusyDates"
15-
| "onToggleCalendar"
16-
| "loadingConnectedCalendar"
17-
| "isOverlayCalendarEnabled"
10+
WrappedBookerPropsMain["calendars"],
11+
"connectedCalendars" | "overlayBusyDates" | "onToggleCalendar" | "isOverlayCalendarEnabled"
1812
> & {
1913
handleClickNoCalendar: () => void;
2014
hasSession: boolean;
@@ -27,12 +21,11 @@ export const OverlayCalendar = ({
2721
overlayBusyDates,
2822
onToggleCalendar,
2923
isOverlayCalendarEnabled,
30-
loadingConnectedCalendar,
3124
handleClickNoCalendar,
3225
handleSwitchStateChange,
3326
handleClickContinue,
3427
hasSession,
35-
}: OverlayCalendarProps) => {
28+
}: OverlayCalendarProps): JSX.Element | null => {
3629
const isPlatform = useIsPlatform();
3730
const {
3831
handleCloseContinueModal,
@@ -70,10 +63,8 @@ export const OverlayCalendar = ({
7063
/>
7164
)}
7265
<OverlayCalendarSettingsModal
73-
connectedCalendars={connectedCalendars}
7466
open={isOpenOverlaySettingsModal}
7567
onClose={handleCloseSettingsModal}
76-
isLoading={loadingConnectedCalendar}
7768
onToggleConnectedCalendar={handleToggleConnectedCalendar}
7869
onClickNoCalendar={() => {
7970
handleClickNoCalendar();

0 commit comments

Comments
 (0)