Skip to content

Commit

Permalink
As Google Meet is always installed, this fixes the doubling (calcom#3093
Browse files Browse the repository at this point in the history
)

* As Google Meet is always installed, this fixes the doubling

* Make entire Google link clickable, fix extraData

* Attempt at type fixing :)

* AdditionalInformation for the booking page?

* Update packages/emails/src/components/LocationInfo.tsx

Being explicit :)

* Exclude AdditionalInformation as it is irrelevant here

Co-authored-by: Peer Richelsen <[email protected]>
Co-authored-by: Omar López <[email protected]>
  • Loading branch information
3 people authored Jun 17, 2022
1 parent b9b3fef commit 159c026
Show file tree
Hide file tree
Showing 12 changed files with 72 additions and 74 deletions.
2 changes: 1 addition & 1 deletion apps/web/pages/api/book/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ async function handler(req: NextApiRequest) {
return prisma.booking.create(createBookingObj);
}

let results: EventResult[] = [];
let results: EventResult<AdditionalInformation>[] = [];
let referencesToCreate: PartialReference[] = [];
let user: User | null = null;

Expand Down
14 changes: 10 additions & 4 deletions packages/app-store/exchange2013calendar/lib/CalendarService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@ import { symmetricDecrypt } from "@calcom/lib/crypto";
// Probably don't need
// import { CALENDAR_INTEGRATIONS_TYPES } from "@calcom/lib/integrations/calendar/constants/generals";
import logger from "@calcom/lib/logger";
import { Calendar, CalendarEvent, EventBusyDate, IntegrationCalendar } from "@calcom/types/Calendar";
import {
Calendar,
CalendarEvent,
EventBusyDate,
IntegrationCalendar,
NewCalendarEventType,
} from "@calcom/types/Calendar";

export default class ExchangeCalendarService implements Calendar {
private url = "";
Expand Down Expand Up @@ -55,7 +61,7 @@ export default class ExchangeCalendarService implements Calendar {
this.exchangeVersion = ExchangeVersion.Exchange2013;
}

async createEvent(event: CalendarEvent) {
async createEvent(event: CalendarEvent): Promise<NewCalendarEventType> {
try {
const appointment = new Appointment(this.getExchangeService()); // service instance of ExchangeService
appointment.Subject = event.title;
Expand All @@ -76,15 +82,15 @@ export default class ExchangeCalendarService implements Calendar {
password: "",
type: "",
url: "",
additionalInfo: [],
additionalInfo: {},
};
} catch (reason) {
this.log.error(reason);
throw reason;
}
}

async updateEvent(uid: string, event: CalendarEvent) {
async updateEvent(uid: string, event: CalendarEvent): Promise<any> {
try {
const appointment = await Appointment.Bind(
this.getExchangeService(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export default class ExchangeCalendarService implements Calendar {
password: "",
type: "",
url: "",
additionalInfo: [],
additionalInfo: {},
};
} catch (reason) {
this.log.error(reason);
Expand Down
2 changes: 0 additions & 2 deletions packages/app-store/googlecalendar/_metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ export const metadata = {
url: "https://cal.com/",
verified: true,
email: "[email protected]",
locationType: LocationType.GoogleMeet,
locationLabel: "Google Meet",
} as App;

export default metadata;
15 changes: 11 additions & 4 deletions packages/core/CalendarManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { getUid } from "@calcom/lib/CalEventParser";
import { getErrorFromUnknown } from "@calcom/lib/errors";
import logger from "@calcom/lib/logger";
import notEmpty from "@calcom/lib/notEmpty";
import type { CalendarEvent, EventBusyDate } from "@calcom/types/Calendar";
import type { CalendarEvent, EventBusyDate, NewCalendarEventType } from "@calcom/types/Calendar";
import type { Event } from "@calcom/types/Event";
import type { EventResult } from "@calcom/types/EventManager";

const log = logger.getChildLogger({ prefix: ["CalendarManager"] });
Expand Down Expand Up @@ -97,7 +98,10 @@ export const getBusyCalendarTimes = async (
return results.reduce((acc, availability) => acc.concat(availability), []);
};

export const createEvent = async (credential: Credential, calEvent: CalendarEvent): Promise<EventResult> => {
export const createEvent = async (
credential: Credential,
calEvent: CalendarEvent
): Promise<EventResult<NewCalendarEventType>> => {
const uid: string = getUid(calEvent);
const calendar = getCalendar(credential);
let success = true;
Expand Down Expand Up @@ -130,7 +134,7 @@ export const updateEvent = async (
calEvent: CalendarEvent,
bookingRefUid: string | null,
externalCalendarId: string | null
): Promise<EventResult> => {
): Promise<EventResult<NewCalendarEventType>> => {
const uid = getUid(calEvent);
const calendar = getCalendar(credential);
let success = false;
Expand All @@ -141,7 +145,10 @@ export const updateEvent = async (
calendar && bookingRefUid
? await calendar
.updateEvent(bookingRefUid, calEvent, externalCalendarId)
.then(() => (success = true))
.then((event) => {
success = true;
return event;
})
.catch((e) => {
log.error("updateEvent failed", e, calEvent);
return undefined;
Expand Down
25 changes: 9 additions & 16 deletions packages/core/EventManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,14 @@ import { v5 as uuidv5 } from "uuid";
import { FAKE_DAILY_CREDENTIAL } from "@calcom/app-store/dailyvideo/lib/VideoApiAdapter";
import getApps from "@calcom/app-store/utils";
import prisma from "@calcom/prisma";
import type { AdditionalInformation, CalendarEvent } from "@calcom/types/Calendar";
import type {
CreateUpdateResult,
EventResult,
PartialBooking,
PartialReference,
} from "@calcom/types/EventManager";
import type { VideoCallData } from "@calcom/types/VideoApiAdapter";
import type { AdditionalInformation, CalendarEvent, NewCalendarEventType } from "@calcom/types/Calendar";
import type { Event } from "@calcom/types/Event";
import type { CreateUpdateResult, EventResult, PartialBooking } from "@calcom/types/EventManager";

import { createEvent, updateEvent } from "./CalendarManager";
import { LocationType } from "./location";
import { createMeeting, updateMeeting } from "./videoClient";

export type Event = AdditionalInformation & VideoCallData;

export const isZoom = (location: string): boolean => {
return location === "integrations:zoom";
};
Expand Down Expand Up @@ -126,7 +119,7 @@ export default class EventManager {
const evt = processLocation(event);
const isDedicated = evt.location ? isDedicatedIntegration(evt.location) : null;

const results: Array<EventResult> = [];
const results: Array<EventResult<Exclude<Event, AdditionalInformation>>> = [];
// If and only if event type is a dedicated meeting, create a dedicated video meeting.
if (isDedicated) {
const result = await this.createVideoEvent(evt);
Expand All @@ -140,7 +133,7 @@ export default class EventManager {
// Create the calendar event with the proper video call data
results.push(...(await this.createAllCalendarEvents(evt)));

const referencesToCreate: Array<PartialReference> = results.map((result: EventResult) => {
const referencesToCreate = results.map((result) => {
return {
type: result.type,
uid: result.createdEvent?.id.toString() ?? "",
Expand Down Expand Up @@ -214,7 +207,7 @@ export default class EventManager {
});

const isDedicated = evt.location ? isDedicatedIntegration(evt.location) : null;
const results: Array<EventResult> = [];
const results: Array<EventResult<Event>> = [];
// If and only if event type is a dedicated meeting, update the dedicated video meeting.
if (isDedicated) {
const result = await this.updateVideoEvent(evt, booking);
Expand Down Expand Up @@ -285,7 +278,7 @@ export default class EventManager {
* @param noMail
* @private
*/
private async createAllCalendarEvents(event: CalendarEvent): Promise<Array<EventResult>> {
private async createAllCalendarEvents(event: CalendarEvent) {
/** Can I use destinationCalendar here? */
/* How can I link a DC to a cred? */
if (event.destinationCalendar) {
Expand Down Expand Up @@ -341,7 +334,7 @@ export default class EventManager {
* @param event
* @private
*/
private createVideoEvent(event: CalendarEvent): Promise<EventResult> {
private createVideoEvent(event: CalendarEvent) {
const credential = this.getVideoCredential(event);

if (credential) {
Expand All @@ -366,7 +359,7 @@ export default class EventManager {
private updateAllCalendarEvents(
event: CalendarEvent,
booking: PartialBooking
): Promise<Array<EventResult>> {
): Promise<Array<EventResult<NewCalendarEventType>>> {
return async.mapLimit(this.calendarCredentials, 5, async (credential: Credential) => {
try {
// HACK:
Expand Down
6 changes: 3 additions & 3 deletions packages/core/videoClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getUid } from "@calcom/lib/CalEventParser";
import logger from "@calcom/lib/logger";
import type { CalendarEvent } from "@calcom/types/Calendar";
import type { EventResult, PartialReference } from "@calcom/types/EventManager";
import type { VideoApiAdapter, VideoApiAdapterFactory } from "@calcom/types/VideoApiAdapter";
import type { VideoApiAdapter, VideoApiAdapterFactory, VideoCallData } from "@calcom/types/VideoApiAdapter";

const log = logger.getChildLogger({ prefix: ["[lib] videoClient"] });

Expand All @@ -32,7 +32,7 @@ const getBusyVideoTimes = (withCredentials: Credential[]) =>
results.reduce((acc, availability) => acc.concat(availability), [])
);

const createMeeting = async (credential: Credential, calEvent: CalendarEvent): Promise<EventResult> => {
const createMeeting = async (credential: Credential, calEvent: CalendarEvent) => {
const uid: string = getUid(calEvent);

if (!credential) {
Expand Down Expand Up @@ -69,7 +69,7 @@ const updateMeeting = async (
credential: Credential,
calEvent: CalendarEvent,
bookingRef: PartialReference | null
): Promise<EventResult> => {
): Promise<EventResult<VideoCallData>> => {
const uid = translator.fromUUID(uuidv5(JSON.stringify(calEvent), uuidv5.URL));

let success = true;
Expand Down
54 changes: 21 additions & 33 deletions packages/emails/src/components/LocationInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,18 @@ export function LocationInfo(props: { calEvent: CalendarEvent; t: TFunction }) {
label={t("where")}
withSpacer
description={
<>
{providerName}
{meetingUrl && (
<a
href={meetingUrl}
target="_blank"
title={t("meeting_url")}
style={{ color: "#3E3E3E" }}
rel="noreferrer">
<LinkIcon />
</a>
)}
</>
meetingUrl ? (
<a
href={meetingUrl}
target="_blank"
title={t("meeting_url")}
style={{ color: "#3E3E3E" }}
rel="noreferrer">
{providerName} <LinkIcon />
</a>
) : (
<>{t("something_went_wrong")}</>
)
}
extraInfo={
<>
Expand Down Expand Up @@ -84,26 +83,15 @@ export function LocationInfo(props: { calEvent: CalendarEvent; t: TFunction }) {
label={t("where")}
withSpacer
description={
<>
{providerName}
{hangoutLink && (
<a
href={hangoutLink}
target="_blank"
title={t("meeting_url")}
style={{ color: "#3E3E3E" }}
rel="noreferrer">
<LinkIcon />
</a>
)}
</>
}
extraInfo={
providerName === "Zoom" || providerName === "Google" ? (
<p style={{ color: "#494949", fontWeight: 400, lineHeight: "24px" }}>
<>{t("meeting_url_provided_after_confirmed")}</>
</p>
) : null
<a
href={hangoutLink}
target="_blank"
title={t("meeting_url")}
style={{ color: "#3E3E3E" }}
rel="noreferrer">
Google <LinkIcon />

</a>
}
/>
);
Expand Down
11 changes: 8 additions & 3 deletions packages/lib/CalendarService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,10 @@ export default abstract class BaseCalendarService implements Calendar {
}
}

async updateEvent(uid: string, event: CalendarEvent) {
async updateEvent(
uid: string,
event: CalendarEvent
): Promise<NewCalendarEventType | NewCalendarEventType[]> {
try {
const events = await this.getEventsByUID(uid);

Expand All @@ -166,10 +169,12 @@ export default abstract class BaseCalendarService implements Calendar {
this.log.debug("Error creating iCalString");

return {
uid,
type: event.type,
id: typeof event.uid === "string" ? event.uid : "-1",
password: "",
url: typeof event.location === "string" ? event.location : "-1",
additionalInfo: {},
};
}

Expand All @@ -186,7 +191,7 @@ export default abstract class BaseCalendarService implements Calendar {
headers: this.headers,
});
})
).then((p) => p.map((r) => r.json() as unknown as Event));
).then((p) => p.map((r) => r.json() as unknown as NewCalendarEventType));
} catch (reason) {
this.log.error(reason);

Expand Down Expand Up @@ -290,7 +295,7 @@ export default abstract class BaseCalendarService implements Calendar {
if (vtimezone) {
const zone = new ICAL.Timezone(vtimezone);
currentEvent.startDate = currentEvent.startDate.convertToZone(zone);
currentEvent.endDate = currentEvent.endDate.convertToZone(zone);
currentEvent.endDate = currentEvent.endDate.convertToZone(zone);
}
currentStart = dayjs(currentEvent.startDate.toJSDate());

Expand Down
4 changes: 2 additions & 2 deletions packages/types/Calendar.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export type NewCalendarEventType = {
type: string;
password: string;
url: string;
additionalInfo: Record<string, any>;
additionalInfo: Record<string, unknown>;
};

export type CalendarEventType = {
Expand Down Expand Up @@ -154,7 +154,7 @@ export interface Calendar {
uid: string,
event: CalendarEvent,
externalCalendarId?: string | null
): Promise<Event | Event[]>;
): Promise<NewCalendarEventType | NewCalendarEventType[]>;

deleteEvent(uid: string, event: CalendarEvent, externalCalendarId?: string | null): Promise<unknown>;

Expand Down
5 changes: 3 additions & 2 deletions packages/types/Event.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { PartialReference } from "./EventManager";
import type { NewCalendarEventType, AdditionalInformation } from "@calcom/types/Calendar";

import type { VideoCallData } from "./VideoApiAdapter";

export type Event = AdditionalInformation & VideoCallData;
export type Event = AdditionalInformation | NewCalendarEventType | VideoCallData;
6 changes: 3 additions & 3 deletions packages/types/EventManager.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ export interface PartialReference {
externalCalendarId?: string | null;
}

export interface EventResult {
export interface EventResult<T> {
type: string;
success: boolean;
uid: string;
createdEvent?: Event;
updatedEvent?: Event | Event[];
createdEvent?: T;
updatedEvent?: T | T[];
originalEvent: CalendarEvent;
}

Expand Down

0 comments on commit 159c026

Please sign in to comment.