refactor: Extract <CalVideoSettings /> from `<Locations /> (#23113)

* Create `CalVideoSettings` type

* Create `LocationOptionContainer`

* Extract cal video settings to `CalVideoSettings`

* Refactor `<Locations />` component to use `<CalVideoSettings />`

* Unify naming

* Move location folder back under components

* Type fixes

* Delete console.log
This commit is contained in:
Joe Au-Yeung
2025-08-19 10:24:28 +00:00
committed by GitHub
parent 9e9f815809
commit f9e24f51a7
6 changed files with 176 additions and 143 deletions
@@ -2,9 +2,11 @@ import { useMemo } from "react";
import { useFormContext } from "react-hook-form";
import type { UseFormGetValues, UseFormSetValue, Control, FormState } from "react-hook-form";
import type { TLocationOptions } from "@calcom/features/eventtypes/components/Locations";
import type { TEventTypeLocation } from "@calcom/features/eventtypes/components/Locations";
import Locations from "@calcom/features/eventtypes/components/Locations";
import type {
TLocationOptions,
TEventTypeLocation,
} from "@calcom/features/eventtypes/components/locations/Locations";
import Locations from "@calcom/features/eventtypes/components/locations/Locations";
import type { LocationFormValues } from "@calcom/features/eventtypes/lib/types";
import type { SingleValueLocationOption } from "@calcom/features/form/components/LocationSelect";
import { useLocale } from "@calcom/lib/hooks/useLocale";
@@ -0,0 +1,143 @@
import { ErrorMessage } from "@hookform/error-message";
import { useFormContext, Controller } from "react-hook-form";
import { useIsPlatform } from "@calcom/atoms/hooks/useIsPlatform";
import type { FormValues } from "@calcom/features/eventtypes/lib/types";
import type { CalVideoSettings as CalVideoSettingsType } from "@calcom/features/eventtypes/lib/types";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import classNames from "@calcom/ui/classNames";
import { UpgradeTeamsBadge } from "@calcom/ui/components/badge";
import { TextField } from "@calcom/ui/components/form";
import { SettingsToggle } from "@calcom/ui/components/form";
import LocationSettingsContainer from "./LocationSettingsContainer";
const CalVideoSettings = ({ calVideoSettings }: { calVideoSettings?: CalVideoSettingsType }) => {
const { t } = useLocale();
const formMethods = useFormContext<FormValues>();
const isPlatform = useIsPlatform();
return (
<LocationSettingsContainer>
<Controller
name="calVideoSettings.disableRecordingForGuests"
defaultValue={!!calVideoSettings?.disableRecordingForGuests}
render={({ field: { onChange, value } }) => {
return (
<SettingsToggle
title={t("disable_recording_for_guests")}
labelClassName="text-sm leading-6 whitespace-normal break-words"
checked={value}
onCheckedChange={onChange}
Badge={<UpgradeTeamsBadge checkForActiveStatus />}
/>
);
}}
/>
<Controller
name="calVideoSettings.disableRecordingForOrganizer"
defaultValue={!!calVideoSettings?.disableRecordingForOrganizer}
render={({ field: { onChange, value } }) => {
return (
<SettingsToggle
title={t("disable_recording_for_organizer")}
labelClassName="text-sm leading-6 whitespace-normal break-words"
checked={value}
onCheckedChange={onChange}
Badge={<UpgradeTeamsBadge checkForActiveStatus />}
/>
);
}}
/>
{!isPlatform && (
<Controller
name="calVideoSettings.enableAutomaticRecordingForOrganizer"
defaultValue={!!calVideoSettings?.enableAutomaticRecordingForOrganizer}
render={({ field: { onChange, value } }) => {
return (
<SettingsToggle
title={t("enable_automatic_recording")}
labelClassName="text-sm"
checked={value}
onCheckedChange={onChange}
Badge={<UpgradeTeamsBadge checkForActiveStatus />}
/>
);
}}
/>
)}
<Controller
name="calVideoSettings.enableAutomaticTranscription"
defaultValue={!!calVideoSettings?.enableAutomaticTranscription}
render={({ field: { onChange, value } }) => {
return (
<SettingsToggle
title={t("enable_automatic_transcription")}
labelClassName="text-sm leading-6 whitespace-normal break-words"
checked={value}
onCheckedChange={onChange}
Badge={<UpgradeTeamsBadge checkForActiveStatus />}
/>
);
}}
/>
{!isPlatform && (
<Controller
name="calVideoSettings.disableTranscriptionForGuests"
defaultValue={!!calVideoSettings?.disableTranscriptionForGuests}
render={({ field: { onChange, value } }) => {
return (
<SettingsToggle
title={t("disable_transcription_for_guests")}
labelClassName="text-sm leading-6 whitespace-normal break-words"
checked={value}
onCheckedChange={onChange}
Badge={<UpgradeTeamsBadge checkForActiveStatus />}
/>
);
}}
/>
)}
{!isPlatform && (
<Controller
name="calVideoSettings.disableTranscriptionForOrganizer"
defaultValue={!!calVideoSettings?.disableTranscriptionForOrganizer}
render={({ field: { onChange, value } }) => {
return (
<SettingsToggle
title={t("disable_transcription_for_organizer")}
labelClassName="text-sm leading-6 whitespace-normal break-words"
checked={value}
onCheckedChange={onChange}
Badge={<UpgradeTeamsBadge checkForActiveStatus />}
/>
);
}}
/>
)}
<TextField
label={t("enter_redirect_url_on_exit_description")}
defaultValue={calVideoSettings?.redirectUrlOnExit || ""}
data-testid="calVideoSettings.redirectUrlOnExit"
containerClassName="mt-4"
className="leading-6"
{...formMethods.register("calVideoSettings.redirectUrlOnExit", {
setValueAs: (v) => (!v || v.trim() === "" ? null : v),
})}
/>
<ErrorMessage
errors={formMethods.formState.errors?.calVideoSettings}
name="redirectUrlOnExit"
className={classNames("text-error text-sm")}
as="div"
id="calVideoSettings.redirectUrlOnExit-error"
/>
</LocationSettingsContainer>
);
};
export default CalVideoSettings;
@@ -0,0 +1,11 @@
const LocationSettingsContainer = ({ children }: { children: React.ReactNode }) => {
return (
<div className="bg-muted mt-2 space-y-2 rounded-lg p-4">
<div className="w-full">
<div className="flex flex-col gap-4">{children}</div>
</div>
</div>
);
};
export default LocationSettingsContainer;
@@ -25,14 +25,13 @@ import ServerTrans from "@calcom/lib/components/ServerTrans";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import classNames from "@calcom/ui/classNames";
import { UpgradeTeamsBadge } from "@calcom/ui/components/badge";
import { Button } from "@calcom/ui/components/button";
import { TextField } from "@calcom/ui/components/form";
import { SettingsToggle } from "@calcom/ui/components/form";
import { Input } from "@calcom/ui/components/form";
import { Icon } from "@calcom/ui/components/icon";
import { showToast } from "@calcom/ui/components/toast";
import CalVideoSettings from "./CalVideoSettings";
export type TEventTypeLocation = Pick<EventTypeSetupProps["eventType"], "locations" | "calVideoSettings">;
export type TLocationOptions = Pick<EventTypeSetupProps, "locationOptions">["locationOptions"];
export type TDestinationCalendar = { integration: string } | null;
@@ -342,132 +341,7 @@ const Locations: React.FC<LocationsProps> = ({
)}
</div>
{isCalVideo && !isPlatform && (
<div className="bg-muted mt-2 space-y-2 rounded-lg p-4">
<div className="w-full">
<div className="flex flex-col gap-4">
<Controller
name="calVideoSettings.disableRecordingForGuests"
defaultValue={!!eventType.calVideoSettings?.disableRecordingForGuests}
render={({ field: { onChange, value } }) => {
return (
<SettingsToggle
title={t("disable_recording_for_guests")}
labelClassName="text-sm leading-6 whitespace-normal break-words"
checked={value}
onCheckedChange={onChange}
Badge={<UpgradeTeamsBadge checkForActiveStatus />}
/>
);
}}
/>
<Controller
name="calVideoSettings.disableRecordingForOrganizer"
defaultValue={!!eventType.calVideoSettings?.disableRecordingForOrganizer}
render={({ field: { onChange, value } }) => {
return (
<SettingsToggle
title={t("disable_recording_for_organizer")}
labelClassName="text-sm leading-6 whitespace-normal break-words"
checked={value}
onCheckedChange={onChange}
Badge={<UpgradeTeamsBadge checkForActiveStatus />}
/>
);
}}
/>
{!isPlatform && (
<Controller
name="calVideoSettings.enableAutomaticRecordingForOrganizer"
defaultValue={!!eventType.calVideoSettings?.enableAutomaticRecordingForOrganizer}
render={({ field: { onChange, value } }) => {
return (
<SettingsToggle
title={t("enable_automatic_recording")}
labelClassName="text-sm"
checked={value}
onCheckedChange={onChange}
Badge={<UpgradeTeamsBadge checkForActiveStatus />}
/>
);
}}
/>
)}
<Controller
name="calVideoSettings.enableAutomaticTranscription"
defaultValue={!!eventType.calVideoSettings?.enableAutomaticTranscription}
render={({ field: { onChange, value } }) => {
return (
<SettingsToggle
title={t("enable_automatic_transcription")}
labelClassName="text-sm leading-6 whitespace-normal break-words"
checked={value}
onCheckedChange={onChange}
Badge={<UpgradeTeamsBadge checkForActiveStatus />}
/>
);
}}
/>
{!isPlatform && (
<Controller
name="calVideoSettings.disableTranscriptionForGuests"
defaultValue={!!eventType.calVideoSettings?.disableTranscriptionForGuests}
render={({ field: { onChange, value } }) => {
return (
<SettingsToggle
title={t("disable_transcription_for_guests")}
labelClassName="text-sm leading-6 whitespace-normal break-words"
checked={value}
onCheckedChange={onChange}
Badge={<UpgradeTeamsBadge checkForActiveStatus />}
/>
);
}}
/>
)}
{!isPlatform && (
<Controller
name="calVideoSettings.disableTranscriptionForOrganizer"
defaultValue={!!eventType.calVideoSettings?.disableTranscriptionForOrganizer}
render={({ field: { onChange, value } }) => {
return (
<SettingsToggle
title={t("disable_transcription_for_organizer")}
labelClassName="text-sm leading-6 whitespace-normal break-words"
checked={value}
onCheckedChange={onChange}
Badge={<UpgradeTeamsBadge checkForActiveStatus />}
/>
);
}}
/>
)}
<TextField
label={t("enter_redirect_url_on_exit_description")}
defaultValue={eventType.calVideoSettings?.redirectUrlOnExit || ""}
data-testid="calVideoSettings.redirectUrlOnExit"
containerClassName="mt-4"
className="leading-6"
{...formMethods.register("calVideoSettings.redirectUrlOnExit", {
setValueAs: (v) => (!v || v.trim() === "" ? null : v),
})}
/>
<ErrorMessage
errors={formMethods.formState.errors?.calVideoSettings}
name="redirectUrlOnExit"
className={classNames("text-error text-sm")}
as="div"
id="calVideoSettings.redirectUrlOnExit-error"
/>
</div>
</div>
</div>
)}
{isCalVideo && !isPlatform && <CalVideoSettings />}
{eventLocationType?.organizerInputType && (
<div className="mt-2 space-y-2">
@@ -5,8 +5,6 @@ import type { MultiValue } from "react-select";
import { useIsPlatform } from "@calcom/atoms/hooks/useIsPlatform";
import useLockedFieldsManager from "@calcom/features/ee/managed-event-types/hooks/useLockedFieldsManager";
import type { LocationCustomClassNames } from "@calcom/features/eventtypes/components/Locations";
import Locations from "@calcom/features/eventtypes/components/Locations";
import type {
EventTypeSetupProps,
InputClassNames,
@@ -28,6 +26,9 @@ import { Select } from "@calcom/ui/components/form";
import { SettingsToggle } from "@calcom/ui/components/form";
import { Skeleton } from "@calcom/ui/components/skeleton";
import type { LocationCustomClassNames } from "../../locations/Locations";
import Locations from "../../locations/Locations";
export type EventSetupTabCustomClassNames = {
wrapper?: string;
titleSection?: {
+11 -9
View File
@@ -168,15 +168,7 @@ export type FormValues = {
restrictionScheduleId: number | null;
useBookerTimezone: boolean;
restrictionScheduleName: string | null;
calVideoSettings?: {
disableRecordingForOrganizer?: boolean;
disableRecordingForGuests?: boolean;
enableAutomaticTranscription?: boolean;
enableAutomaticRecordingForOrganizer?: boolean;
disableTranscriptionForGuests?: boolean;
disableTranscriptionForOrganizer?: boolean;
redirectUrlOnExit?: string;
};
calVideoSettings?: CalVideoSettings;
maxActiveBookingPerBookerOfferReschedule: boolean;
};
@@ -243,3 +235,13 @@ export interface EventTypePlatformWrapperRef {
validateForm: () => Promise<FormValidationResult>;
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;
}