diff --git a/apps/web/server/routers/viewer.tsx b/apps/web/server/routers/viewer.tsx index 0cb50c4309..035f329c78 100644 --- a/apps/web/server/routers/viewer.tsx +++ b/apps/web/server/routers/viewer.tsx @@ -550,7 +550,11 @@ const loggedInViewerRouter = createProtectedRouter() const connectedCalendars = await getConnectedCalendars(calendarCredentials, user.selectedCalendars); const allCals = connectedCalendars.map((cal) => cal.calendars ?? []).flat(); - if (!allCals.find((cal) => cal.externalId === externalId && cal.integration === integration)) { + const credentialId = allCals.find( + (cal) => cal.externalId === externalId && cal.integration === integration && cal.readOnly === false + )?.credentialId; + + if (!credentialId) { throw new TRPCError({ code: "BAD_REQUEST", message: `Could not find calendar ${input.externalId}` }); } @@ -565,11 +569,13 @@ const loggedInViewerRouter = createProtectedRouter() update: { integration, externalId, + credentialId, }, create: { ...where, integration, externalId, + credentialId, }, }); }, diff --git a/packages/app-store/googlecalendar/lib/CalendarService.ts b/packages/app-store/googlecalendar/lib/CalendarService.ts index 1240962576..55f2ee3e6f 100644 --- a/packages/app-store/googlecalendar/lib/CalendarService.ts +++ b/packages/app-store/googlecalendar/lib/CalendarService.ts @@ -337,6 +337,7 @@ export default class GoogleCalendarService implements Calendar { integration: this.integrationName, name: cal.summary ?? "No name", primary: cal.primary ?? false, + readOnly: !(cal.accessRole === "reader" || cal.accessRole === "owner") && true, }; return calendar; }) || [] diff --git a/packages/app-store/office365calendar/lib/CalendarService.ts b/packages/app-store/office365calendar/lib/CalendarService.ts index 3b6629f3ee..90279163db 100644 --- a/packages/app-store/office365calendar/lib/CalendarService.ts +++ b/packages/app-store/office365calendar/lib/CalendarService.ts @@ -177,6 +177,7 @@ export default class Office365CalendarService implements Calendar { integration: this.integrationName, name: cal.name ?? "No calendar name", primary: cal.isDefaultCalendar ?? false, + readOnly: !cal.canEdit && true, }; return calendar; }); diff --git a/packages/core/CalendarManager.ts b/packages/core/CalendarManager.ts index db4610944f..33a5714ea7 100644 --- a/packages/core/CalendarManager.ts +++ b/packages/core/CalendarManager.ts @@ -46,6 +46,7 @@ export const getConnectedCalendars = async ( ...cal, primary: cal.primary || null, isSelected: selectedCalendars.some((selected) => selected.externalId === cal.externalId), + credentialId, })) .sortBy(["primary"]) .value(); diff --git a/packages/core/EventManager.ts b/packages/core/EventManager.ts index 2195c98909..188a31e17b 100644 --- a/packages/core/EventManager.ts +++ b/packages/core/EventManager.ts @@ -282,6 +282,18 @@ export default class EventManager { /** Can I use destinationCalendar here? */ /* How can I link a DC to a cred? */ if (event.destinationCalendar) { + if (event.destinationCalendar.credentialId) { + const credential = await prisma.credential.findFirst({ + where: { + id: event.destinationCalendar.credentialId, + }, + }); + + if (credential) { + return [await createEvent(credential, event)]; + } + } + const destinationCalendarCredentials = this.calendarCredentials.filter( (c) => c.type === event.destinationCalendar?.integration ); diff --git a/packages/prisma/migrations/20220629151617_connect_destination_calendar_to_credential/migration.sql b/packages/prisma/migrations/20220629151617_connect_destination_calendar_to_credential/migration.sql new file mode 100644 index 0000000000..e4002e77dd --- /dev/null +++ b/packages/prisma/migrations/20220629151617_connect_destination_calendar_to_credential/migration.sql @@ -0,0 +1,5 @@ +-- AlterTable +ALTER TABLE "DestinationCalendar" ADD COLUMN "credentialId" INTEGER; + +-- AddForeignKey +ALTER TABLE "DestinationCalendar" ADD CONSTRAINT "DestinationCalendar_credentialId_fkey" FOREIGN KEY ("credentialId") REFERENCES "Credential"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index d790f842ff..538fb7794f 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -89,6 +89,7 @@ model Credential { app App? @relation(fields: [appId], references: [slug], onDelete: Cascade) // How to make it a required column? appId String? + destinationCalendars DestinationCalendar[] } enum UserPlan { @@ -113,6 +114,8 @@ model DestinationCalendar { bookingId Int? @unique eventType EventType? @relation(fields: [eventTypeId], references: [id]) eventTypeId Int? @unique + credentialId Int? + credential Credential? @relation(fields: [credentialId], references: [id]) } enum UserPermissionRole { diff --git a/packages/types/Calendar.d.ts b/packages/types/Calendar.d.ts index bd378bf0f5..68bb770d7d 100644 --- a/packages/types/Calendar.d.ts +++ b/packages/types/Calendar.d.ts @@ -146,6 +146,7 @@ export interface AdditionalInformation { export interface IntegrationCalendar extends Ensure, "externalId"> { primary?: boolean; name?: string; + readOnly?: boolean; } export interface Calendar {