fix: /getting-started/connected-calendar Toggle the first calendar on (#9028)
* [CAL-115] /getting-started/connected-calendar Toggle the first calendar on * Fix lint error * Fix error shown after completion of onboarding by connecting to calendars and playing around with toggle * Fix type errors * Fix first calendar selected even in all the screens wherever connectedCalendars is used
This commit is contained in:
parent
64796a96fc
commit
7f7d80e653
|
@ -15,7 +15,7 @@ interface IConnectCalendarsProps {
|
|||
|
||||
const ConnectedCalendars = (props: IConnectCalendarsProps) => {
|
||||
const { nextStep } = props;
|
||||
const queryConnectedCalendars = trpc.viewer.connectedCalendars.useQuery();
|
||||
const queryConnectedCalendars = trpc.viewer.connectedCalendars.useQuery({ onboarding: true });
|
||||
const { t } = useLocale();
|
||||
const queryIntegrations = trpc.viewer.integrations.useQuery({ variant: "calendar", onlyInstalled: false });
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import { ZAppByIdInputSchema } from "./appById.schema";
|
|||
import { ZAppCredentialsByTypeInputSchema } from "./appCredentialsByType.schema";
|
||||
import { ZAppsInputSchema } from "./apps.schema";
|
||||
import { ZAwayInputSchema } from "./away.schema";
|
||||
import { ZConnectedCalendarsInputSchema } from "./connectedCalendars.schema";
|
||||
import { ZDeleteCredentialInputSchema } from "./deleteCredential.schema";
|
||||
import { ZDeleteMeInputSchema } from "./deleteMe.schema";
|
||||
import { ZEventTypeOrderInputSchema } from "./eventTypeOrder.schema";
|
||||
|
@ -110,7 +111,7 @@ export const loggedInViewerRouter = router({
|
|||
return UNSTABLE_HANDLER_CACHE.away({ ctx, input });
|
||||
}),
|
||||
|
||||
connectedCalendars: authedProcedure.query(async ({ ctx }) => {
|
||||
connectedCalendars: authedProcedure.input(ZConnectedCalendarsInputSchema).query(async ({ ctx, input }) => {
|
||||
if (!UNSTABLE_HANDLER_CACHE.connectedCalendars) {
|
||||
UNSTABLE_HANDLER_CACHE.connectedCalendars = (
|
||||
await import("./connectedCalendars.handler")
|
||||
|
@ -122,7 +123,7 @@ export const loggedInViewerRouter = router({
|
|||
throw new Error("Failed to load handler");
|
||||
}
|
||||
|
||||
return UNSTABLE_HANDLER_CACHE.connectedCalendars({ ctx });
|
||||
return UNSTABLE_HANDLER_CACHE.connectedCalendars({ ctx, input });
|
||||
}),
|
||||
|
||||
setDestinationCalendar: authedProcedure
|
||||
|
|
|
@ -5,14 +5,18 @@ import { prisma } from "@calcom/prisma";
|
|||
import { AppCategories } from "@calcom/prisma/enums";
|
||||
import type { TrpcSessionUser } from "@calcom/trpc/server/trpc";
|
||||
|
||||
import type { TConnectedCalendarsInputSchema } from "./connectedCalendars.schema";
|
||||
|
||||
type ConnectedCalendarsOptions = {
|
||||
ctx: {
|
||||
user: NonNullable<TrpcSessionUser>;
|
||||
};
|
||||
input: TConnectedCalendarsInputSchema;
|
||||
};
|
||||
|
||||
export const connectedCalendarsHandler = async ({ ctx }: ConnectedCalendarsOptions) => {
|
||||
export const connectedCalendarsHandler = async ({ ctx, input }: ConnectedCalendarsOptions) => {
|
||||
const { user } = ctx;
|
||||
const onboarding = input?.onboarding || false;
|
||||
|
||||
const userCredentials = await prisma.credential.findMany({
|
||||
where: {
|
||||
|
@ -33,6 +37,12 @@ export const connectedCalendarsHandler = async ({ ctx }: ConnectedCalendarsOptio
|
|||
user.selectedCalendars,
|
||||
user.destinationCalendar?.externalId
|
||||
);
|
||||
let toggledCalendarDetails:
|
||||
| {
|
||||
externalId: string;
|
||||
integration: string;
|
||||
}
|
||||
| undefined;
|
||||
|
||||
if (connectedCalendars.length === 0) {
|
||||
/* As there are no connected calendars, delete the destination calendar if it exists */
|
||||
|
@ -48,6 +58,19 @@ export const connectedCalendarsHandler = async ({ ctx }: ConnectedCalendarsOptio
|
|||
So create a default destination calendar with the first primary connected calendar
|
||||
*/
|
||||
const { integration = "", externalId = "", credentialId } = connectedCalendars[0].primary ?? {};
|
||||
// Select the first calendar matching the primary by default since that will also be the destination calendar
|
||||
if (onboarding && externalId) {
|
||||
const calendarIndex = (connectedCalendars[0].calendars || []).findIndex(
|
||||
(item) => item.externalId === externalId && item.integration === integration
|
||||
);
|
||||
if (calendarIndex >= 0 && connectedCalendars[0].calendars) {
|
||||
connectedCalendars[0].calendars[calendarIndex].isSelected = true;
|
||||
toggledCalendarDetails = {
|
||||
externalId,
|
||||
integration,
|
||||
};
|
||||
}
|
||||
}
|
||||
user.destinationCalendar = await prisma.destinationCalendar.create({
|
||||
data: {
|
||||
userId: user.id,
|
||||
|
@ -70,6 +93,19 @@ export const connectedCalendarsHandler = async ({ ctx }: ConnectedCalendarsOptio
|
|||
if (!destinationCal) {
|
||||
// If destinationCalendar is out of date, update it with the first primary connected calendar
|
||||
const { integration = "", externalId = "" } = connectedCalendars[0].primary ?? {};
|
||||
// Select the first calendar matching the primary by default since that will also be the destination calendar
|
||||
if (onboarding && externalId) {
|
||||
const calendarIndex = (connectedCalendars[0].calendars || []).findIndex(
|
||||
(item) => item.externalId === externalId && item.integration === integration
|
||||
);
|
||||
if (calendarIndex >= 0 && connectedCalendars[0].calendars) {
|
||||
connectedCalendars[0].calendars[calendarIndex].isSelected = true;
|
||||
toggledCalendarDetails = {
|
||||
externalId,
|
||||
integration,
|
||||
};
|
||||
}
|
||||
}
|
||||
user.destinationCalendar = await prisma.destinationCalendar.update({
|
||||
where: { userId: user.id },
|
||||
data: {
|
||||
|
@ -77,9 +113,49 @@ export const connectedCalendarsHandler = async ({ ctx }: ConnectedCalendarsOptio
|
|||
externalId,
|
||||
},
|
||||
});
|
||||
} else if (onboarding && !destinationCal.isSelected) {
|
||||
// Mark the destination calendar as selected in the calendar list
|
||||
// We use every so that we can exit early once we find the matching calendar
|
||||
connectedCalendars.every((cal) => {
|
||||
const index = (cal.calendars || []).findIndex(
|
||||
(calendar) =>
|
||||
calendar.externalId === destinationCal.externalId &&
|
||||
calendar.integration === destinationCal.integration
|
||||
);
|
||||
if (index >= 0 && cal.calendars) {
|
||||
cal.calendars[index].isSelected = true;
|
||||
toggledCalendarDetails = {
|
||||
externalId: destinationCal.externalId,
|
||||
integration: destinationCal.integration || "",
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Insert the newly toggled record to the DB
|
||||
if (toggledCalendarDetails) {
|
||||
await prisma.selectedCalendar.upsert({
|
||||
where: {
|
||||
userId_integration_externalId: {
|
||||
userId: user.id,
|
||||
integration: toggledCalendarDetails.integration,
|
||||
externalId: toggledCalendarDetails.externalId,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
userId: user.id,
|
||||
integration: toggledCalendarDetails.integration,
|
||||
externalId: toggledCalendarDetails.externalId,
|
||||
},
|
||||
// already exists
|
||||
update: {},
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
connectedCalendars,
|
||||
destinationCalendar: {
|
||||
|
|
|
@ -1 +1,9 @@
|
|||
export {};
|
||||
import { z } from "zod";
|
||||
|
||||
export const ZConnectedCalendarsInputSchema = z
|
||||
.object({
|
||||
onboarding: z.boolean().optional(),
|
||||
})
|
||||
.optional();
|
||||
|
||||
export type TConnectedCalendarsInputSchema = z.infer<typeof ZConnectedCalendarsInputSchema>;
|
||||
|
|
Loading…
Reference in New Issue
Block a user