From cfb09a1b21962a9193d014966d30cae533462fb8 Mon Sep 17 00:00:00 2001 From: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com> Date: Mon, 23 Dec 2024 13:16:38 -0600 Subject: [PATCH] feat: virtual queues tab in insights (#18260) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: CarinaWolli Co-authored-by: sean-brydon Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: Peer Richelsen Co-authored-by: Omar López --- apps/web/app/insights/virtual-queues/page.tsx | 17 ++ .../installation/[[...step]]/step-view.tsx | 22 +- .../bookings/views/bookings-single-view.tsx | 16 +- .../insights/insights-virtual-queues-view.tsx | 49 ++++ apps/web/modules/test-setup.ts | 3 + .../web/playwright/integrations-stripe.e2e.ts | 10 +- apps/web/public/static/locales/en/common.json | 7 + .../app-store/_utils/getEventTypeAppData.ts | 6 +- .../payments/checkForMultiplePaymentApps.ts | 9 +- .../routing-forms/components/SingleForm.tsx | 237 ++++++++++++------ packages/app-store/salesforce/zod.ts | 5 +- .../getAllCredentials.ts | 4 +- .../bookings/lib/handleConfirmation.ts | 5 +- .../features/bookings/lib/handleNewBooking.ts | 20 +- .../lib/handleSeats/create/createNewSeat.ts | 4 +- .../credentials/handleDeleteCredential.ts | 20 +- packages/features/ee/payments/api/webhook.ts | 4 +- .../components/EventTypeDescription.tsx | 6 +- .../tabs/instant/EventInstantTab.tsx | 6 +- .../tabs/recurring/EventRecurringTab.tsx | 6 +- .../features/eventtypes/lib/getPublicEvent.ts | 6 +- packages/features/eventtypes/lib/types.ts | 4 +- .../features/insights/server/trpc-router.ts | 12 + .../insights/server/virtual-queues.ts | 73 ++++++ .../handleSendingAttendeeNoShowDataToApps.ts | 4 +- .../features/shell/navigation/Navigation.tsx | 5 + packages/lib/defaultEvents.ts | 3 +- packages/lib/event-types/getEventTypeById.ts | 4 +- .../lib/event-types/getEventTypesByViewer.ts | 4 +- packages/lib/getPaymentAppData.ts | 12 +- packages/lib/payment/handlePayment.ts | 13 +- packages/lib/payment/handlePaymentSuccess.ts | 4 +- packages/lib/piiFreeData.ts | 4 +- packages/lib/server/service/eventType.ts | 6 +- .../event-types/hooks/useEventTypeForm.ts | 4 +- .../event-types/hooks/useTabsNavigations.tsx | 6 +- packages/prisma/zod-utils.ts | 98 ++++---- .../viewer/eventTypes/update.handler.ts | 6 +- .../getAllActiveWorkflows.handler.ts | 9 +- 39 files changed, 538 insertions(+), 195 deletions(-) create mode 100644 apps/web/app/insights/virtual-queues/page.tsx create mode 100644 apps/web/modules/insights/insights-virtual-queues-view.tsx create mode 100644 packages/features/insights/server/virtual-queues.ts diff --git a/apps/web/app/insights/virtual-queues/page.tsx b/apps/web/app/insights/virtual-queues/page.tsx new file mode 100644 index 0000000000..073f205f09 --- /dev/null +++ b/apps/web/app/insights/virtual-queues/page.tsx @@ -0,0 +1,17 @@ +import { withAppDirSsr } from "app/WithAppDirSsr"; +import { _generateMetadata } from "app/_utils"; +import { WithLayout } from "app/layoutHOC"; + +import { getServerSideProps } from "@lib/insights/getServerSideProps"; + +import InsightsVirtualQueuesPage from "~/insights/insights-virtual-queues-view"; + +export const generateMetadata = async () => + await _generateMetadata( + (t) => t("insights"), + (t) => t("insights_subtitle") + ); + +const getData = withAppDirSsr(getServerSideProps); + +export default WithLayout({ getLayout: null, getData, Page: InsightsVirtualQueuesPage }); diff --git a/apps/web/modules/apps/installation/[[...step]]/step-view.tsx b/apps/web/modules/apps/installation/[[...step]]/step-view.tsx index 6691621cbc..d5937d3251 100644 --- a/apps/web/modules/apps/installation/[[...step]]/step-view.tsx +++ b/apps/web/modules/apps/installation/[[...step]]/step-view.tsx @@ -18,6 +18,7 @@ import { WEBAPP_URL } from "@calcom/lib/constants"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import type { Team } from "@calcom/prisma/client"; import type { eventTypeBookingFields } from "@calcom/prisma/zod-utils"; +import { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/prisma/zod-utils"; import type { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils"; import { trpc } from "@calcom/trpc/react"; import type { AppMeta } from "@calcom/types/App"; @@ -243,15 +244,20 @@ const OnboardingPage = ({ const promises = group.eventTypes .filter((eventType) => eventType.selected) .map((value: TEventType) => { - // Prevent two payment apps to be enabled - // Ok to cast type here because this metadata will be updated as the event type metadata - if ( - checkForMultiplePaymentApps(value.metadata as z.infer) - ) - throw new Error(t("event_setup_multiple_payment_apps_error")); - if (value.metadata?.apps?.stripe?.paymentOption === "HOLD" && value.seatsPerTimeSlot) { - throw new Error(t("seats_and_no_show_fee_error")); + if (value.metadata) { + const metadata = eventTypeMetaDataSchemaWithTypedApps.parse(value.metadata); + // Prevent two payment apps to be enabled + // Ok to cast type here because this metadata will be updated as the event type metadata + if (checkForMultiplePaymentApps(metadata)) + throw new Error(t("event_setup_multiple_payment_apps_error")); + if ( + value.metadata?.apps?.stripe?.paymentOption === "HOLD" && + value.seatsPerTimeSlot + ) { + throw new Error(t("seats_and_no_show_fee_error")); + } } + let updateObject: TUpdateObject = { id: value.id }; if (isConferencing) { updateObject = { diff --git a/apps/web/modules/bookings/views/bookings-single-view.tsx b/apps/web/modules/bookings/views/bookings-single-view.tsx index c6e45ca79d..f1a190dbc5 100644 --- a/apps/web/modules/bookings/views/bookings-single-view.tsx +++ b/apps/web/modules/bookings/views/bookings-single-view.tsx @@ -48,7 +48,7 @@ import { getEveryFreqFor } from "@calcom/lib/recurringStrings"; import { getIs24hClockFromLocalStorage, isBrowserLocale24h } from "@calcom/lib/timeFormat"; import { localStorage } from "@calcom/lib/webstorage"; import { BookingStatus, SchedulingType } from "@calcom/prisma/enums"; -import { bookingMetadataSchema } from "@calcom/prisma/zod-utils"; +import { bookingMetadataSchema, eventTypeMetaDataSchemaWithTypedApps } from "@calcom/prisma/zod-utils"; import { trpc } from "@calcom/trpc/react"; import { Alert, @@ -61,6 +61,7 @@ import { showToast, EmptyScreen, Icon, + HeadSeo, } from "@calcom/ui"; import CancelBooking from "@calcom/web/components/booking/CancelBooking"; import EventReservationSchema from "@calcom/web/components/schemas/EventReservationSchema"; @@ -229,7 +230,13 @@ export default function Success(props: PageProps) { t, }; - const giphyAppData = getEventTypeAppData(eventType, "giphy"); + const giphyAppData = getEventTypeAppData( + { + ...eventType, + metadata: eventTypeMetaDataSchemaWithTypedApps.parse(eventType.metadata), + }, + "giphy" + ); const giphyImage = giphyAppData?.thankYouPage; const isRoundRobin = eventType.schedulingType === SchedulingType.ROUND_ROBIN; @@ -433,7 +440,10 @@ export default function Success(props: PageProps) { )} - + +
( + routingForms && routingForms.length > 0 ? routingForms[0] : undefined + ); + + if (routingForms && !selectedForm && routingForms.length > 0) { + setSelectedForm(routingForms[0]); + } + + return ( + + +