* WIP-already-reschedule-success-emails-missing * WIP now saving bookingSeatsReferences and identifyin on reschedule/book page * Remove logs and created test * WIP saving progress * Select second slot to pass test * Delete attendee from event * Clean up * Update with main changes * Fix emails not being sent * Changed test end url from success to booking * Remove unused pkg * Fix new booking reschedule * remove log * Renable test * remove unused pkg * rename table name * review changes * Fix and and other test to reschedule with seats * Fix api for cancel booking * Typings * Update [uid].tsx * Abstracted common pattern into maybeGetBookingUidFromSeat * Reverts * Nitpicks * Update handleCancelBooking.ts * Adds missing cascades * Improve booking seats changes (#6858) * Create sendCancelledSeatEmails * Draft attendee cancelled seat email * Send no longer attendee email to attendee * Send email to organizer when attendee cancels * Pass cloned event data to emails * Send booked email for first seat * Add seat reference uid from email link * Query for seatReferenceUId and add to cancel & reschedule links * WIP * Display proper attendee when rescheduling seats * Remove console.logs * Only check for already invited when not rescheduling * WIP sending reschedule email to just single attendee and owner * Merge branch 'main' into send-email-on-seats-attendee-changes * Remove console.logs * Add cloned event to seat emails * Do not show manage link for calendar event * First seat, have both attendees on calendar * WIP refactor booking seats reschedule logic * WIP Refactor handleSeats * Change relation of attendee & seat reference to a one-to-one * Migration with relationship change * Booking page handling unique seat references * Abstract to handleSeats * Remove console.logs and clean up * New migration file, delete on cascade * Check if attendee is already a part of the booking * Move deleting booking logic to `handleSeats` * When owner reschedule, move whole booking * Prevent owner from rescheduling if not enough seats * Add owner reschedule * Send reschedule email when moving to new timeslot * Add event data to reschedule email for seats * Remove DB changes from event manager * When a booking has no attendees then delete * Update calendar when merging bookings * Move both attendees and seat references when merging * Remove guest list from seats booking page * Update original booking when moving an attendee * Delete calendar and video events if no more attendees * Update or delete integrations when attendees cancel * Show no longer attendee if a single attendee cancels * Change booking to accepted if an attendee books on an empty booking * If booking in same slot then just return the booking * Clean up * Clean up * Remove booking select * Typos --------- Co-authored-by: zomars <zomars@me.com> * Fix migration table name * Add missing trpc import * Rename bookingSeatReferences to bookingSeat * Change relationship between Attendee & BookingSeat to one to one * Fix some merge conflicts * Minor merge artifact fixup * Add the right 'Person' type * Check on email, less (although still) editable than name * Removed calEvent.attendeeUniqueId * rename referenceUId -> referenceUid * Squashes migrations * Run cached installs Should still be faster. Ensures prisma client is up to date. * Solve attendee form on booking page * Remove unused code * Some type fixes * Squash migrations * Type fixes * Fix for reschedule/[uid] redirect * Fix e2e test * Solve double declaration of host * Solve lint errors * Drop constraint only if exists * Renamed UId to Uid * Explicit vs. implicit * Attempt to work around text flakiness by adding a little break between animations * Various bugfixes * Persistently apply seatReferenceUid (#7545) * Persistently apply seatReferenceUid * Small ts fix * Setup guards correctly * Type fixes * Fix render 0 in conditional * Test refactoring * Fix type on handleSeats * Fix handle seats conditional * Fix type inference * Update packages/features/bookings/lib/handleNewBooking.ts * Update apps/web/components/booking/pages/BookingPage.tsx * Fix type and missing logic for reschedule * Fix delete of calendar event and booking * Add handleSeats return type * Fix seats booking creation * Fall through normal booking for initial booking, handleSeats for secondary/reschedule * Simplification of fetching booking * Enable seats for round-robin events * A lot harder than I expected * ignore-owner-if-seat-reference-given * Return seatReferenceUid when second seat * negate userIsOwner * Fix booking seats with a link without bookingUid * Needed a time check otherwise the attendee will be in the older booking * Can't open dialog twice in test.. * Allow passing the booking ID from the server * Fixed isCancelled check, fixed test * Delete through cascade instead of multiple deletes --------- Co-authored-by: Joe Au-Yeung <j.auyeung419@gmail.com> Co-authored-by: Peer Richelsen <peer@cal.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com> Co-authored-by: Alex van Andel <me@alexvanandel.com> Co-authored-by: Efraín Rochín <roae.85@gmail.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com>
238 lines
5.6 KiB
TypeScript
238 lines
5.6 KiB
TypeScript
import type { Prisma, DestinationCalendar, SelectedCalendar, BookingSeat } from "@prisma/client";
|
|
import type { Dayjs } from "dayjs";
|
|
import type { calendar_v3 } from "googleapis";
|
|
import type { Time } from "ical.js";
|
|
import type { TFunction } from "next-i18next";
|
|
|
|
import type { Calendar } from "@calcom/features/calendars/weeklyview";
|
|
import type { TimeFormat } from "@calcom/lib/timeFormat";
|
|
import type { Frequency } from "@calcom/prisma/zod-utils";
|
|
|
|
import type { Ensure } from "./utils";
|
|
|
|
export type { VideoCallData } from "./VideoApiAdapter";
|
|
|
|
type PaymentInfo = {
|
|
link?: string | null;
|
|
reason?: string | null;
|
|
id?: string | null;
|
|
};
|
|
|
|
export type Person = {
|
|
name: string;
|
|
email: string;
|
|
timeZone: string;
|
|
language: { translate: TFunction; locale: string };
|
|
username?: string;
|
|
id?: number;
|
|
bookingId?: number | null;
|
|
locale?: string | null;
|
|
timeFormat?: TimeFormat;
|
|
bookingSeat?: BookingSeat | null;
|
|
};
|
|
|
|
export type TeamMember = {
|
|
name: string;
|
|
email: string;
|
|
timeZone: string;
|
|
language: { translate: TFunction; locale: string };
|
|
};
|
|
|
|
export type EventBusyDate = {
|
|
start: Date | string;
|
|
end: Date | string;
|
|
source?: string | null;
|
|
};
|
|
|
|
export type EventBusyDetails = EventBusyDate & {
|
|
title?: string;
|
|
source?: string | null;
|
|
};
|
|
|
|
export type CalendarServiceType = typeof Calendar;
|
|
export type AdditionalInfo = Record<string, unknown> & { calWarnings?: string[] };
|
|
|
|
export type NewCalendarEventType = {
|
|
uid: string;
|
|
id: string;
|
|
type: string;
|
|
password: string;
|
|
url: string;
|
|
additionalInfo: AdditionalInfo;
|
|
};
|
|
|
|
export type CalendarEventType = {
|
|
uid: string;
|
|
etag: string;
|
|
/** This is the actual caldav event url, not the location url. */
|
|
url: string;
|
|
summary: string;
|
|
description: string;
|
|
location: string;
|
|
sequence: number;
|
|
startDate: Date | Dayjs;
|
|
endDate: Date | Dayjs;
|
|
duration: {
|
|
weeks: number;
|
|
days: number;
|
|
hours: number;
|
|
minutes: number;
|
|
seconds: number;
|
|
isNegative: boolean;
|
|
};
|
|
organizer: string;
|
|
attendees: any[][];
|
|
recurrenceId: Time;
|
|
timezone: any;
|
|
};
|
|
|
|
export type BatchResponse = {
|
|
responses: SubResponse[];
|
|
};
|
|
|
|
export type SubResponse = {
|
|
body: {
|
|
value: {
|
|
showAs: "free" | "tentative" | "away" | "busy" | "workingElsewhere";
|
|
start: { dateTime: string };
|
|
end: { dateTime: string };
|
|
}[];
|
|
};
|
|
};
|
|
|
|
export interface ConferenceData {
|
|
createRequest?: calendar_v3.Schema$CreateConferenceRequest;
|
|
}
|
|
|
|
export interface AdditionalInformation {
|
|
conferenceData?: ConferenceData;
|
|
entryPoints?: EntryPoint[];
|
|
hangoutLink?: string;
|
|
}
|
|
|
|
export interface RecurringEvent {
|
|
dtstart?: Date | undefined;
|
|
interval: number;
|
|
count: number;
|
|
freq: Frequency;
|
|
until?: Date | undefined;
|
|
tzid?: string | undefined;
|
|
}
|
|
|
|
export interface IntervalLimit {
|
|
PER_DAY?: number | undefined;
|
|
PER_WEEK?: number | undefined;
|
|
PER_MONTH?: number | undefined;
|
|
PER_YEAR?: number | undefined;
|
|
}
|
|
|
|
export type AppsStatus = {
|
|
appName: string;
|
|
type: (typeof App)["type"];
|
|
success: number;
|
|
failures: number;
|
|
errors: string[];
|
|
warnings?: string[];
|
|
};
|
|
|
|
// If modifying this interface, probably should update builders/calendarEvent files
|
|
export interface CalendarEvent {
|
|
type: string;
|
|
title: string;
|
|
startTime: string;
|
|
endTime: string;
|
|
organizer: Person;
|
|
attendees: Person[];
|
|
additionalNotes?: string | null;
|
|
customInputs?: Prisma.JsonObject | null;
|
|
description?: string | null;
|
|
team?: {
|
|
name: string;
|
|
members: TeamMember[];
|
|
};
|
|
location?: string | null;
|
|
conferenceData?: ConferenceData;
|
|
additionalInformation?: AdditionalInformation;
|
|
uid?: string | null;
|
|
videoCallData?: VideoCallData;
|
|
paymentInfo?: PaymentInfo | null;
|
|
requiresConfirmation?: boolean | null;
|
|
destinationCalendar?: DestinationCalendar | null;
|
|
cancellationReason?: string | null;
|
|
rejectionReason?: string | null;
|
|
hideCalendarNotes?: boolean;
|
|
recurrence?: string;
|
|
recurringEvent?: RecurringEvent | null;
|
|
eventTypeId?: number | null;
|
|
appsStatus?: AppsStatus[];
|
|
seatsShowAttendees?: boolean | null;
|
|
attendeeSeatId?: string;
|
|
seatsPerTimeSlot?: number | null;
|
|
|
|
// It has responses to all the fields(system + user)
|
|
responses?: Record<
|
|
string,
|
|
{
|
|
value: string | string[];
|
|
label: string;
|
|
}
|
|
> | null;
|
|
|
|
// It just has responses to only the user fields. It allows to easily iterate over to show only user fields
|
|
userFieldsResponses?: Record<
|
|
string,
|
|
{
|
|
value: string | string[];
|
|
label: string;
|
|
}
|
|
> | null;
|
|
}
|
|
|
|
export interface EntryPoint {
|
|
entryPointType?: string;
|
|
uri?: string;
|
|
label?: string;
|
|
pin?: string;
|
|
accessCode?: string;
|
|
meetingCode?: string;
|
|
passcode?: string;
|
|
password?: string;
|
|
}
|
|
|
|
export interface AdditionalInformation {
|
|
conferenceData?: ConferenceData;
|
|
entryPoints?: EntryPoint[];
|
|
hangoutLink?: string;
|
|
}
|
|
|
|
export interface IntegrationCalendar extends Ensure<Partial<SelectedCalendar>, "externalId"> {
|
|
primary?: boolean;
|
|
name?: string;
|
|
readOnly?: boolean;
|
|
// For displaying the connected email address
|
|
email?: string;
|
|
primaryEmail?: string;
|
|
credentialId?: number;
|
|
integrationTitle?: string;
|
|
}
|
|
|
|
export interface Calendar {
|
|
createEvent(event: CalendarEvent): Promise<NewCalendarEventType>;
|
|
|
|
updateEvent(
|
|
uid: string,
|
|
event: CalendarEvent,
|
|
externalCalendarId?: string | null
|
|
): Promise<NewCalendarEventType | NewCalendarEventType[]>;
|
|
|
|
deleteEvent(uid: string, event: CalendarEvent, externalCalendarId?: string | null): Promise<unknown>;
|
|
|
|
getAvailability(
|
|
dateFrom: string,
|
|
dateTo: string,
|
|
selectedCalendars: IntegrationCalendar[]
|
|
): Promise<EventBusyDate[]>;
|
|
|
|
listCalendars(event?: CalendarEvent): Promise<IntegrationCalendar[]>;
|
|
}
|