refactor: eliminate all @calcom/trpc/react imports and tRPC hooks from @calcom/features (#27728)
* migrate booker layout selector * move schedule hooks and types * migrate feature opt in components * migrate feedback dialog * update * migrate schedule hooks * migrate useSegments * update * update import paths * fix import paths * mv useTimesForSchedule back to features * fix * add useEvent to web * remove the old file * update imports * clean up * migrate Segment * update imports * update imports * fix name * fix tests * fix * fix * update imports * remove trpc/react * remove trpc dependency from package.json * rm * wip * wip * fix types * fix * migrate PhoneInput * mv LocationInput * remove dead file * update import paths * rm dead import * rm useApp hook * cleanup * wip * restore * wip * remove dead code * fix * simplify * fix * fix * fix * fix * fix * fix * format * format * restore * remove prop
This commit is contained in:
@@ -64,9 +64,6 @@ vi.mock("@calcom/web/modules/shell/Shell", () => ({
|
||||
ShellMain: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@calcom/lib/hooks/useApp", () => ({
|
||||
default: vi.fn(),
|
||||
}));
|
||||
/**
|
||||
* Avoids the error due to Formbricks
|
||||
*/
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
OrganizerDefaultConferencingAppType,
|
||||
} from "@calcom/app-store/locations";
|
||||
import { Dialog } from "@calcom/features/components/controlled-dialog";
|
||||
import PhoneInput from "@calcom/features/components/phone-input";
|
||||
import PhoneInput from "@calcom/web/components/phone-input";
|
||||
import type { LocationOption } from "@calcom/features/form/components/LocationSelect";
|
||||
import LocationSelect from "@calcom/features/form/components/LocationSelect";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
|
||||
@@ -8,7 +8,7 @@ import { DefaultEventLocationTypeEnum } from "@calcom/app-store/locations";
|
||||
import { useBookerStore } from "@calcom/features/bookings/Booker/store";
|
||||
import type { GetBookingType } from "@calcom/features/bookings/lib/get-booking";
|
||||
import getLocationOptionsForSelect from "@calcom/features/bookings/lib/getLocationOptionsForSelect";
|
||||
import { FormBuilderField } from "@calcom/features/form-builder/FormBuilderField";
|
||||
import { FormBuilderField } from "@calcom/web/modules/form-builder/components/FormBuilderField";
|
||||
import { fieldTypesConfigMap } from "@calcom/features/form-builder/fieldTypes";
|
||||
import { fieldsThatSupportLabelAsSafeHtml } from "@calcom/features/form-builder/fieldsThatSupportLabelAsSafeHtml";
|
||||
import { SystemField } from "@calcom/lib/bookings/SystemField";
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Controller, useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
import { Dialog } from "@calcom/features/components/controlled-dialog";
|
||||
import PhoneInput from "@calcom/features/components/phone-input";
|
||||
import PhoneInput from "@calcom/web/components/phone-input";
|
||||
import { WORKFLOW_ACTIONS } from "@calcom/features/ee/workflows/lib/constants";
|
||||
import { onlyLettersNumbersSpaces } from "@calcom/features/ee/workflows/lib/schema";
|
||||
import { SENDER_ID, SENDER_NAME } from "@calcom/lib/constants";
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useState } from "react";
|
||||
import type { UseFormReturn } from "react-hook-form";
|
||||
|
||||
import { Dialog } from "@calcom/features/components/controlled-dialog";
|
||||
import PhoneInput from "@calcom/features/components/phone-input";
|
||||
import PhoneInput from "@calcom/web/components/phone-input";
|
||||
import { getEventTypeIdForCalAiTest } from "@calcom/features/ee/workflows/lib/actionHelperFunctions";
|
||||
import type { FormValues } from "@calcom/features/ee/workflows/lib/types";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
|
||||
@@ -8,7 +8,7 @@ import "react-phone-number-input/style.css";
|
||||
|
||||
import type { RetellAgentWithDetails } from "@calcom/features/calAIPhone/providers/retellAI";
|
||||
import { Dialog } from "@calcom/features/components/controlled-dialog";
|
||||
import PhoneInput from "@calcom/features/components/phone-input";
|
||||
import PhoneInput from "@calcom/web/components/phone-input";
|
||||
import {
|
||||
isSMSAction,
|
||||
isWhatsappAction,
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import classNames from "@calcom/ui/classNames";
|
||||
import { TextField } from "@calcom/ui/components/form";
|
||||
|
||||
import LocationInput from "@calcom/features/eventtypes/components/locations/LocationInput";
|
||||
import LocationInput from "./LocationInput";
|
||||
import LocationOptionContainer from "./LocationSettingsContainer";
|
||||
|
||||
const DefaultLocationSettings = ({
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
isStaticLocationType,
|
||||
} from "@calcom/app-store/locations";
|
||||
import { getAppFromSlug } from "@calcom/app-store/utils";
|
||||
import PhoneInput from "@calcom/features/components/phone-input";
|
||||
import PhoneInput from "@calcom/web/components/phone-input";
|
||||
import invertLogoOnDark from "@calcom/lib/invertLogoOnDark";
|
||||
import type { LocationOption } from "@calcom/features/form/components/LocationSelect";
|
||||
import LocationSelect from "@calcom/features/form/components/LocationSelect";
|
||||
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
import { useFormContext, Controller } from "react-hook-form";
|
||||
|
||||
import type { EventLocationType } from "@calcom/app-store/locations";
|
||||
import PhoneInput from "@calcom/features/components/phone-input";
|
||||
import PhoneInput from "@calcom/web/components/phone-input";
|
||||
import type { FormValues } from "@calcom/features/eventtypes/lib/types";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import classNames from "@calcom/ui/classNames";
|
||||
import { TextField } from "@calcom/ui/components/form";
|
||||
|
||||
import type { LocationInputCustomClassNames } from "./types";
|
||||
import type { LocationInputCustomClassNames } from "@calcom/features/eventtypes/components/locations/types";
|
||||
|
||||
const LocationInput = (props: {
|
||||
eventLocationType: EventLocationType;
|
||||
@@ -23,7 +23,7 @@ import { showToast } from "@calcom/ui/components/toast";
|
||||
|
||||
import CalVideoSettings from "./CalVideoSettings";
|
||||
import DefaultLocationSettings from "./DefaultLocationSettings";
|
||||
import LocationInput from "@calcom/features/eventtypes/components/locations/LocationInput";
|
||||
import LocationInput from "./LocationInput";
|
||||
|
||||
export type TEventTypeLocation = Pick<EventTypeSetupProps["eventType"], "locations" | "calVideoSettings">;
|
||||
export type TLocationOptions = Pick<EventTypeSetupProps, "locationOptions">["locationOptions"];
|
||||
|
||||
@@ -7,10 +7,10 @@ import { z } from "zod";
|
||||
import { getTemplateFieldsSchema } from "@calcom/features/calAIPhone/getTemplateFieldsSchema";
|
||||
import { templateFieldsMap } from "@calcom/features/calAIPhone/template-fields-map";
|
||||
import type { TemplateType } from "@calcom/features/calAIPhone/zod-utils";
|
||||
import PhoneInput from "@calcom/features/components/phone-input";
|
||||
import PhoneInput from "@calcom/web/components/phone-input";
|
||||
import LicenseRequired from "~/ee/common/components/LicenseRequired";
|
||||
import type { EventTypeSetup, FormValues } from "@calcom/features/eventtypes/lib/types";
|
||||
import { ComponentForField } from "@calcom/features/form-builder/FormBuilderField";
|
||||
import { ComponentForField } from "@calcom/web/modules/form-builder/components/FormBuilderField";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import classNames from "@calcom/ui/classNames";
|
||||
|
||||
+3
-3
@@ -6,7 +6,7 @@ import type {
|
||||
TextLikeComponentProps,
|
||||
} from "@calcom/app-store/routing-forms/components/react-awesome-query-builder/widgets";
|
||||
import Widgets from "@calcom/app-store/routing-forms/components/react-awesome-query-builder/widgets";
|
||||
import PhoneInput from "@calcom/features/components/phone-input";
|
||||
import PhoneInput from "@calcom/web/components/phone-input";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import type { fieldSchema, variantsConfigSchema, FieldType } from "@calcom/prisma/zod-utils";
|
||||
import { AddressInput } from "@calcom/ui/components/address";
|
||||
@@ -18,8 +18,8 @@ import { RadioGroup, RadioField } from "@calcom/ui/components/radio";
|
||||
import { Tooltip } from "@calcom/ui/components/tooltip";
|
||||
|
||||
import { ComponentForField } from "./FormBuilderField";
|
||||
import { propsTypes } from "./propsTypes";
|
||||
import { preprocessNameFieldDataWithVariant } from "./utils";
|
||||
import { propsTypes } from "@calcom/features/form-builder/propsTypes";
|
||||
import { preprocessNameFieldDataWithVariant } from "@calcom/features/form-builder/utils";
|
||||
|
||||
export const isValidValueProp: Record<Component["propsType"], (val: unknown) => boolean> = {
|
||||
boolean: (val) => typeof val === "boolean",
|
||||
+1
-1
@@ -59,7 +59,7 @@ describe("FormBuilderField", () => {
|
||||
});
|
||||
|
||||
const component = {
|
||||
getFieldInput: ({ label }) => screen.getByRole("textbox", { name: label }) as HTMLInputElement,
|
||||
getFieldInput: ({ label }: { label: string }) => screen.getByRole("textbox", { name: label }) as HTMLInputElement,
|
||||
fillFieldInput: ({ label, value }: { label: string; value: string }) => {
|
||||
fireEvent.change(component.getFieldInput({ label }), { target: { value } });
|
||||
},
|
||||
+5
-5
@@ -11,14 +11,14 @@ import { Label } from "@calcom/ui/components/form";
|
||||
import { Icon } from "@calcom/ui/components/icon";
|
||||
|
||||
import { Components, isValidValueProp } from "./Components";
|
||||
import { fieldTypesConfigMap } from "./fieldTypes";
|
||||
import { fieldsThatSupportLabelAsSafeHtml } from "./fieldsThatSupportLabelAsSafeHtml";
|
||||
import type { fieldsSchema } from "./schema";
|
||||
import { fieldTypesConfigMap } from "@calcom/features/form-builder/fieldTypes";
|
||||
import { fieldsThatSupportLabelAsSafeHtml } from "@calcom/features/form-builder/fieldsThatSupportLabelAsSafeHtml";
|
||||
import type { fieldsSchema } from "@calcom/features/form-builder/schema";
|
||||
import {
|
||||
useShouldBeDisabledDueToPrefill,
|
||||
getFieldNameFromErrorMessage,
|
||||
} from "./useShouldBeDisabledDueToPrefill";
|
||||
import { getTranslatedConfig as getTranslatedVariantsConfig } from "./utils/variantsConfig";
|
||||
} from "@calcom/features/form-builder/useShouldBeDisabledDueToPrefill";
|
||||
import { getTranslatedConfig as getTranslatedVariantsConfig } from "@calcom/features/form-builder/utils/variantsConfig";
|
||||
|
||||
// helper to render markdown label safely
|
||||
const renderLabel = (field: Partial<RhfFormField>) => {
|
||||
@@ -115,7 +115,6 @@ export default function AppCard({
|
||||
) : (
|
||||
<OmniInstallAppButton
|
||||
className="ml-auto flex items-center"
|
||||
appId={app.slug}
|
||||
app={app}
|
||||
returnTo={returnTo}
|
||||
teamId={teamId}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import useApp from "@calcom/features/apps/hooks/useApp";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import classNames from "@calcom/ui/classNames";
|
||||
import { Button } from "@calcom/ui/components/button";
|
||||
import { showToast } from "@calcom/ui/components/toast";
|
||||
|
||||
import useAddAppMutation from "../_utils/useAddAppMutation";
|
||||
import { InstallAppButton } from "../InstallAppButton";
|
||||
import type { AppCardApp } from "../types";
|
||||
import useAddAppMutation from "../_utils/useAddAppMutation";
|
||||
|
||||
type AppData = Pick<AppCardApp, "type" | "variant" | "slug" | "teamsPlanRequired">;
|
||||
|
||||
@@ -14,28 +12,23 @@ type AppData = Pick<AppCardApp, "type" | "variant" | "slug" | "teamsPlanRequired
|
||||
* Use this component to allow installing an app from anywhere on the app.
|
||||
* Use of this component requires you to remove custom InstallAppButtonComponent so that it can manage the redirection itself.
|
||||
*
|
||||
* When `app` prop is provided, it will use that data directly instead of fetching via useApp.
|
||||
* This is useful when the app data is already available (e.g., from the integrations query)
|
||||
* to avoid redundant API calls that can cause URL length issues when batched.
|
||||
* The `app` prop must be provided with the necessary app data.
|
||||
* This avoids redundant API calls and prevents the app-store package from depending on the features package.
|
||||
*/
|
||||
export default function OmniInstallAppButton({
|
||||
appId,
|
||||
app: appProp,
|
||||
app,
|
||||
className,
|
||||
returnTo,
|
||||
teamId,
|
||||
onAppInstallSuccess,
|
||||
}: {
|
||||
appId: string;
|
||||
app?: AppData;
|
||||
app: AppData;
|
||||
className: string;
|
||||
onAppInstallSuccess: () => void;
|
||||
returnTo?: string;
|
||||
teamId?: number;
|
||||
}) {
|
||||
const { t } = useLocale();
|
||||
const { data: fetchedApp } = useApp(appId, { enabled: !appProp });
|
||||
const app = appProp ?? fetchedApp;
|
||||
|
||||
const mutation = useAddAppMutation(null, {
|
||||
returnTo,
|
||||
@@ -49,10 +42,6 @@ export default function OmniInstallAppButton({
|
||||
},
|
||||
});
|
||||
|
||||
if (!app) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<InstallAppButton
|
||||
type={app.type}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import { useSession } from "next-auth/react";
|
||||
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
|
||||
export default function useApp(appId: string, options?: { enabled?: boolean }) {
|
||||
const { status } = useSession();
|
||||
|
||||
return trpc.viewer.apps.appById.useQuery(
|
||||
{ appId },
|
||||
{
|
||||
enabled: status === "authenticated" && (options?.enabled ?? true),
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -2,13 +2,12 @@ import type { ErrorOption, FieldPath } from "react-hook-form";
|
||||
|
||||
import type { RegularBookingCreateResult } from "@calcom/features/bookings/lib/dto/types";
|
||||
import type { Slots } from "@calcom/features/calendars/lib/types";
|
||||
import type { PublicEventType } from "@calcom/features/eventtypes/lib/getPublicEvent";
|
||||
import type { SchedulingType } from "@calcom/prisma/enums";
|
||||
import type { RouterOutputs } from "@calcom/trpc/react";
|
||||
import type { AppsStatus } from "@calcom/types/Calendar";
|
||||
|
||||
import type { BookingCreateBody } from "./lib/bookingCreateBodySchema";
|
||||
|
||||
export type PublicEvent = NonNullable<RouterOutputs["viewer"]["public"]["event"]>;
|
||||
export type PublicEvent = NonNullable<PublicEventType>;
|
||||
|
||||
export type BookerEventQuery = {
|
||||
isSuccess: boolean;
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import type { ConnectedApps } from "@calcom/app-store/_utils/getConnectedApps";
|
||||
import type { EventLocationType } from "@calcom/app-store/locations";
|
||||
import type { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils";
|
||||
import type { TemplateType } from "@calcom/features/calAIPhone/zod-utils";
|
||||
import type { ChildrenEventType } from "@calcom/features/eventtypes/lib/childrenEventType";
|
||||
import type { IntervalLimit } from "@calcom/lib/intervalLimits/intervalLimitSchema";
|
||||
import type { AttributesQueryValue } from "@calcom/lib/raqb/types";
|
||||
import type { EventTypeTranslation } from "@calcom/prisma/client";
|
||||
import { type PeriodType, SchedulingType } from "@calcom/prisma/enums";
|
||||
import type { BookerLayoutSettings } from "@calcom/prisma/zod-utils";
|
||||
import type { customInputSchema } from "@calcom/prisma/zod-utils";
|
||||
import type { eventTypeBookingFields } from "@calcom/prisma/zod-utils";
|
||||
import type { eventTypeColor } from "@calcom/prisma/zod-utils";
|
||||
import type { RouterOutputs, RouterInputs } from "@calcom/trpc/react";
|
||||
import type { MembershipRole, PeriodType, SchedulingType } from "@calcom/prisma/enums";
|
||||
import type {
|
||||
BookerLayoutSettings,
|
||||
CustomInputSchema,
|
||||
customInputSchema,
|
||||
EventTypeLocation,
|
||||
EventTypeMetadata,
|
||||
eventTypeBookingFields,
|
||||
eventTypeColor,
|
||||
} from "@calcom/prisma/zod-utils";
|
||||
import type { RecurringEvent } from "@calcom/types/Calendar";
|
||||
import { MembershipRole } from "@calcom/prisma/enums";
|
||||
import type { UserProfile } from "@calcom/types/UserProfile";
|
||||
|
||||
import type { z } from "zod";
|
||||
import type { EventType } from "./getEventTypeById";
|
||||
export type CustomInputParsed = typeof customInputSchema._output;
|
||||
|
||||
export type AvailabilityOption = {
|
||||
@@ -24,9 +28,9 @@ export type AvailabilityOption = {
|
||||
isDefault: boolean;
|
||||
isManaged?: boolean;
|
||||
};
|
||||
export type EventTypeSetupProps = RouterOutputs["viewer"]["eventTypes"]["get"];
|
||||
export type EventTypeSetup = RouterOutputs["viewer"]["eventTypes"]["get"]["eventType"];
|
||||
export type EventTypeApps = RouterOutputs["viewer"]["apps"]["integrations"];
|
||||
export type EventTypeSetupProps = EventType;
|
||||
export type EventTypeSetup = EventType["eventType"];
|
||||
export type EventTypeApps = ConnectedApps;
|
||||
export type HostLocation = {
|
||||
id?: string;
|
||||
userId: number;
|
||||
@@ -223,7 +227,223 @@ export type EventTypeHosts = {
|
||||
weight: number | null;
|
||||
groupId: string | null;
|
||||
}[];
|
||||
export type EventTypeUpdateInput = RouterInputs["viewer"]["eventTypesHeavy"]["update"];
|
||||
|
||||
// ============================================================================
|
||||
// EVENT TYPE UPDATE INPUT TYPES
|
||||
// ============================================================================
|
||||
// These types define the shape of event type update operations and should be
|
||||
// consumed by both the features package and tRPC routers.
|
||||
// ============================================================================
|
||||
|
||||
export type HashedLinkInput = {
|
||||
link: string;
|
||||
expiresAt?: Date | null;
|
||||
maxUsageCount?: number | null;
|
||||
usageCount?: number | null;
|
||||
};
|
||||
|
||||
export type AiPhoneCallConfig = {
|
||||
generalPrompt: string;
|
||||
enabled: boolean;
|
||||
beginMessage: string | null;
|
||||
yourPhoneNumber: string;
|
||||
numberToCall: string;
|
||||
guestName?: string | null;
|
||||
guestEmail?: string | null;
|
||||
guestCompany?: string | null;
|
||||
templateType: TemplateType;
|
||||
};
|
||||
|
||||
export type HostLocationInput = {
|
||||
id?: string;
|
||||
userId: number;
|
||||
eventTypeId: number;
|
||||
type: string;
|
||||
credentialId?: number | null;
|
||||
link?: string | null;
|
||||
address?: string | null;
|
||||
phoneNumber?: string | null;
|
||||
};
|
||||
|
||||
export type HostInput = {
|
||||
userId: number;
|
||||
profileId?: number | null;
|
||||
isFixed?: boolean;
|
||||
priority?: number | null;
|
||||
weight?: number | null;
|
||||
scheduleId?: number | null;
|
||||
groupId?: string | null;
|
||||
location?: HostLocationInput | null;
|
||||
};
|
||||
|
||||
export type HostGroupInput = {
|
||||
id: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type ChildInput = {
|
||||
owner: {
|
||||
id: number;
|
||||
name: string;
|
||||
email: string;
|
||||
eventTypeSlugs: string[];
|
||||
};
|
||||
hidden: boolean;
|
||||
};
|
||||
|
||||
export type DestinationCalendarInput = {
|
||||
integration: string;
|
||||
externalId: string;
|
||||
} | null;
|
||||
|
||||
export type RecurringEventInput = {
|
||||
dtstart?: Date;
|
||||
interval: number;
|
||||
count: number;
|
||||
freq: number;
|
||||
until?: Date;
|
||||
tzid?: string;
|
||||
} | null;
|
||||
|
||||
export type EventTypeColorInput = {
|
||||
lightEventTypeColor: string;
|
||||
darkEventTypeColor: string;
|
||||
} | null;
|
||||
|
||||
/**
|
||||
* Booking field type - minimal type definition for fields that need to be accessed.
|
||||
* Only includes properties that are actually read in server code.
|
||||
* Does NOT use an index signature to maintain compatibility with API v2 DTO classes.
|
||||
*/
|
||||
export type BookingFieldInput = {
|
||||
name: string;
|
||||
hidden?: boolean;
|
||||
required?: boolean;
|
||||
type?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* RR Segment query value - using index signature for complex RAQB structure.
|
||||
* The values need to be indexable (string keys) for downstream usage.
|
||||
*/
|
||||
export type RRSegmentQueryValueInput = {
|
||||
[key: string]: unknown;
|
||||
} | null;
|
||||
|
||||
/**
|
||||
* Explicit type definition for event type update input.
|
||||
*
|
||||
* This type is defined explicitly rather than using z.infer<> on a complex
|
||||
* schema chain to significantly reduce TypeScript type-checking time.
|
||||
* The schema still validates all fields at runtime.
|
||||
*
|
||||
* All fields are optional (from .partial()) except `id` which is required.
|
||||
*/
|
||||
export type EventTypeUpdateInput = {
|
||||
// Required field
|
||||
id: number;
|
||||
|
||||
// Fields from EventTypeSchema (all optional due to .partial())
|
||||
periodType?: PeriodType;
|
||||
schedulingType?: SchedulingType | null;
|
||||
title?: string;
|
||||
slug?: string;
|
||||
description?: string | null;
|
||||
interfaceLanguage?: string | null;
|
||||
position?: number;
|
||||
locations?: EventTypeLocation[] | null;
|
||||
length?: number;
|
||||
offsetStart?: number;
|
||||
hidden?: boolean;
|
||||
userId?: number | null;
|
||||
profileId?: number | null;
|
||||
teamId?: number | null;
|
||||
useEventLevelSelectedCalendars?: boolean;
|
||||
eventName?: string | null;
|
||||
parentId?: number | null;
|
||||
bookingFields?: BookingFieldInput[] | null;
|
||||
timeZone?: string | null;
|
||||
periodStartDate?: Date | null;
|
||||
periodEndDate?: Date | null;
|
||||
periodDays?: number | null;
|
||||
periodCountCalendarDays?: boolean | null;
|
||||
lockTimeZoneToggleOnBookingPage?: boolean;
|
||||
lockedTimeZone?: string | null;
|
||||
requiresConfirmation?: boolean;
|
||||
requiresConfirmationWillBlockSlot?: boolean;
|
||||
requiresConfirmationForFreeEmail?: boolean;
|
||||
requiresBookerEmailVerification?: boolean;
|
||||
canSendCalVideoTranscriptionEmails?: boolean;
|
||||
autoTranslateDescriptionEnabled?: boolean;
|
||||
autoTranslateInstantMeetingTitleEnabled?: boolean;
|
||||
recurringEvent?: RecurringEventInput;
|
||||
disableGuests?: boolean;
|
||||
hideCalendarNotes?: boolean;
|
||||
hideCalendarEventDetails?: boolean;
|
||||
minimumBookingNotice?: number;
|
||||
beforeEventBuffer?: number;
|
||||
afterEventBuffer?: number;
|
||||
seatsPerTimeSlot?: number | null;
|
||||
onlyShowFirstAvailableSlot?: boolean;
|
||||
showOptimizedSlots?: boolean | null;
|
||||
disableCancelling?: boolean | null;
|
||||
disableRescheduling?: boolean | null;
|
||||
minimumRescheduleNotice?: number | null;
|
||||
seatsShowAttendees?: boolean | null;
|
||||
seatsShowAvailabilityCount?: boolean | null;
|
||||
scheduleId?: number | null;
|
||||
allowReschedulingCancelledBookings?: boolean | null;
|
||||
price?: number;
|
||||
currency?: string;
|
||||
slotInterval?: number | null;
|
||||
metadata?: EventTypeMetadata;
|
||||
successRedirectUrl?: string | null;
|
||||
forwardParamsSuccessRedirect?: boolean | null;
|
||||
redirectUrlOnNoRoutingFormResponse?: string | null;
|
||||
bookingLimits?: IntervalLimit | null;
|
||||
durationLimits?: IntervalLimit | null;
|
||||
isInstantEvent?: boolean;
|
||||
instantMeetingExpiryTimeOffsetInSeconds?: number;
|
||||
instantMeetingScheduleId?: number | null;
|
||||
instantMeetingParameters?: string[];
|
||||
assignAllTeamMembers?: boolean;
|
||||
assignRRMembersUsingSegment?: boolean;
|
||||
rrSegmentQueryValue?: RRSegmentQueryValueInput;
|
||||
useEventTypeDestinationCalendarEmail?: boolean;
|
||||
isRRWeightsEnabled?: boolean;
|
||||
maxLeadThreshold?: number | null;
|
||||
includeNoShowInRRCalculation?: boolean;
|
||||
allowReschedulingPastBookings?: boolean;
|
||||
hideOrganizerEmail?: boolean;
|
||||
maxActiveBookingsPerBooker?: number | null;
|
||||
maxActiveBookingPerBookerOfferReschedule?: boolean;
|
||||
customReplyToEmail?: string | null;
|
||||
eventTypeColor?: EventTypeColorInput;
|
||||
rescheduleWithSameRoundRobinHost?: boolean;
|
||||
secondaryEmailId?: number | null;
|
||||
useBookerTimezone?: boolean;
|
||||
restrictionScheduleId?: number | null;
|
||||
bookingRequiresAuthentication?: boolean;
|
||||
rrHostSubsetEnabled?: boolean;
|
||||
createdAt?: Date | null;
|
||||
updatedAt?: Date | null;
|
||||
|
||||
// Extended fields (all optional due to .partial())
|
||||
aiPhoneCallConfig?: AiPhoneCallConfig;
|
||||
calVideoSettings?: CalVideoSettings;
|
||||
calAiPhoneScript?: string;
|
||||
customInputs?: CustomInputSchema[];
|
||||
destinationCalendar?: DestinationCalendarInput;
|
||||
users?: number[];
|
||||
children?: ChildInput[];
|
||||
hosts?: HostInput[];
|
||||
schedule?: number | null;
|
||||
instantMeetingSchedule?: number | null;
|
||||
multiplePrivateLinks?: (string | HashedLinkInput)[];
|
||||
hostGroups?: HostGroupInput[];
|
||||
enablePerHostLocations?: boolean;
|
||||
};
|
||||
|
||||
export type TabMap = {
|
||||
advanced: React.ReactNode;
|
||||
ai?: React.ReactNode;
|
||||
@@ -286,13 +506,13 @@ export interface EventTypePlatformWrapperRef {
|
||||
handleFormSubmit: (callbacks?: { onSuccess?: () => void; onError?: (error: Error) => void }) => void;
|
||||
}
|
||||
|
||||
export interface CalVideoSettings {
|
||||
disableRecordingForOrganizer?: boolean;
|
||||
disableRecordingForGuests?: boolean;
|
||||
enableAutomaticTranscription?: boolean;
|
||||
enableAutomaticRecordingForOrganizer?: boolean;
|
||||
disableTranscriptionForGuests?: boolean;
|
||||
disableTranscriptionForOrganizer?: boolean;
|
||||
redirectUrlOnExit?: string;
|
||||
requireEmailForGuests?: boolean;
|
||||
}
|
||||
export type CalVideoSettings = {
|
||||
disableRecordingForGuests?: boolean | null;
|
||||
disableRecordingForOrganizer?: boolean | null;
|
||||
enableAutomaticTranscription?: boolean | null;
|
||||
enableAutomaticRecordingForOrganizer?: boolean | null;
|
||||
disableTranscriptionForGuests?: boolean | null;
|
||||
disableTranscriptionForOrganizer?: boolean | null;
|
||||
redirectUrlOnExit?: string | null;
|
||||
requireEmailForGuests?: boolean | null;
|
||||
} | null;
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
// TODO: FormBuilder makes more sense in @calcom/ui but it has an additional thing that other components don't have
|
||||
// It has zod schema associated with it and I currently can't import zod in there.
|
||||
// Move it later there maybe? @sean
|
||||
export { FormBuilderField } from "./FormBuilderField";
|
||||
@@ -1,20 +0,0 @@
|
||||
export function PermissionProvider({ children }: { children: React.ReactNode }) {
|
||||
// const { data: permissions, isLoading } = trpc.viewer.pbac.getUserPermissions.useQuery(undefined, {
|
||||
// // Since permissions don't change often, we can cache them for a while
|
||||
// staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
// });
|
||||
|
||||
// const setTeamPermissions = usePermissionStore((state) => state.setTeamPermissions);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (permissions) {
|
||||
// setTeamPermissions(permissions);
|
||||
// }
|
||||
// }, [permissions, setTeamPermissions]);
|
||||
|
||||
// if (true) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
return <>{children}</>;
|
||||
}
|
||||
@@ -18,7 +18,6 @@ import dayjs from "@calcom/dayjs";
|
||||
import { defaultDayRange as DEFAULT_DAY_RANGE } from "@calcom/lib/availability";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { weekdayNames } from "@calcom/lib/weekday";
|
||||
import useMeQuery from "@calcom/trpc/react/hooks/useMeQuery";
|
||||
import type { TimeRange } from "@calcom/types/schedule";
|
||||
import cn from "@calcom/ui/classNames";
|
||||
import { Button } from "@calcom/ui/components/button";
|
||||
|
||||
@@ -1,253 +1,27 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import type { TemplateType } from "@calcom/features/calAIPhone/zod-utils";
|
||||
import { templateTypeEnum } from "@calcom/features/calAIPhone/zod-utils";
|
||||
import { MAX_SEATS_PER_TIME_SLOT } from "@calcom/lib/constants";
|
||||
import type { PeriodType, SchedulingType } from "@calcom/prisma/enums";
|
||||
import type {
|
||||
CustomInputSchema,
|
||||
EventTypeMetadata,
|
||||
IntervalLimit,
|
||||
EventTypeLocation,
|
||||
} from "@calcom/prisma/zod-utils";
|
||||
AiPhoneCallConfig,
|
||||
CalVideoSettings,
|
||||
ChildInput,
|
||||
DestinationCalendarInput,
|
||||
EventTypeUpdateInput,
|
||||
HashedLinkInput,
|
||||
HostGroupInput,
|
||||
HostInput,
|
||||
} from "@calcom/features/eventtypes/lib/types";
|
||||
import { MAX_SEATS_PER_TIME_SLOT } from "@calcom/lib/constants";
|
||||
import {
|
||||
customInputSchema,
|
||||
EventTypeMetaDataSchema,
|
||||
rrSegmentQueryValueSchema,
|
||||
eventTypeLocations,
|
||||
recurringEventType,
|
||||
intervalLimitsType,
|
||||
eventTypeBookingFields,
|
||||
eventTypeColor,
|
||||
eventTypeLocations,
|
||||
intervalLimitsType,
|
||||
recurringEventType,
|
||||
rrSegmentQueryValueSchema,
|
||||
} from "@calcom/prisma/zod-utils";
|
||||
|
||||
// ============================================================================
|
||||
// EXPLICIT TYPE DEFINITIONS
|
||||
// ============================================================================
|
||||
// These explicit types prevent TypeScript from having to infer complex types
|
||||
// through chains of .extend(), .partial(), .merge() etc. This significantly
|
||||
// reduces type-checking time by giving TypeScript the answer directly.
|
||||
// ============================================================================
|
||||
|
||||
type HashedLinkInput = {
|
||||
link: string;
|
||||
expiresAt?: Date | null;
|
||||
maxUsageCount?: number | null;
|
||||
usageCount?: number | null;
|
||||
};
|
||||
|
||||
type AiPhoneCallConfig = {
|
||||
generalPrompt: string;
|
||||
enabled: boolean;
|
||||
beginMessage: string | null;
|
||||
yourPhoneNumber: string;
|
||||
numberToCall: string;
|
||||
guestName?: string | null;
|
||||
guestEmail?: string | null;
|
||||
guestCompany?: string | null;
|
||||
templateType: TemplateType;
|
||||
};
|
||||
|
||||
type CalVideoSettings = {
|
||||
disableRecordingForGuests?: boolean | null;
|
||||
disableRecordingForOrganizer?: boolean | null;
|
||||
enableAutomaticTranscription?: boolean | null;
|
||||
enableAutomaticRecordingForOrganizer?: boolean | null;
|
||||
disableTranscriptionForGuests?: boolean | null;
|
||||
disableTranscriptionForOrganizer?: boolean | null;
|
||||
redirectUrlOnExit?: string | null;
|
||||
requireEmailForGuests?: boolean | null;
|
||||
} | null;
|
||||
|
||||
type HostLocationInput = {
|
||||
id?: string;
|
||||
userId: number;
|
||||
eventTypeId: number;
|
||||
type: string;
|
||||
credentialId?: number | null;
|
||||
link?: string | null;
|
||||
address?: string | null;
|
||||
phoneNumber?: string | null;
|
||||
};
|
||||
|
||||
type HostInput = {
|
||||
userId: number;
|
||||
profileId?: number | null;
|
||||
isFixed?: boolean;
|
||||
priority?: number | null;
|
||||
weight?: number | null;
|
||||
scheduleId?: number | null;
|
||||
groupId?: string | null;
|
||||
location?: HostLocationInput | null;
|
||||
};
|
||||
|
||||
type HostGroupInput = {
|
||||
id: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
type ChildInput = {
|
||||
owner: {
|
||||
id: number;
|
||||
name: string;
|
||||
email: string;
|
||||
eventTypeSlugs: string[];
|
||||
};
|
||||
hidden: boolean;
|
||||
};
|
||||
|
||||
type DestinationCalendarInput = {
|
||||
integration: string;
|
||||
externalId: string;
|
||||
} | null;
|
||||
|
||||
type RecurringEventInput = {
|
||||
dtstart?: Date;
|
||||
interval: number;
|
||||
count: number;
|
||||
freq: number;
|
||||
until?: Date;
|
||||
tzid?: string;
|
||||
} | null;
|
||||
|
||||
type EventTypeColorInput = {
|
||||
lightEventTypeColor: string;
|
||||
darkEventTypeColor: string;
|
||||
} | null;
|
||||
|
||||
/**
|
||||
* Booking field type - minimal type definition for fields that need to be accessed.
|
||||
* Only includes properties that are actually read in server code.
|
||||
* Does NOT use an index signature to maintain compatibility with API v2 DTO classes.
|
||||
*/
|
||||
type BookingFieldInput = {
|
||||
name: string;
|
||||
hidden?: boolean;
|
||||
required?: boolean;
|
||||
type?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* RR Segment query value - using index signature for complex RAQB structure.
|
||||
* The values need to be indexable (string keys) for downstream usage.
|
||||
*/
|
||||
type RRSegmentQueryValueInput = {
|
||||
[key: string]: unknown;
|
||||
} | null;
|
||||
|
||||
/**
|
||||
* Explicit type definition for event type update input.
|
||||
*
|
||||
* This type is defined explicitly rather than using z.infer<> on a complex
|
||||
* schema chain to significantly reduce TypeScript type-checking time.
|
||||
* The schema still validates all fields at runtime.
|
||||
*
|
||||
* All fields are optional (from .partial()) except `id` which is required.
|
||||
*/
|
||||
export type TUpdateInputSchema = {
|
||||
// Required field
|
||||
id: number;
|
||||
|
||||
// Fields from EventTypeSchema (all optional due to .partial())
|
||||
periodType?: PeriodType;
|
||||
schedulingType?: SchedulingType | null;
|
||||
title?: string;
|
||||
slug?: string;
|
||||
description?: string | null;
|
||||
interfaceLanguage?: string | null;
|
||||
position?: number;
|
||||
locations?: EventTypeLocation[] | null;
|
||||
length?: number;
|
||||
offsetStart?: number;
|
||||
hidden?: boolean;
|
||||
userId?: number | null;
|
||||
profileId?: number | null;
|
||||
teamId?: number | null;
|
||||
useEventLevelSelectedCalendars?: boolean;
|
||||
eventName?: string | null;
|
||||
parentId?: number | null;
|
||||
bookingFields?: BookingFieldInput[] | null;
|
||||
timeZone?: string | null;
|
||||
periodStartDate?: Date | null;
|
||||
periodEndDate?: Date | null;
|
||||
periodDays?: number | null;
|
||||
periodCountCalendarDays?: boolean | null;
|
||||
lockTimeZoneToggleOnBookingPage?: boolean;
|
||||
lockedTimeZone?: string | null;
|
||||
requiresConfirmation?: boolean;
|
||||
requiresConfirmationWillBlockSlot?: boolean;
|
||||
requiresConfirmationForFreeEmail?: boolean;
|
||||
requiresBookerEmailVerification?: boolean;
|
||||
canSendCalVideoTranscriptionEmails?: boolean;
|
||||
autoTranslateDescriptionEnabled?: boolean;
|
||||
autoTranslateInstantMeetingTitleEnabled?: boolean;
|
||||
recurringEvent?: RecurringEventInput;
|
||||
disableGuests?: boolean;
|
||||
hideCalendarNotes?: boolean;
|
||||
hideCalendarEventDetails?: boolean;
|
||||
minimumBookingNotice?: number;
|
||||
beforeEventBuffer?: number;
|
||||
afterEventBuffer?: number;
|
||||
seatsPerTimeSlot?: number | null;
|
||||
onlyShowFirstAvailableSlot?: boolean;
|
||||
showOptimizedSlots?: boolean | null;
|
||||
disableCancelling?: boolean | null;
|
||||
disableRescheduling?: boolean | null;
|
||||
minimumRescheduleNotice?: number | null;
|
||||
seatsShowAttendees?: boolean | null;
|
||||
seatsShowAvailabilityCount?: boolean | null;
|
||||
scheduleId?: number | null;
|
||||
allowReschedulingCancelledBookings?: boolean | null;
|
||||
price?: number;
|
||||
currency?: string;
|
||||
slotInterval?: number | null;
|
||||
metadata?: EventTypeMetadata;
|
||||
successRedirectUrl?: string | null;
|
||||
forwardParamsSuccessRedirect?: boolean | null;
|
||||
redirectUrlOnNoRoutingFormResponse?: string | null;
|
||||
bookingLimits?: IntervalLimit | null;
|
||||
durationLimits?: IntervalLimit | null;
|
||||
isInstantEvent?: boolean;
|
||||
instantMeetingExpiryTimeOffsetInSeconds?: number;
|
||||
instantMeetingScheduleId?: number | null;
|
||||
instantMeetingParameters?: string[];
|
||||
assignAllTeamMembers?: boolean;
|
||||
assignRRMembersUsingSegment?: boolean;
|
||||
rrSegmentQueryValue?: RRSegmentQueryValueInput;
|
||||
useEventTypeDestinationCalendarEmail?: boolean;
|
||||
isRRWeightsEnabled?: boolean;
|
||||
maxLeadThreshold?: number | null;
|
||||
includeNoShowInRRCalculation?: boolean;
|
||||
allowReschedulingPastBookings?: boolean;
|
||||
hideOrganizerEmail?: boolean;
|
||||
maxActiveBookingsPerBooker?: number | null;
|
||||
maxActiveBookingPerBookerOfferReschedule?: boolean;
|
||||
customReplyToEmail?: string | null;
|
||||
eventTypeColor?: EventTypeColorInput;
|
||||
rescheduleWithSameRoundRobinHost?: boolean;
|
||||
secondaryEmailId?: number | null;
|
||||
useBookerTimezone?: boolean;
|
||||
restrictionScheduleId?: number | null;
|
||||
bookingRequiresAuthentication?: boolean;
|
||||
rrHostSubsetEnabled?: boolean;
|
||||
createdAt?: Date | null;
|
||||
updatedAt?: Date | null;
|
||||
|
||||
// Extended fields (all optional due to .partial())
|
||||
aiPhoneCallConfig?: AiPhoneCallConfig;
|
||||
calVideoSettings?: CalVideoSettings;
|
||||
calAiPhoneScript?: string;
|
||||
customInputs?: CustomInputSchema[];
|
||||
destinationCalendar?: DestinationCalendarInput;
|
||||
users?: number[];
|
||||
children?: ChildInput[];
|
||||
hosts?: HostInput[];
|
||||
schedule?: number | null;
|
||||
instantMeetingSchedule?: number | null;
|
||||
multiplePrivateLinks?: (string | HashedLinkInput)[];
|
||||
hostGroups?: HostGroupInput[];
|
||||
enablePerHostLocations?: boolean;
|
||||
};
|
||||
import { z } from "zod";
|
||||
export type TUpdateInputSchema = EventTypeUpdateInput;
|
||||
|
||||
// ============================================================================
|
||||
// ZOD SCHEMAS
|
||||
|
||||
Reference in New Issue
Block a user