Skip to content

Commit

Permalink
Migrated to core
Browse files Browse the repository at this point in the history
  • Loading branch information
Hariom Balhara committed Feb 3, 2025
1 parent 9608669 commit 0e16ec1
Show file tree
Hide file tree
Showing 175 changed files with 2,383 additions and 728 deletions.
1 change: 1 addition & 0 deletions PR_TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Webhooks iterate over apps to identify routing webhooks - It needs to be fixed
20 changes: 10 additions & 10 deletions apps/web/components/dialog/RerouteDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import { useState } from "react";
import { useEffect, useCallback } from "react";
import type { z } from "zod";

import FormInputFields, {
FormInputFieldsSkeleton,
} from "@calcom/app-store/routing-forms/components/FormInputFields";
import { getAbsoluteEventTypeRedirectUrl } from "@calcom/app-store/routing-forms/getEventTypeRedirectUrl";
import { findMatchingRoute } from "@calcom/app-store/routing-forms/lib/processRoute";
import { substituteVariables } from "@calcom/app-store/routing-forms/lib/substituteVariables";
import { getUrlSearchParamsToForwardForReroute } from "@calcom/app-store/routing-forms/pages/routing-link/getUrlSearchParamsToForward";
import type { FormResponse, LocalRoute } from "@calcom/app-store/routing-forms/types/types";
import { RouteActionType } from "@calcom/app-store/routing-forms/zod";
import dayjs from "@calcom/dayjs";
import { createBooking } from "@calcom/features/bookings/lib/create-booking";
import FormInputFields, {
FormInputFieldsSkeleton,
} from "@calcom/features/routing-forms/components/FormInputFields";
import { getAbsoluteEventTypeRedirectUrl } from "@calcom/features/routing-forms/getEventTypeRedirectUrl";
import { getUrlSearchParamsToForwardForReroute } from "@calcom/features/routing-forms/lib/getUrlSearchParamsToForward";
import { findMatchingRoute } from "@calcom/features/routing-forms/lib/processRoute";
import { substituteVariables } from "@calcom/features/routing-forms/lib/substituteVariables";
import type { FormResponse, LocalRoute } from "@calcom/features/routing-forms/types/types";
import { RouteActionType } from "@calcom/features/routing-forms/zod";
import { useBookerUrl } from "@calcom/lib/hooks/useBookerUrl";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { EventType, User, Team, Attendee, Booking as PrismaBooking } from "@calcom/prisma/client";
Expand All @@ -35,7 +35,7 @@ const enum ReroutingStatusEnum {
REROUTING_FAILED = "failed",
}

type ResponseWithForm = RouterOutputs["viewer"]["appRoutingForms"]["getResponseWithFormFields"];
type ResponseWithForm = RouterOutputs["viewer"]["routingForms"]["getResponseWithFormFields"];

type BookingToReroute = Pick<PrismaBooking, "metadata" | "responses" | "id" | "uid" | "title" | "status"> & {
routedFromRoutingFormReponse: {
Expand Down
6 changes: 3 additions & 3 deletions apps/web/components/dialog/__tests__/RerouteDialog.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { act, fireEvent, render, screen } from "@testing-library/react";
import { vi } from "vitest";

import { RouteActionType } from "@calcom/app-store/routing-forms/zod";
import { RouteActionType } from "@calcom/features/routing-forms/zod";
import { BookingStatus, SchedulingType } from "@calcom/prisma/enums";

import { RerouteDialog } from "../RerouteDialog";
Expand All @@ -20,7 +20,7 @@ vi.mock("next/navigation", async (importOriginal) => {
};
});

vi.mock("@calcom/app-store/routing-forms/lib/processRoute", () => ({
vi.mock("@calcom/features/routing-forms/lib/processRoute", () => ({
findMatchingRoute: vi.fn(({ form, response }) => {
return form.routes.find((route: any) => route.__testMatching);
}),
Expand All @@ -36,7 +36,7 @@ const mockOpen = vi.fn((_url: string) => {

vi.stubGlobal("open", mockOpen);

vi.mock("@calcom/app-store/routing-forms/components/FormInputFields", () => ({
vi.mock("@calcom/features/routing-forms/components/FormInputFields", () => ({
default: vi.fn(({ response, form, setResponse, disabledFields }) => {
return (
<div data-testid="mock-form-input-fields">
Expand Down
8 changes: 4 additions & 4 deletions apps/web/lib/__tests__/getTeamMemberEmailFromCrm.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { v4 } from "uuid";
import { describe, expect, it, vi, beforeEach } from "vitest";

import { getCRMContactOwnerForRRLeadSkip } from "@calcom/app-store/_utils/CRMRoundRobinSkip";
import bookingFormHandlers from "@calcom/app-store/routing-forms/appBookingFormHandler";
import { ROUTING_FORM_RESPONSE_ID_QUERY_STRING } from "@calcom/app-store/routing-forms/lib/constants";
import { RouteActionType } from "@calcom/app-store/routing-forms/zod";
import bookingFormHandlers from "@calcom/features/routing-forms/appBookingFormHandler";
import { ROUTING_FORM_RESPONSE_ID_QUERY_STRING } from "@calcom/features/routing-forms/lib/constants";
import { RouteActionType } from "@calcom/features/routing-forms/zod";
import { SchedulingType } from "@calcom/prisma/enums";

import { getTeamMemberEmailForResponseOrContactUsingUrlQuery } from "../getTeamMemberEmailFromCrm";

vi.mock("@calcom/app-store/routing-forms/appBookingFormHandler", () => ({
vi.mock("@calcom/features/routing-forms/appBookingFormHandler", () => ({
default: {
salesforce: vi.fn(),
},
Expand Down
115 changes: 8 additions & 107 deletions apps/web/lib/apps/[slug]/[...pages]/getServerSideProps.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,6 @@
import type { GetServerSidePropsContext, GetServerSidePropsResult } from "next";
import { z } from "zod";

import { getAppWithMetadata } from "@calcom/app-store/_appRegistry";
import RoutingFormsRoutingConfig from "@calcom/app-store/routing-forms/pages/app-routing.config";
import TypeformRoutingConfig from "@calcom/app-store/typeform/pages/app-routing.config";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import prisma from "@calcom/prisma";
import type { AppGetServerSideProps } from "@calcom/types/AppGetServerSideProps";

import type { AppProps } from "@lib/app-providers";

import { ssrInit } from "@server/lib/ssr";

type AppPageType = {
getServerSideProps?: AppGetServerSideProps;
// A component than can accept any properties
// eslint-disable-next-line @typescript-eslint/no-explicit-any
default: ((props: any) => JSX.Element) &
Pick<AppProps["Component"], "isBookingPage" | "getLayout" | "PageWrapper">;
};

type Found = {
notFound: false;
Component: AppPageType["default"];
getServerSideProps: AppPageType["getServerSideProps"];
};

type NotFound = {
notFound: true;
};

// TODO: It is a candidate for apps.*.generated.*
const AppsRouting = {
"routing-forms": RoutingFormsRoutingConfig,
typeform: TypeformRoutingConfig,
};

function getRoute(appName: string, pages: string[]) {
const routingConfig = AppsRouting[appName as keyof typeof AppsRouting] as Record<string, AppPageType>;

if (!routingConfig) {
return {
notFound: true,
} as NotFound;
}
const mainPage = pages[0];
const appPage = routingConfig.layoutHandler || (routingConfig[mainPage] as AppPageType);
if (!appPage) {
return {
notFound: true,
} as NotFound;
}
return { notFound: false, Component: appPage.default, ...appPage } as Found;
}

const paramsSchema = z.object({
slug: z.string(),
pages: z.array(z.string()),
Expand All @@ -62,7 +9,7 @@ const paramsSchema = z.object({
export async function getServerSideProps(
context: GetServerSidePropsContext
): Promise<GetServerSidePropsResult<any>> {
const { params, req } = context;
const { params } = context;
if (!params) {
return {
notFound: true,
Expand All @@ -78,58 +25,12 @@ export async function getServerSideProps(

const appName = parsedParams.data.slug;
const pages = parsedParams.data.pages;
const route = getRoute(appName, pages);

if (route.notFound) {
return { notFound: true };
}

if (route.getServerSideProps) {
// TODO: Document somewhere that right now it is just a convention that filename should have appPages in it's name.
// appPages is actually hardcoded here and no matter the fileName the same variable would be used.
// We can write some validation logic later on that ensures that [...appPages].tsx file exists
params.appPages = pages.slice(1);
const session = await getServerSession({ req });
const user = session?.user;
const app = await getAppWithMetadata({ slug: appName });

if (!app) {
return {
notFound: true,
};
}

const result = await route.getServerSideProps(
context as GetServerSidePropsContext<{
slug: string;
pages: string[];
appPages: string[];
}>,
prisma,
user,
ssrInit
);

if (result.notFound) {
return { notFound: true };
}

if (result.redirect) {
return { redirect: result.redirect };
}

return {
props: {
appName,
appUrl: app.simplePath || `/apps/${appName}`,
...result.props,
},
};
} else {
return {
props: {
appName,
},
};
}
// Redirect to the actual page using Next.js routing
return {
redirect: {
destination: `/${appName}/${pages.join("/")}`,
permanent: false,
},
};
}
10 changes: 5 additions & 5 deletions apps/web/lib/getTeamMemberEmailFromCrm.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { ParsedUrlQuery } from "querystring";

import { getCRMContactOwnerForRRLeadSkip } from "@calcom/app-store/_utils/CRMRoundRobinSkip";
import { ROUTING_FORM_RESPONSE_ID_QUERY_STRING } from "@calcom/app-store/routing-forms/lib/constants";
import { enabledAppSlugs } from "@calcom/app-store/routing-forms/lib/enabledApps";
import type { AttributeRoutingConfig, LocalRoute } from "@calcom/app-store/routing-forms/types/types";
import { zodRoutes as routesSchema } from "@calcom/app-store/routing-forms/zod";
import { ROUTING_FORM_RESPONSE_ID_QUERY_STRING } from "@calcom/features/routing-forms/lib/constants";
import { enabledAppSlugs } from "@calcom/features/routing-forms/lib/enabledApps";
import type { AttributeRoutingConfig, LocalRoute } from "@calcom/features/routing-forms/types/types";
import { zodRoutes as routesSchema } from "@calcom/features/routing-forms/zod";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import prisma from "@calcom/prisma";
Expand Down Expand Up @@ -151,7 +151,7 @@ async function getTeamMemberEmailUsingRoutingFormHandler({
// If the skipContactOwner is enabled then don't return an team member email
if (attributeRoutingConfig.skipContactOwner) return { ...nullReturnValue, skipContactOwner: true };

const appBookingFormHandler = (await import("@calcom/app-store/routing-forms/appBookingFormHandler"))
const appBookingFormHandler = (await import("@calcom/features/routing-forms/appBookingFormHandler"))
.default;
const appHandler = appBookingFormHandler[crmAppSlug];
if (!appHandler) return nullReturnValue;
Expand Down
2 changes: 0 additions & 2 deletions apps/web/modules/apps/[slug]/[...pages]/pages-view.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"use client";

import RoutingFormsRoutingConfig from "@calcom/app-store/routing-forms/pages/app-routing.config";
import TypeformRoutingConfig from "@calcom/app-store/typeform/pages/app-routing.config";
import { useParamsWithFallback } from "@calcom/lib/hooks/useParamsWithFallback";
import type { AppGetServerSideProps } from "@calcom/types/AppGetServerSideProps";
Expand Down Expand Up @@ -29,7 +28,6 @@ type NotFound = {

// TODO: It is a candidate for apps.*.generated.*
const AppsRouting = {
"routing-forms": RoutingFormsRoutingConfig,
typeform: TypeformRoutingConfig,
};

Expand Down
4 changes: 2 additions & 2 deletions apps/web/modules/insights/insights-virtual-queues-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import { useState } from "react";

import { TestForm } from "@calcom/app-store/routing-forms/components/SingleForm";
import type { RoutingForm } from "@calcom/app-store/routing-forms/types/types";
import { TestForm } from "@calcom/features/routing-forms/components/SingleForm";
import type { RoutingForm } from "@calcom/features/routing-forms/types/types";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc";
import { Label, Select } from "@calcom/ui";
Expand Down
2 changes: 1 addition & 1 deletion apps/web/pages/api/trpc/appRoutingForms/[trpc].ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import appRoutingForms from "@calcom/app-store/routing-forms/trpc-router";
import appRoutingForms from "@calcom/features/routing-forms/trpc-router";
import { createNextApiHandler } from "@calcom/trpc/server/createNextApiHandler";

export default createNextApiHandler(appRoutingForms);
22 changes: 9 additions & 13 deletions apps/web/pages/apps/[slug]/[...pages].tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import { getServerSideProps } from "@lib/apps/[slug]/[...pages]/getServerSideProps";
import type { GetServerSideProps } from "next";

import PageWrapper from "@components/PageWrapper";
export const getServerSideProps: GetServerSideProps = async (context) => {
return {
notFound: true, // This will let Next.js handle the routing through the pages directory
};
};

import type { PageProps } from "~/apps/[slug]/[...pages]/pages-view";
import PagesView, { getLayout } from "~/apps/[slug]/[...pages]/pages-view";

const Page = (props: PageProps) => <PagesView {...props} />;

Page.PageWrapper = PageWrapper;
Page.getLayout = getLayout;

export { getServerSideProps };

export default Page;
export default function AppPage() {
return null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ import type { UseFormReturn } from "react-hook-form";
import { Controller, useFieldArray, useWatch } from "react-hook-form";
import { v4 as uuidv4 } from "uuid";

import Shell from "@calcom/features/shell/Shell";
import type { RoutingFormWithResponseCount } from "@calcom/features/routing-forms/components/SingleForm";
import SingleForm from "@calcom/features/routing-forms/components/SingleForm";
import getLayout from "@calcom/features/routing-forms/getLayout";
import { getServerSideProps } from "@calcom/features/routing-forms/getServerSidePropsSingleForm";
import { FieldTypes } from "@calcom/features/routing-forms/lib/FieldTypes";
import classNames from "@calcom/lib/classNames";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { inferSSRProps } from "@calcom/types/inferSSRProps";
import {
BooleanToggleGroupField,
Button,
Expand All @@ -21,15 +26,10 @@ import {
TextField,
} from "@calcom/ui";

import type { inferSSRProps } from "@lib/types/inferSSRProps";

import type { RoutingFormWithResponseCount } from "../../components/SingleForm";
import SingleForm, {
getServerSidePropsForSingleFormView as getServerSideProps,
} from "../../components/SingleForm";
import { FieldTypes } from "../../lib/FieldTypes";
import PageWrapper from "@components/PageWrapper";

export { getServerSideProps };

type SelectOption = { label: string; id: string | null };
type HookForm = UseFormReturn<RoutingFormWithResponseCount>;

Expand Down Expand Up @@ -480,10 +480,6 @@ export default function FormEditPage({
);
}

FormEditPage.getLayout = (page: React.ReactElement) => {
return (
<Shell backPath="/apps/routing-forms/forms" withoutMain={true}>
{page}
</Shell>
);
};
FormEditPage.getLayout = getLayout;

FormEditPage.PageWrapper = PageWrapper;
Loading

0 comments on commit 0e16ec1

Please sign in to comment.