diff --git a/apps/web/components/setup/EnterpriseLicense.tsx b/apps/web/components/setup/EnterpriseLicense.tsx
index 5be4a528b1..d30044e920 100644
--- a/apps/web/components/setup/EnterpriseLicense.tsx
+++ b/apps/web/components/setup/EnterpriseLicense.tsx
@@ -1,4 +1,5 @@
import { zodResolver } from "@hookform/resolvers/zod";
+// eslint-disable-next-line no-restricted-imports
import { noop } from "lodash";
import { useCallback, useState } from "react";
import { Controller, FormProvider, useForm, useFormState } from "react-hook-form";
diff --git a/apps/web/components/ui/UsernameAvailability/PremiumTextfield.tsx b/apps/web/components/ui/UsernameAvailability/PremiumTextfield.tsx
index f58fd01b50..418133f9d9 100644
--- a/apps/web/components/ui/UsernameAvailability/PremiumTextfield.tsx
+++ b/apps/web/components/ui/UsernameAvailability/PremiumTextfield.tsx
@@ -1,4 +1,5 @@
import classNames from "classnames";
+// eslint-disable-next-line no-restricted-imports
import { debounce, noop } from "lodash";
import { useSession } from "next-auth/react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
diff --git a/apps/web/components/ui/UsernameAvailability/UsernameTextfield.tsx b/apps/web/components/ui/UsernameAvailability/UsernameTextfield.tsx
index 316d48a690..e2c046f7aa 100644
--- a/apps/web/components/ui/UsernameAvailability/UsernameTextfield.tsx
+++ b/apps/web/components/ui/UsernameAvailability/UsernameTextfield.tsx
@@ -1,4 +1,5 @@
import classNames from "classnames";
+// eslint-disable-next-line no-restricted-imports
import { debounce, noop } from "lodash";
import { useSession } from "next-auth/react";
import type { RefCallback } from "react";
diff --git a/apps/web/pages/auth/forgot-password/index.tsx b/apps/web/pages/auth/forgot-password/index.tsx
index 2a6717087b..750f86b996 100644
--- a/apps/web/pages/auth/forgot-password/index.tsx
+++ b/apps/web/pages/auth/forgot-password/index.tsx
@@ -1,3 +1,4 @@
+// eslint-disable-next-line no-restricted-imports
import { debounce } from "lodash";
import type { GetServerSidePropsContext } from "next";
import { getCsrfToken } from "next-auth/react";
diff --git a/apps/web/playwright/lib/testUtils.ts b/apps/web/playwright/lib/testUtils.ts
index 01af676146..3f317ebc95 100644
--- a/apps/web/playwright/lib/testUtils.ts
+++ b/apps/web/playwright/lib/testUtils.ts
@@ -2,6 +2,7 @@ import type { Page } from "@playwright/test";
import { expect } from "@playwright/test";
import type { IncomingMessage, ServerResponse } from "http";
import { createServer } from "http";
+// eslint-disable-next-line no-restricted-imports
import { noop } from "lodash";
import { test } from "./fixtures";
diff --git a/apps/web/public/static/locales/en/common.json b/apps/web/public/static/locales/en/common.json
index c77ca78645..d172f4df25 100644
--- a/apps/web/public/static/locales/en/common.json
+++ b/apps/web/public/static/locales/en/common.json
@@ -929,7 +929,7 @@
"verify_wallet": "Verify Wallet",
"create_events_on": "Create events on",
"enterprise_license": "This is an enterprise feature",
- "enterprise_license_description": "To enable this feature, have an administrator go to {{setupUrl}} to enter a license key. If a license key is already in place, please contact {{supportMail}} for help.",
+ "enterprise_license_description": "To enable this feature, have an administrator go to <2>/auth/setup2> to enter a license key. If a license key is already in place, please contact <5>{{SUPPORT_MAIL_ADDRESS}}5> for help.",
"enterprise_license_development": "You can test this feature on development mode. For production usage please have an administrator go to <2>/auth/setup2> to enter a license key.",
"missing_license": "Missing License",
"signup_requires": "Commercial license required",
diff --git a/package.json b/package.json
index 774d1b8836..7c993a5e7a 100644
--- a/package.json
+++ b/package.json
@@ -77,7 +77,6 @@
"@playwright/test": "^1.31.2",
"@snaplet/copycat": "^0.3.0",
"@testing-library/jest-dom": "^5.16.5",
- "@types/dompurify": "^2.4.0",
"c8": "^7.13.0",
"dotenv-checker": "^1.1.5",
"husky": "^8.0.0",
diff --git a/packages/app-store-cli/src/build.ts b/packages/app-store-cli/src/build.ts
index df2f19906a..6469db035c 100644
--- a/packages/app-store-cli/src/build.ts
+++ b/packages/app-store-cli/src/build.ts
@@ -1,5 +1,6 @@
import chokidar from "chokidar";
import fs from "fs";
+// eslint-disable-next-line no-restricted-imports
import { debounce } from "lodash";
import path from "path";
import prettier from "prettier";
@@ -7,7 +8,7 @@ import prettier from "prettier";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
import prettierConfig from "@calcom/config/prettier-preset";
-import { AppMeta } from "@calcom/types/App";
+import type { AppMeta } from "@calcom/types/App";
import { APP_STORE_PATH } from "./constants";
import { getAppName } from "./utils/getAppName";
diff --git a/packages/app-store/routing-forms/components/react-awesome-query-builder/widgets.tsx b/packages/app-store/routing-forms/components/react-awesome-query-builder/widgets.tsx
index 66d230a7a8..4e018496f4 100644
--- a/packages/app-store/routing-forms/components/react-awesome-query-builder/widgets.tsx
+++ b/packages/app-store/routing-forms/components/react-awesome-query-builder/widgets.tsx
@@ -1,3 +1,4 @@
+import dynamic from "next/dynamic";
import type { ChangeEvent } from "react";
import type {
ButtonGroupProps,
@@ -7,9 +8,13 @@ import type {
ProviderProps,
} from "react-awesome-query-builder";
-import { Button as CalButton, SelectWithValidation as Select, TextField, TextArea } from "@calcom/ui";
+import { Button as CalButton, TextField, TextArea } from "@calcom/ui";
import { Trash, Plus } from "@calcom/ui/components/icon";
+const Select = dynamic(
+ async () => (await import("@calcom/ui")).SelectWithValidation
+) as unknown as typeof import("@calcom/ui").SelectWithValidation;
+
export type CommonProps<
TVal extends
| string
diff --git a/packages/config/eslint-preset.js b/packages/config/eslint-preset.js
index 0d364f0b73..e608c4f4df 100644
--- a/packages/config/eslint-preset.js
+++ b/packages/config/eslint-preset.js
@@ -36,6 +36,12 @@ module.exports = {
},
],
"unused-imports/no-unused-imports": "error",
+ "no-restricted-imports": [
+ "error",
+ {
+ patterns: ["lodash"],
+ },
+ ],
},
overrides: [
{
diff --git a/packages/core/CalendarManager.ts b/packages/core/CalendarManager.ts
index f1786a97b2..b256eb1cfc 100644
--- a/packages/core/CalendarManager.ts
+++ b/packages/core/CalendarManager.ts
@@ -1,4 +1,5 @@
import type { SelectedCalendar } from "@prisma/client";
+// eslint-disable-next-line no-restricted-imports
import { sortBy } from "lodash";
import { getCalendar } from "@calcom/app-store/_utils/getCalendar";
diff --git a/packages/core/EventManager.ts b/packages/core/EventManager.ts
index 0f0b465977..72aa75eb68 100644
--- a/packages/core/EventManager.ts
+++ b/packages/core/EventManager.ts
@@ -1,4 +1,5 @@
import type { DestinationCalendar, Booking } from "@prisma/client";
+// eslint-disable-next-line no-restricted-imports
import { cloneDeep, merge } from "lodash";
import { v5 as uuidv5 } from "uuid";
import type { z } from "zod";
diff --git a/packages/emails/email-manager.ts b/packages/emails/email-manager.ts
index 91e381b2b0..1608809787 100644
--- a/packages/emails/email-manager.ts
+++ b/packages/emails/email-manager.ts
@@ -1,3 +1,4 @@
+// eslint-disable-next-line no-restricted-imports
import { cloneDeep } from "lodash";
import type { TFunction } from "next-i18next";
diff --git a/packages/emails/templates/attendee-scheduled-email.ts b/packages/emails/templates/attendee-scheduled-email.ts
index b483677267..0d22891118 100644
--- a/packages/emails/templates/attendee-scheduled-email.ts
+++ b/packages/emails/templates/attendee-scheduled-email.ts
@@ -1,5 +1,6 @@
import type { DateArray, ParticipationStatus, ParticipationRole } from "ics";
import { createEvent } from "ics";
+// eslint-disable-next-line no-restricted-imports
import { cloneDeep } from "lodash";
import type { TFunction } from "next-i18next";
import { RRule } from "rrule";
diff --git a/packages/emails/templates/organizer-scheduled-email.ts b/packages/emails/templates/organizer-scheduled-email.ts
index df2c6dd476..9592c63869 100644
--- a/packages/emails/templates/organizer-scheduled-email.ts
+++ b/packages/emails/templates/organizer-scheduled-email.ts
@@ -1,5 +1,6 @@
import type { DateArray } from "ics";
import { createEvent } from "ics";
+// eslint-disable-next-line no-restricted-imports
import { cloneDeep } from "lodash";
import type { TFunction } from "next-i18next";
import { RRule } from "rrule";
diff --git a/packages/features/apps/AdminAppsList.tsx b/packages/features/apps/AdminAppsList.tsx
index 51f7d30c55..5991687276 100644
--- a/packages/features/apps/AdminAppsList.tsx
+++ b/packages/features/apps/AdminAppsList.tsx
@@ -1,4 +1,5 @@
import { zodResolver } from "@hookform/resolvers/zod";
+// eslint-disable-next-line no-restricted-imports
import { noop } from "lodash";
import { useSearchParams } from "next/navigation";
import type { FC } from "react";
diff --git a/packages/features/bookings/lib/handleNewBooking.ts b/packages/features/bookings/lib/handleNewBooking.ts
index 31668800f4..eb8ed25479 100644
--- a/packages/features/bookings/lib/handleNewBooking.ts
+++ b/packages/features/bookings/lib/handleNewBooking.ts
@@ -2,6 +2,7 @@ import type { App, Attendee, Credential, EventTypeCustomInput } from "@prisma/cl
import { Prisma } from "@prisma/client";
import async from "async";
import { isValidPhoneNumber } from "libphonenumber-js";
+// eslint-disable-next-line no-restricted-imports
import { cloneDeep } from "lodash";
import type { NextApiRequest } from "next";
import short, { uuid } from "short-uuid";
diff --git a/packages/features/ee/common/components/LicenseRequired.tsx b/packages/features/ee/common/components/LicenseRequired.tsx
index 47a960ae47..e34134cc97 100644
--- a/packages/features/ee/common/components/LicenseRequired.tsx
+++ b/packages/features/ee/common/components/LicenseRequired.tsx
@@ -1,10 +1,9 @@
-import DOMPurify from "dompurify";
import { useSession } from "next-auth/react";
import { Trans } from "next-i18next";
import type { AriaRole, ComponentType } from "react";
import React, { Fragment, useEffect } from "react";
-import { APP_NAME, CONSOLE_URL, SUPPORT_MAIL_ADDRESS, WEBAPP_URL } from "@calcom/lib/constants";
+import { SUPPORT_MAIL_ADDRESS, WEBAPP_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { EmptyScreen, TopBanner } from "@calcom/ui";
import { AlertTriangle } from "@calcom/ui/components/icon";
@@ -62,20 +61,17 @@ const LicenseRequired = ({ children, as = "", ...rest }: LicenseRequiredProps) =
Icon={AlertTriangle}
headline={t("enterprise_license")}
description={
-
- ${APP_NAME}
- `,
- setupUrl: `
/auth/setup`,
- supportMail: `
- ${SUPPORT_MAIL_ADDRESS}`,
- })
- ),
- }}
- />
+
+ To enable this feature, have an administrator go to{" "}
+
+ /auth/setup
+
+ to enter a license key. If a license key is already in place, please contact{" "}
+
+ {{ SUPPORT_MAIL_ADDRESS }}
+
+ for help.
+
}
/>
)}
diff --git a/packages/features/ee/managed-event-types/hooks/useLockedFieldsManager.tsx b/packages/features/ee/managed-event-types/hooks/useLockedFieldsManager.tsx
index b719d3e2ac..55f3c9922f 100644
--- a/packages/features/ee/managed-event-types/hooks/useLockedFieldsManager.tsx
+++ b/packages/features/ee/managed-event-types/hooks/useLockedFieldsManager.tsx
@@ -1,3 +1,4 @@
+// eslint-disable-next-line no-restricted-imports
import { get } from "lodash";
import React from "react";
import type z from "zod";
diff --git a/packages/features/ee/support/lib/intercom/useIntercom.ts b/packages/features/ee/support/lib/intercom/useIntercom.ts
index 76e7a68e1d..6675a570f7 100644
--- a/packages/features/ee/support/lib/intercom/useIntercom.ts
+++ b/packages/features/ee/support/lib/intercom/useIntercom.ts
@@ -1,3 +1,4 @@
+// eslint-disable-next-line no-restricted-imports
import { noop } from "lodash";
import { useIntercom as useIntercomLib } from "react-use-intercom";
import { z } from "zod";
diff --git a/packages/features/ee/users/components/UserForm.tsx b/packages/features/ee/users/components/UserForm.tsx
index 898641ab0e..130682e2bc 100644
--- a/packages/features/ee/users/components/UserForm.tsx
+++ b/packages/features/ee/users/components/UserForm.tsx
@@ -1,3 +1,4 @@
+// eslint-disable-next-line no-restricted-imports
import { noop } from "lodash";
import { Controller, useForm } from "react-hook-form";
diff --git a/packages/features/package.json b/packages/features/package.json
index 5763dbdffb..4f27f21a0f 100644
--- a/packages/features/package.json
+++ b/packages/features/package.json
@@ -13,7 +13,6 @@
"@calcom/ui": "*",
"@lexical/react": "^0.9.0",
"@tanstack/react-table": "^8.9.3",
- "dompurify": "^2.4.1",
"framer-motion": "^10.12.8",
"lexical": "^0.9.0",
"react-select": "^5.7.0",
diff --git a/packages/prisma/zod-utils.ts b/packages/prisma/zod-utils.ts
index c14619f141..9216701c78 100644
--- a/packages/prisma/zod-utils.ts
+++ b/packages/prisma/zod-utils.ts
@@ -1,6 +1,5 @@
import type { Prisma } from "@prisma/client";
import type { UnitTypeLongPlural } from "dayjs";
-import { pick } from "lodash";
import z, { ZodNullable, ZodObject, ZodOptional } from "zod";
/* eslint-disable no-underscore-dangle */
@@ -589,7 +588,9 @@ export const allManagedEventTypeProps: { [k in keyof Omit
= { form: UseFormReturn; handleSubmit: SubmitHandler } & Omit<
+ JSX.IntrinsicElements["form"],
+ "onSubmit"
+>;
+
+const PlainForm = (props: FormProps, ref: Ref) => {
+ const { form, handleSubmit, ...passThrough } = props;
+
+ return (
+
+
+
+ );
+};
+
+export const Form = forwardRef(PlainForm) as (
+ p: FormProps & { ref?: Ref }
+) => ReactElement;
diff --git a/packages/ui/components/form/inputs/Input.tsx b/packages/ui/components/form/inputs/Input.tsx
index 5a5619df18..5944b40ec6 100644
--- a/packages/ui/components/form/inputs/Input.tsx
+++ b/packages/ui/components/form/inputs/Input.tsx
@@ -1,35 +1,14 @@
-import type { ReactElement, ReactNode, Ref } from "react";
+import type { ReactNode } from "react";
import React, { forwardRef, useCallback, useId, useState } from "react";
-import type { FieldValues, SubmitHandler, UseFormReturn } from "react-hook-form";
-import { FormProvider, useFormContext } from "react-hook-form";
+import { useFormContext } from "react-hook-form";
import classNames from "@calcom/lib/classNames";
-import { getErrorFromUnknown } from "@calcom/lib/errors";
import { useLocale } from "@calcom/lib/hooks/useLocale";
-import { Alert, showToast, Skeleton, Tooltip, UnstyledSelect } from "../../..";
-import { Eye, EyeOff, X, Search } from "../../icon";
-import { HintsOrErrors } from "./HintOrErrors";
+import { Alert, Input, InputField, Tooltip } from "../../..";
+import { Eye, EyeOff, Search } from "../../icon";
import { Label } from "./Label";
-
-type InputProps = JSX.IntrinsicElements["input"] & { isFullWidth?: boolean };
-
-export const Input = forwardRef(function Input(
- { isFullWidth = true, ...props },
- ref
-) {
- return (
-
- );
-});
+import type { InputFieldProps } from "./types";
export function InputLeading(props: JSX.IntrinsicElements["div"]) {
return (
@@ -39,174 +18,6 @@ export function InputLeading(props: JSX.IntrinsicElements["div"]) {
);
}
-type InputFieldProps = {
- label?: ReactNode;
- LockedIcon?: React.ReactNode;
- hint?: ReactNode;
- hintErrors?: string[];
- addOnLeading?: ReactNode;
- addOnSuffix?: ReactNode;
- inputIsFullWidth?: boolean;
- addOnFilled?: boolean;
- addOnClassname?: string;
- error?: string;
- labelSrOnly?: boolean;
- containerClassName?: string;
- showAsteriskIndicator?: boolean;
- t?: (key: string) => string;
-} & React.ComponentProps & {
- labelProps?: React.ComponentProps;
- labelClassName?: string;
- };
-
-type AddonProps = {
- children: React.ReactNode;
- isFilled?: boolean;
- className?: string;
- error?: boolean;
-};
-
-const Addon = ({ isFilled, children, className, error }: AddonProps) => (
-
-);
-
-export const InputField = forwardRef(function InputField(props, ref) {
- const id = useId();
- const { t: _t, isLocaleReady, i18n } = useLocale();
- const t = props.t || _t;
- const name = props.name || "";
- const {
- label = t(name),
- labelProps,
- labelClassName,
- disabled,
- LockedIcon,
- placeholder = isLocaleReady && i18n.exists(name + "_placeholder") ? t(name + "_placeholder") : "",
- className,
- addOnLeading,
- addOnSuffix,
- addOnFilled = true,
- addOnClassname,
- inputIsFullWidth,
- hint,
- type,
- hintErrors,
- labelSrOnly,
- containerClassName,
- readOnly,
- showAsteriskIndicator,
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- t: __t,
- ...passThrough
- } = props;
-
- const [inputValue, setInputValue] = useState("");
-
- return (
-
- {!!name && (
-
- {label}
- {showAsteriskIndicator && !readOnly && passThrough.required ? (
- *
- ) : null}
- {LockedIcon}
-
- )}
- {addOnLeading || addOnSuffix ? (
-
- {addOnLeading && (
-
- {addOnLeading}
-
- )}
-
{
- setInputValue(e.target.value);
- props.onChange && props.onChange(e);
- },
- value: inputValue,
- })}
- disabled={readOnly || disabled}
- ref={ref}
- />
- {addOnSuffix && (
-
- {addOnSuffix}
-
- )}
- {type === "search" && inputValue?.toString().length > 0 && (
-
{
- setInputValue("");
- props.onChange && props.onChange(e as unknown as React.ChangeEvent);
- }}
- />
- )}
-
- ) : (
-
- )}
-
- {hint &&
{hint}
}
-
- );
-});
-
-export const TextField = forwardRef(function TextField(props, ref) {
- return ;
-});
-
export const PasswordField = forwardRef(function PasswordField(
props,
ref
@@ -335,40 +146,6 @@ export const TextAreaField = forwardRef
);
});
-type FormProps = { form: UseFormReturn; handleSubmit: SubmitHandler } & Omit<
- JSX.IntrinsicElements["form"],
- "onSubmit"
->;
-
-const PlainForm = (props: FormProps, ref: Ref) => {
- const { form, handleSubmit, ...passThrough } = props;
-
- return (
-
-
-
- );
-};
-
-export const Form = forwardRef(PlainForm) as (
- p: FormProps & { ref?: Ref }
-) => ReactElement;
-
export function FieldsetLegend(props: JSX.IntrinsicElements["legend"]) {
return (