import { useAutoAnimate } from "@formkit/auto-animate/react"; import Link from "next/link"; import React, { useCallback, useState } from "react"; import { Query, Builder, Utils as QbUtils } from "react-awesome-query-builder"; // types import type { JsonTree, ImmutableTree, BuilderProps } from "react-awesome-query-builder"; import type { UseFormReturn } from "react-hook-form"; import Shell from "@calcom/features/shell/Shell"; import { areTheySiblingEntitites } from "@calcom/lib/entityPermissionUtils"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { trpc } from "@calcom/trpc/react"; import type { inferSSRProps } from "@calcom/types/inferSSRProps"; import { SelectField, FormCard, SelectWithValidation as Select, TextArea, TextField, Badge, Divider, } from "@calcom/ui"; import type { RoutingFormWithResponseCount } from "../../components/SingleForm"; import SingleForm, { getServerSidePropsForSingleFormView as getServerSideProps, } from "../../components/SingleForm"; import "../../components/react-awesome-query-builder/styles.css"; import { RoutingPages } from "../../lib/RoutingPages"; import { createFallbackRoute } from "../../lib/createFallbackRoute"; import { getQueryBuilderConfig } from "../../lib/getQueryBuilderConfig"; import isRouter from "../../lib/isRouter"; import type { GlobalRoute, LocalRoute, QueryBuilderUpdatedConfig, SerializableRoute, } from "../../types/types"; export { getServerSideProps }; const hasRules = (route: Route) => { if (isRouter(route)) return false; route.queryValue.children1 && Object.keys(route.queryValue.children1).length; }; const getEmptyRoute = (): Exclude => { const uuid = QbUtils.uuid(); return { id: uuid, action: { type: "eventTypeRedirectUrl", value: "", }, queryValue: { id: uuid, type: "group" }, }; }; type Route = | (LocalRoute & { // This is what's persisted queryValue: JsonTree; // `queryValue` is parsed to create state state: { tree: ImmutableTree; config: QueryBuilderUpdatedConfig; }; }) | GlobalRoute; const Route = ({ form, route, routes, setRoute, config, setRoutes, moveUp, moveDown, appUrl, disabled = false, }: { form: inferSSRProps["form"]; route: Route; routes: Route[]; setRoute: (id: string, route: Partial) => void; config: QueryBuilderUpdatedConfig; setRoutes: React.Dispatch>; moveUp?: { fn: () => void; check: () => boolean } | null; moveDown?: { fn: () => void; check: () => boolean } | null; appUrl: string; disabled?: boolean; }) => { const index = routes.indexOf(route); const { data: eventTypesByGroup } = trpc.viewer.eventTypes.getByViewer.useQuery(); const eventOptions: { label: string; value: string }[] = []; eventTypesByGroup?.eventTypeGroups.forEach((group) => { const eventTypeValidInContext = areTheySiblingEntitites({ entity1: { teamId: group.teamId ?? null, // group doesn't have userId. The query ensures that it belongs to the user only, if teamId isn't set. So, I am manually setting it to the form userId userId: form.userId, }, entity2: { teamId: form.teamId ?? null, userId: form.userId, }, }); group.eventTypes.forEach((eventType) => { const uniqueSlug = `${group.profile.slug}/${eventType.slug}`; const isRouteAlreadyInUse = isRouter(route) ? false : uniqueSlug === route.action.value; // If Event is already in use, we let it be so as to not break the existing setup if (!isRouteAlreadyInUse && !eventTypeValidInContext) { return; } eventOptions.push({ label: uniqueSlug, value: uniqueSlug, }); }); }); const onChange = (route: Route, immutableTree: ImmutableTree, config: QueryBuilderUpdatedConfig) => { const jsonTree = QbUtils.getTree(immutableTree); setRoute(route.id, { state: { tree: immutableTree, config: config }, queryValue: jsonTree, }); }; const renderBuilder = useCallback( (props: BuilderProps) => (
), [] ); if (isRouter(route)) { return (
routes.length !== 1, fn: () => { const newRoutes = routes.filter((r) => r.id !== route.id); setRoutes(newRoutes); }, }} label={
{`Route ${index + 1}`}
} className="mb-6">
{route.name}

Fields available in {route.name} will be added to this form.

); } return ( routes.length !== 1 && !route.isFallback, fn: () => { const newRoutes = routes.filter((r) => r.id !== route.id); setRoutes(newRoutes); }, }}>
Send Booker to