From aef1705abfa27eb890a97a8783809d794aca8da5 Mon Sep 17 00:00:00 2001 From: hbjORbj Date: Sat, 14 Dec 2024 12:50:52 -0500 Subject: [PATCH 01/14] refactor event type web wrapper --- .../wrappers/EventTypeWebWrapper.tsx | 69 +++---------------- 1 file changed, 8 insertions(+), 61 deletions(-) diff --git a/packages/platform/atoms/event-types/wrappers/EventTypeWebWrapper.tsx b/packages/platform/atoms/event-types/wrappers/EventTypeWebWrapper.tsx index 2819a7a42b8b31..c8ceed3aea9795 100644 --- a/packages/platform/atoms/event-types/wrappers/EventTypeWebWrapper.tsx +++ b/packages/platform/atoms/event-types/wrappers/EventTypeWebWrapper.tsx @@ -3,10 +3,6 @@ import type { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime"; import dynamic from "next/dynamic"; import { usePathname, useRouter as useAppRouter } from "next/navigation"; -// eslint-disable-next-line @calcom/eslint/deprecated-imports-next-router -import { useRouter as usePageRouter } from "next/router"; -// eslint-disable-next-line @calcom/eslint/deprecated-imports-next-router -import type { NextRouter as NextPageRouter } from "next/router"; import { useEffect, useRef, useState } from "react"; import { z } from "zod"; @@ -89,71 +85,34 @@ const EventAITab = dynamic(() => export type EventTypeWebWrapperProps = { id: number; - isAppDir?: boolean; }; -// discriminative factor: isAppDir type EventTypeAppComponentProp = { id: number; - isAppDir: true; pathname: string; - pageRouter: null; appRouter: AppRouterInstance; }; -// discriminative factor: isAppDir -type EventTypePageComponentProp = { - id: number; - isAppDir: false; - pageRouter: NextPageRouter; - pathname: null; - appRouter: null; -}; - -type EventTypeAppPageComponentProp = EventTypeAppComponentProp | EventTypePageComponentProp; - -export const EventTypeWebWrapper = ({ id, isAppDir }: EventTypeWebWrapperProps & { isAppDir?: boolean }) => { +export const EventTypeWebWrapper = ({ id }: EventTypeWebWrapperProps) => { const { data: eventTypeQueryData } = trpc.viewer.eventTypes.get.useQuery({ id }); if (!eventTypeQueryData) return null; - return isAppDir ? ( - - ) : ( - - ); -}; - -const EventTypePageWrapper = ({ id, ...rest }: EventTypeSetupProps & { id: number }) => { - const router = usePageRouter(); - return ( - - ); + return ; }; const EventTypeAppWrapper = ({ id, ...rest }: EventTypeSetupProps & { id: number }) => { const pathname = usePathname(); const router = useAppRouter(); - return ( - - ); + return ; }; const EventTypeWeb = ({ id, - isAppDir, - pageRouter, appRouter, pathname, ...rest -}: EventTypeSetupProps & EventTypeAppPageComponentProp) => { +}: EventTypeSetupProps & EventTypeAppComponentProp) => { const { t } = useLocale(); const utils = trpc.useUtils(); @@ -281,7 +240,7 @@ const EventTypeWeb = ({ } as const; useHandleRouteChange({ - watchTrigger: isAppDir ? pageRouter : pathname, + watchTrigger: pathname, isTeamEventTypeDeleted: isTeamEventTypeDeleted.current, isleavingWithoutAssigningHosts: leaveWithoutAssigningHosts.current, isTeamEventType: !!team, @@ -292,22 +251,10 @@ const EventTypeWeb = ({ onError: (url) => { setIsOpenAssignmentWarnDialog(true); setPendingRoute(url); - if (!isAppDir) { - pageRouter.events.emit( - "routeChangeError", - new Error(`Aborted route change to ${url} because none was assigned to team event`) - ); - throw "Aborted"; - } - - if (isAppDir) throw new Error(`Aborted route change to ${url} because none was assigned to team event`); + throw new Error(`Aborted route change to ${url} because none was assigned to team event`); }, onStart: (handleRouteChange) => { - !isAppDir && pageRouter.events.on("routeChangeStart", handleRouteChange); - isAppDir && handleRouteChange(pathname || ""); - }, - onEnd: (handleRouteChange) => { - !isAppDir && pageRouter.events.off("routeChangeStart", handleRouteChange); + handleRouteChange(pathname || ""); }, }); @@ -370,7 +317,7 @@ const EventTypeWeb = ({ await utils.viewer.eventTypes.invalidate(); showToast(t("event_type_deleted_successfully"), "success"); isTeamEventTypeDeleted.current = true; - isAppDir ? appRouter.push("/event-types") : pageRouter.push("/event-types"); + appRouter.push("/event-types"); setSlugExistsChildrenDialogOpen([]); setIsOpenAssignmentWarnDialog(false); }, From 3a72d3155aca924059a43df662b06755b798dd8c Mon Sep 17 00:00:00 2001 From: hbjORbj Date: Sat, 14 Dec 2024 12:51:06 -0500 Subject: [PATCH 02/14] finish migration --- apps/web/app/future/event-types/[type]/page.tsx | 9 ++++----- .../event-types/views/event-types-listing-view.tsx | 14 ++++---------- .../event-types/views/event-types-single-view.tsx | 2 +- apps/web/pages/event-types/[type]/index.tsx | 8 +------- 4 files changed, 10 insertions(+), 23 deletions(-) diff --git a/apps/web/app/future/event-types/[type]/page.tsx b/apps/web/app/future/event-types/[type]/page.tsx index 6bd794a2b1aac0..2c151f3a2737d6 100644 --- a/apps/web/app/future/event-types/[type]/page.tsx +++ b/apps/web/app/future/event-types/[type]/page.tsx @@ -4,11 +4,10 @@ import { _generateMetadata } from "app/_utils"; import { WithLayout } from "app/layoutHOC"; import { cookies, headers } from "next/headers"; -import { EventType } from "@calcom/atoms/monorepo"; - import { buildLegacyCtx } from "@lib/buildLegacyCtx"; import { getServerSideProps } from "@lib/event-types/[type]/getServerSideProps"; -import type { PageProps as EventTypePageProps } from "@lib/event-types/[type]/getServerSideProps"; + +import EventTypePageWrapper from "~/event-types/views/event-types-single-view"; export const generateMetadata = async ({ params, searchParams }: PageProps) => { const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams); @@ -21,5 +20,5 @@ export const generateMetadata = async ({ params, searchParams }: PageProps) => { }; const getData = withAppDirSsr(getServerSideProps); -const Page = ({ type, ...rest }: EventTypePageProps) => ; -export default WithLayout({ getLayout: null, getData, Page })<"P">; + +export default WithLayout({ getLayout: null, getData, Page: EventTypePageWrapper })<"P">; diff --git a/apps/web/modules/event-types/views/event-types-listing-view.tsx b/apps/web/modules/event-types/views/event-types-listing-view.tsx index b3e6280f818e0a..c85ee5cc8346b5 100644 --- a/apps/web/modules/event-types/views/event-types-listing-view.tsx +++ b/apps/web/modules/event-types/views/event-types-listing-view.tsx @@ -946,10 +946,7 @@ const InfiniteScrollMain = ({ ); }; -const EventTypesPage: React.FC & { - PageWrapper?: AppProps["Component"]["PageWrapper"]; - getLayout?: AppProps["Component"]["getLayout"]; -} = () => { +const EventTypesPage: React.FC = () => { const { t } = useLocale(); const searchParams = useCompatSearchParams(); const { open } = useIntercom(); @@ -1009,17 +1006,14 @@ const EventTypesPage: React.FC & { return ( }> - + { - return ; + return ; }; export default EventTypePageWrapper; diff --git a/apps/web/pages/event-types/[type]/index.tsx b/apps/web/pages/event-types/[type]/index.tsx index 027bd8b837d09a..e02ad5b03870b6 100644 --- a/apps/web/pages/event-types/[type]/index.tsx +++ b/apps/web/pages/event-types/[type]/index.tsx @@ -4,13 +4,7 @@ import PageWrapper from "@components/PageWrapper"; import EventTypePageWrapper from "~/event-types/views/event-types-single-view"; -export type { - FormValues, - CustomInputParsed, - EventTypeSetup, - EventTypeSetupProps, - Host, -} from "@calcom/features/eventtypes/lib/types"; + const Page = (props: PageProps) => ; Page.PageWrapper = PageWrapper; From 09f983340e5d0d1354adfb4e3aa0635f64cbba93 Mon Sep 17 00:00:00 2001 From: hbjORbj Date: Sat, 14 Dec 2024 12:51:26 -0500 Subject: [PATCH 03/14] move event-types folder out of future --- apps/web/app/{future => }/event-types/[type]/page.tsx | 0 apps/web/app/{future => }/event-types/page.tsx | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename apps/web/app/{future => }/event-types/[type]/page.tsx (100%) rename apps/web/app/{future => }/event-types/page.tsx (100%) diff --git a/apps/web/app/future/event-types/[type]/page.tsx b/apps/web/app/event-types/[type]/page.tsx similarity index 100% rename from apps/web/app/future/event-types/[type]/page.tsx rename to apps/web/app/event-types/[type]/page.tsx diff --git a/apps/web/app/future/event-types/page.tsx b/apps/web/app/event-types/page.tsx similarity index 100% rename from apps/web/app/future/event-types/page.tsx rename to apps/web/app/event-types/page.tsx From 01568aae5fce67e3e389a9ac35023d97bbb89636 Mon Sep 17 00:00:00 2001 From: hbjORbj Date: Sat, 14 Dec 2024 12:52:10 -0500 Subject: [PATCH 04/14] remove vars --- .env.example | 2 -- apps/web/abTest/middlewareFactory.ts | 1 - apps/web/middleware.ts | 1 - apps/web/scripts/vercel-app-router-deploy.sh | 1 - turbo.json | 1 - 5 files changed, 6 deletions(-) diff --git a/.env.example b/.env.example index 124aac0ff8c14d..3e739266727aeb 100644 --- a/.env.example +++ b/.env.example @@ -346,8 +346,6 @@ E2E_TEST_OIDC_USER_PASSWORD= # provide a value between 0 and 100 to ensure the percentage of traffic # redirected from the legacy to the future pages AB_TEST_BUCKET_PROBABILITY=50 -# whether we redirect to the future/event-types from event-types or not -APP_ROUTER_EVENT_TYPES_ENABLED=0 APP_ROUTER_APPS_INSTALLED_CATEGORY_ENABLED=0 APP_ROUTER_APPS_SLUG_ENABLED=0 APP_ROUTER_APPS_SLUG_SETUP_ENABLED=0 diff --git a/apps/web/abTest/middlewareFactory.ts b/apps/web/abTest/middlewareFactory.ts index e3555464beee7a..bd441540984c60 100644 --- a/apps/web/abTest/middlewareFactory.ts +++ b/apps/web/abTest/middlewareFactory.ts @@ -6,7 +6,6 @@ import z from "zod"; import { FUTURE_ROUTES_ENABLED_COOKIE_NAME, FUTURE_ROUTES_OVERRIDE_COOKIE_NAME } from "@calcom/lib/constants"; const ROUTES: [URLPattern, boolean][] = [ - ["/event-types", process.env.APP_ROUTER_EVENT_TYPES_ENABLED === "1"] as const, ["/apps/installed/:category", process.env.APP_ROUTER_APPS_INSTALLED_CATEGORY_ENABLED === "1"] as const, ["/apps/:slug", process.env.APP_ROUTER_APPS_SLUG_ENABLED === "1"] as const, ["/apps/:slug/setup", process.env.APP_ROUTER_APPS_SLUG_SETUP_ENABLED === "1"] as const, diff --git a/apps/web/middleware.ts b/apps/web/middleware.ts index 1290b8bd176096..93f263373d93b5 100644 --- a/apps/web/middleware.ts +++ b/apps/web/middleware.ts @@ -172,7 +172,6 @@ export const config = { "/apps/routing_forms/:path*", "/event-types", - "/future/event-types/", "/apps/installed/:category/", "/future/apps/installed/:category/", "/apps/:slug/", diff --git a/apps/web/scripts/vercel-app-router-deploy.sh b/apps/web/scripts/vercel-app-router-deploy.sh index 591c0b3c3c4234..33bcf91604fc68 100755 --- a/apps/web/scripts/vercel-app-router-deploy.sh +++ b/apps/web/scripts/vercel-app-router-deploy.sh @@ -6,7 +6,6 @@ checkRoute () { # These conditionals are used to remove directories from the build that are not needed in production # This is to reduce the size of the build and prevent OOM errors -checkRoute "$APP_ROUTER_EVENT_TYPES_ENABLED" app/future/event-types checkRoute "$APP_ROUTER_APPS_INSTALLED_CATEGORY_ENABLED" app/future/apps/installed checkRoute "$APP_ROUTER_APPS_SLUG_ENABLED" app/future/apps/\[slug\] checkRoute "$APP_ROUTER_APPS_SLUG_SETUP_ENABLED" app/future/apps/\[slug\]/setup diff --git a/turbo.json b/turbo.json index 2eb54ef949c6cb..ea68968c583088 100644 --- a/turbo.json +++ b/turbo.json @@ -239,7 +239,6 @@ "APP_ROUTER_APPS_SLUG_SETUP_ENABLED", "APP_ROUTER_BOOKING_ENABLED", "APP_ROUTER_BOOKINGS_STATUS_ENABLED", - "APP_ROUTER_EVENT_TYPES_ENABLED", "APP_ROUTER_GETTING_STARTED_STEP_ENABLED", "APP_ROUTER_AUTH_FORGOT_PASSWORD_ENABLED", "APP_ROUTER_AUTH_LOGIN_ENABLED", From 8efb797e8523ced380a014da8b04f27e8124e531 Mon Sep 17 00:00:00 2001 From: hbjORbj Date: Sat, 14 Dec 2024 12:55:31 -0500 Subject: [PATCH 05/14] remove pages router --- apps/web/pages/event-types/[type]/index.tsx | 13 ------------- apps/web/pages/event-types/index.tsx | 9 --------- 2 files changed, 22 deletions(-) delete mode 100644 apps/web/pages/event-types/[type]/index.tsx delete mode 100644 apps/web/pages/event-types/index.tsx diff --git a/apps/web/pages/event-types/[type]/index.tsx b/apps/web/pages/event-types/[type]/index.tsx deleted file mode 100644 index e02ad5b03870b6..00000000000000 --- a/apps/web/pages/event-types/[type]/index.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import type { PageProps } from "@lib/event-types/[type]/getServerSideProps"; - -import PageWrapper from "@components/PageWrapper"; - -import EventTypePageWrapper from "~/event-types/views/event-types-single-view"; - - - -const Page = (props: PageProps) => ; -Page.PageWrapper = PageWrapper; - -export { getServerSideProps } from "@lib/event-types/[type]/getServerSideProps"; -export default Page; diff --git a/apps/web/pages/event-types/index.tsx b/apps/web/pages/event-types/index.tsx deleted file mode 100644 index 25af9e4ea4d656..00000000000000 --- a/apps/web/pages/event-types/index.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import PageWrapper from "@components/PageWrapper"; - -import EventTypesPage from "~/event-types/views/event-types-listing-view"; - -export { getServerSideProps } from "@lib/event-types/getServerSideProps"; - -EventTypesPage.PageWrapper = PageWrapper; - -export default EventTypesPage; From 2721da4015e31f935f185545044d5d3f78a8d3e0 Mon Sep 17 00:00:00 2001 From: hbjORbj Date: Sat, 14 Dec 2024 13:29:20 -0500 Subject: [PATCH 06/14] fix --- apps/web/middleware.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/middleware.ts b/apps/web/middleware.ts index 93f263373d93b5..a5c935fc28e0ce 100644 --- a/apps/web/middleware.ts +++ b/apps/web/middleware.ts @@ -171,7 +171,7 @@ export const config = { */ "/apps/routing_forms/:path*", - "/event-types", + "/event-types/:path*", "/apps/installed/:category/", "/future/apps/installed/:category/", "/apps/:slug/", From 5a73373aca88c13e724749ca741d06bdf5d92291 Mon Sep 17 00:00:00 2001 From: hbjORbj Date: Sat, 14 Dec 2024 14:08:15 -0500 Subject: [PATCH 07/14] fix --- .../event-types/views/event-types-listing-view.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/web/modules/event-types/views/event-types-listing-view.tsx b/apps/web/modules/event-types/views/event-types-listing-view.tsx index c85ee5cc8346b5..4be42f30b2db08 100644 --- a/apps/web/modules/event-types/views/event-types-listing-view.tsx +++ b/apps/web/modules/event-types/views/event-types-listing-view.tsx @@ -3,7 +3,7 @@ import { useAutoAnimate } from "@formkit/auto-animate/react"; import { Trans } from "next-i18next"; import Link from "next/link"; -import { usePathname, useRouter } from "next/navigation"; +import { usePathname, useRouter, useSearchParams } from "next/navigation"; import type { FC } from "react"; import { memo, useEffect, useState } from "react"; import { z } from "zod"; @@ -257,7 +257,7 @@ export const InfiniteEventTypeList = ({ const { t } = useLocale(); const router = useRouter(); const pathname = usePathname(); - const searchParams = useCompatSearchParams(); + const searchParams = useSearchParams(); const { copyToClipboard } = useCopy(); const [parent] = useAutoAnimate(); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); @@ -374,7 +374,7 @@ export const InfiniteEventTypeList = ({ // inject selection data into url for correct router history const openDuplicateModal = (eventType: InfiniteEventType, group: InfiniteEventTypeGroup) => { - const newSearchParams = new URLSearchParams(searchParams ?? undefined); + const newSearchParams = new URLSearchParams(searchParams?.toString() ?? undefined); function setParamsIfDefined(key: string, value: string | number | boolean | null | undefined) { if (value) newSearchParams.set(key, value.toString()); if (value === null) newSearchParams.delete(key); @@ -898,7 +898,7 @@ const InfiniteScrollMain = ({ eventTypeGroups: GetUserEventGroupsResponse["eventTypeGroups"] | undefined; profiles: GetUserEventGroupsResponse["profiles"] | undefined; }) => { - const searchParams = useCompatSearchParams(); + const searchParams = useSearchParams(); const { data } = useTypedQuery(querySchema); const orgBranding = useOrgBranding(); @@ -948,7 +948,7 @@ const InfiniteScrollMain = ({ const EventTypesPage: React.FC = () => { const { t } = useLocale(); - const searchParams = useCompatSearchParams(); + const searchParams = useSearchParams(); const { open } = useIntercom(); const { data: user } = useMeQuery(); // eslint-disable-next-line @typescript-eslint/no-unused-vars From a4b7f3563e95922a4adb504e0fea01ab5f8b695b Mon Sep 17 00:00:00 2001 From: Benny Joo Date: Fri, 20 Dec 2024 16:58:18 -0500 Subject: [PATCH 08/14] fix test --- apps/web/playwright/manage-booking-questions.e2e.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/web/playwright/manage-booking-questions.e2e.ts b/apps/web/playwright/manage-booking-questions.e2e.ts index ce2d3bd22e2b95..75d041e74e4219 100644 --- a/apps/web/playwright/manage-booking-questions.e2e.ts +++ b/apps/web/playwright/manage-booking-questions.e2e.ts @@ -231,7 +231,7 @@ test.describe("Manage Booking Questions", () => { }); test.describe("For Team EventType", () => { - test("Do a booking with a user added question and verify a few thing in b/w", async ({ + test("Do a booking with a user added question and verify a few thing in b/w @test", async ({ page, users, context, @@ -258,7 +258,7 @@ test.describe("Manage Booking Questions", () => { await test.step("Go to First Team Event", async () => { await page.getByTestId(`horizontal-tab-${team?.name}`).click(); - await page.waitForLoadState("networkidle"); + await page.waitForSelector("[data-testid=event-types] li a"); const $eventTypes = page.locator("[data-testid=event-types]").locator("li a"); const firstEventTypeElement = $eventTypes.first(); From d033bd894c4d1d48a55771d9d5272ab7f1a9a5ba Mon Sep 17 00:00:00 2001 From: Benny Joo Date: Fri, 20 Dec 2024 17:01:20 -0500 Subject: [PATCH 09/14] remove test tag --- apps/web/playwright/manage-booking-questions.e2e.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/playwright/manage-booking-questions.e2e.ts b/apps/web/playwright/manage-booking-questions.e2e.ts index 75d041e74e4219..849c83e2225d95 100644 --- a/apps/web/playwright/manage-booking-questions.e2e.ts +++ b/apps/web/playwright/manage-booking-questions.e2e.ts @@ -231,7 +231,7 @@ test.describe("Manage Booking Questions", () => { }); test.describe("For Team EventType", () => { - test("Do a booking with a user added question and verify a few thing in b/w @test", async ({ + test("Do a booking with a user added question and verify a few thing in b/w", async ({ page, users, context, From 80aca22b2bff5ffdc60d0b9cb33c1241d04a2ff3 Mon Sep 17 00:00:00 2001 From: Benny Joo Date: Fri, 20 Dec 2024 17:21:10 -0500 Subject: [PATCH 10/14] refactor --- .../wrappers/EventTypeWebWrapper.tsx | 25 +++---------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/packages/platform/atoms/event-types/wrappers/EventTypeWebWrapper.tsx b/packages/platform/atoms/event-types/wrappers/EventTypeWebWrapper.tsx index c8ceed3aea9795..c3f4601cc5ae13 100644 --- a/packages/platform/atoms/event-types/wrappers/EventTypeWebWrapper.tsx +++ b/packages/platform/atoms/event-types/wrappers/EventTypeWebWrapper.tsx @@ -1,6 +1,5 @@ "use client"; -import type { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime"; import dynamic from "next/dynamic"; import { usePathname, useRouter as useAppRouter } from "next/navigation"; import { useEffect, useRef, useState } from "react"; @@ -87,35 +86,19 @@ export type EventTypeWebWrapperProps = { id: number; }; -type EventTypeAppComponentProp = { - id: number; - pathname: string; - appRouter: AppRouterInstance; -}; - export const EventTypeWebWrapper = ({ id }: EventTypeWebWrapperProps) => { const { data: eventTypeQueryData } = trpc.viewer.eventTypes.get.useQuery({ id }); if (!eventTypeQueryData) return null; - return ; -}; - -const EventTypeAppWrapper = ({ id, ...rest }: EventTypeSetupProps & { id: number }) => { - const pathname = usePathname(); - const router = useAppRouter(); - return ; + return ; }; -const EventTypeWeb = ({ - id, - appRouter, - pathname, - ...rest -}: EventTypeSetupProps & EventTypeAppComponentProp) => { +const EventTypeWeb = ({ id, ...rest }: EventTypeSetupProps & { id: number }) => { const { t } = useLocale(); const utils = trpc.useUtils(); - + const pathname = usePathname(); + const appRouter = useAppRouter(); const { data: user, isPending: isLoggedInUserPending } = useMeQuery(); const isTeamEventTypeDeleted = useRef(false); const leaveWithoutAssigningHosts = useRef(false); From 76287f12bfc289919f6207bbf2a73ffbc139b08c Mon Sep 17 00:00:00 2001 From: Benny Joo Date: Fri, 20 Dec 2024 18:07:06 -0500 Subject: [PATCH 11/14] remove completely --- apps/web/playwright/manage-booking-questions.e2e.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/web/playwright/manage-booking-questions.e2e.ts b/apps/web/playwright/manage-booking-questions.e2e.ts index 849c83e2225d95..41fe6c46c4cf22 100644 --- a/apps/web/playwright/manage-booking-questions.e2e.ts +++ b/apps/web/playwright/manage-booking-questions.e2e.ts @@ -258,8 +258,6 @@ test.describe("Manage Booking Questions", () => { await test.step("Go to First Team Event", async () => { await page.getByTestId(`horizontal-tab-${team?.name}`).click(); - await page.waitForSelector("[data-testid=event-types] li a"); - const $eventTypes = page.locator("[data-testid=event-types]").locator("li a"); const firstEventTypeElement = $eventTypes.first(); From 0c28ff272aae1e69a2071460e79f1555ca6e4069 Mon Sep 17 00:00:00 2001 From: Benny Joo Date: Sat, 28 Dec 2024 14:14:21 -0500 Subject: [PATCH 12/14] add withoutSeo prop for event type web page --- packages/features/eventtypes/components/EventTypeLayout.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/features/eventtypes/components/EventTypeLayout.tsx b/packages/features/eventtypes/components/EventTypeLayout.tsx index 4b2a69f05f1231..526060cd9052f9 100644 --- a/packages/features/eventtypes/components/EventTypeLayout.tsx +++ b/packages/features/eventtypes/components/EventTypeLayout.tsx @@ -101,6 +101,7 @@ function EventTypeSingleLayout({ backPath="/event-types" title={`${eventType.title} | ${t("event_type")}`} heading={eventType.title} + withoutSeo={!isPlatform} // Metadata is handled by App Router Metadata API for Event Type Web Page CTA={
{!formMethods.getValues("metadata")?.managedEventConfig && ( From 4e5cdf367104074d0c62339f22b52ef361c2d7b3 Mon Sep 17 00:00:00 2001 From: Benny Joo Date: Sat, 28 Dec 2024 14:14:37 -0500 Subject: [PATCH 13/14] remove HeadSeo usage from event types listing view --- .../web/modules/event-types/views/event-types-listing-view.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/web/modules/event-types/views/event-types-listing-view.tsx b/apps/web/modules/event-types/views/event-types-listing-view.tsx index 4be42f30b2db08..bf9c5e56a9f688 100644 --- a/apps/web/modules/event-types/views/event-types-listing-view.tsx +++ b/apps/web/modules/event-types/views/event-types-listing-view.tsx @@ -48,7 +48,6 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, EmptyScreen, - HeadSeo, HorizontalTabs, Icon, Label, @@ -1013,8 +1012,6 @@ const EventTypesPage: React.FC = () => { hideHeadingOnMobile subtitle={t("event_types_page_subtitle")} CTA={}> - - Date: Sat, 28 Dec 2024 15:17:05 -0500 Subject: [PATCH 14/14] make onboarding e2e test faster --- apps/web/playwright/onboarding.e2e.ts | 153 ++++++++++++-------------- 1 file changed, 73 insertions(+), 80 deletions(-) diff --git a/apps/web/playwright/onboarding.e2e.ts b/apps/web/playwright/onboarding.e2e.ts index 94aecd6faca589..dd93e58ff57e3c 100644 --- a/apps/web/playwright/onboarding.e2e.ts +++ b/apps/web/playwright/onboarding.e2e.ts @@ -1,93 +1,86 @@ -/* eslint-disable playwright/no-skipped-test */ import { expect } from "@playwright/test"; import { IdentityProvider } from "@calcom/prisma/enums"; import { test } from "./lib/fixtures"; -test.describe.configure({ mode: "serial" }); +test.describe.configure({ mode: "parallel" }); test.afterEach(({ users }) => users.deleteAll()); test.describe("Onboarding", () => { - test.describe("Onboarding v2", () => { - const testOnboarding = (identityProvider: IdentityProvider) => { - test(`Onboarding Flow - ${identityProvider} user`, async ({ page, users }) => { - const user = await users.create({ - completedOnboarding: false, - name: null, - identityProvider, - }); - await user.apiLogin(); - await page.goto("/getting-started"); - // tests whether the user makes it to /getting-started - // after login with completedOnboarding false - await page.waitForURL("/getting-started"); - - await test.step("step 1 - User Settings", async () => { - // Check required fields - await page.locator("button[type=submit]").click(); - await expect(page.locator("data-testid=required")).toBeVisible(); - - // happy path - await page.locator("input[name=username]").fill("new user onboarding"); - await page.locator("input[name=name]").fill("new user 2"); - await page.locator("input[role=combobox]").click(); - await page - .locator("*") - .filter({ hasText: /^Europe\/London/ }) - .first() - .click(); - await page.locator("button[type=submit]").click(); - - await expect(page).toHaveURL(/.*connected-calendar/); - - const userComplete = await user.self(); - expect(userComplete.name).toBe("new user 2"); - }); - - await test.step("step 2 - Connected Calendar", async () => { - const isDisabled = await page.locator("button[data-testid=save-calendar-button]").isDisabled(); - await expect(isDisabled).toBe(true); - // tests skip button, we don't want to test entire flow. - await page.locator("button[data-testid=skip-step]").click(); - - await expect(page).toHaveURL(/.*connected-video/); - }); - - await test.step("step 3 - Connected Video", async () => { - const isDisabled = await page.locator("button[data-testid=save-video-button]").isDisabled(); - await expect(isDisabled).toBe(true); - // tests skip button, we don't want to test entire flow. - await page.locator("button[data-testid=skip-step]").click(); - - await expect(page).toHaveURL(/.*setup-availability/); - }); - - await test.step("step 4 - Setup Availability", async () => { - const isDisabled = await page.locator("button[data-testid=save-availability]").isDisabled(); - await expect(isDisabled).toBe(false); - // same here, skip this step. - await page.locator("button[data-testid=save-availability]").click(); - - await expect(page).toHaveURL(/.*user-profile/); - }); - - await test.step("step 5- User Profile", async () => { - await page.locator("button[type=submit]").click(); - - // should redirect to /event-types after onboarding - await page.waitForURL("/event-types"); - - const userComplete = await user.self(); - - expect(userComplete.bio?.replace("


", "").length).toBe(0); - }); + const testOnboarding = (identityProvider: IdentityProvider) => { + test(`Onboarding Flow - ${identityProvider} user`, async ({ page, users }) => { + const user = await users.create({ + completedOnboarding: false, + name: null, + identityProvider, }); - }; + await user.apiLogin(); + await page.goto("/getting-started"); + // tests whether the user makes it to /getting-started + // after login with completedOnboarding false + await page.waitForURL("/getting-started"); + + await test.step("step 1 - User Settings", async () => { + // Check required fields + await page.locator("button[type=submit]").click(); + await expect(page.locator("data-testid=required")).toBeVisible(); + + // happy path + await page.locator("input[name=username]").fill("new user onboarding"); + await page.locator("input[name=name]").fill("new user 2"); + await page.locator("input[role=combobox]").click(); + await page + .locator("*") + .filter({ hasText: /^Europe\/London/ }) + .first() + .click(); + await page.locator("button[type=submit]").click(); + + await expect(page).toHaveURL(/.*connected-calendar/); + + const userComplete = await user.self(); + expect(userComplete.name).toBe("new user 2"); + }); + + await test.step("step 2 - Connected Calendar", async () => { + const isDisabled = await page.locator("button[data-testid=save-calendar-button]").isDisabled(); + await expect(isDisabled).toBe(true); + // tests skip button, we don't want to test entire flow. + await page.locator("button[data-testid=skip-step]").click(); + await expect(page).toHaveURL(/.*connected-video/); + }); + + await test.step("step 3 - Connected Video", async () => { + const isDisabled = await page.locator("button[data-testid=save-video-button]").isDisabled(); + await expect(isDisabled).toBe(true); + // tests skip button, we don't want to test entire flow. + await page.locator("button[data-testid=skip-step]").click(); + await expect(page).toHaveURL(/.*setup-availability/); + }); + + await test.step("step 4 - Setup Availability", async () => { + const isDisabled = await page.locator("button[data-testid=save-availability]").isDisabled(); + await expect(isDisabled).toBe(false); + // same here, skip this step. + + await page.locator("button[data-testid=save-availability]").click(); + await expect(page).toHaveURL(/.*user-profile/); + }); + + await test.step("step 5- User Profile", async () => { + await page.locator("button[type=submit]").click(); + // should redirect to /event-types after onboarding + await page.waitForURL("/event-types"); + + const userComplete = await user.self(); + expect(userComplete.bio?.replace("


", "").length).toBe(0); + }); + }); + }; - testOnboarding(IdentityProvider.GOOGLE); - testOnboarding(IdentityProvider.CAL); - testOnboarding(IdentityProvider.SAML); - }); + testOnboarding(IdentityProvider.GOOGLE); + testOnboarding(IdentityProvider.CAL); + testOnboarding(IdentityProvider.SAML); });