feat: Booker atom read only fields (#16904)

* refactor: include user-readonly in BookingFields

* feat: add read only name and email booking fields

* feat: Booker atom prop for read only name and email

* refactor: simplify props type
This commit is contained in:
Lauris Skraucis
2024-10-07 15:03:07 +05:30
committed by GitHub
parent ba5b9e951a
commit b0bfec7247
4 changed files with 61 additions and 12 deletions
@@ -40,11 +40,15 @@ export const BookingFields = ({
// During reschedule by default all system fields are readOnly. Make them editable on case by case basis.
// Allowing a system field to be edited might require sending emails to attendees, so we need to be careful
let readOnly =
const rescheduleReadOnly =
(field.editable === "system" || field.editable === "system-but-optional") &&
!!rescheduleUid &&
bookingData !== null;
const bookingReadOnly = field.editable === "user-readonly";
let readOnly = bookingReadOnly || rescheduleReadOnly;
let hidden = !!field.hidden;
const fieldViews = field.views;
@@ -227,7 +227,7 @@ const CustomFieldsSchema = z.object({
const SystemFieldSchema = z.object({
defaultLabel: z.string(),
label: z.string().optional(),
editable: z.enum(["system-but-optional", "system"]),
editable: z.enum(["system-but-optional", "system", "user-readonly"]),
sources: z.array(
z.object({
id: z.literal("default"),
@@ -352,6 +352,21 @@ export const systemBeforeFieldName: NameSystemField = {
],
};
export const systemBeforeFieldNameReadOnly: NameSystemField = {
type: "name",
name: "name",
editable: "user-readonly",
defaultLabel: "your_name",
required: true,
sources: [
{
label: "Default",
id: "default",
type: "default",
},
],
};
export const systemBeforeFieldEmail: EmailSystemField = {
defaultLabel: "email_address",
type: "email",
@@ -367,6 +382,21 @@ export const systemBeforeFieldEmail: EmailSystemField = {
],
};
export const systemBeforeFieldEmailReadOnly: EmailSystemField = {
defaultLabel: "email_address",
type: "email",
name: "email",
required: true,
editable: "user-readonly",
sources: [
{
label: "Default",
id: "default",
type: "default",
},
],
};
export const systemBeforeFieldLocation: LocationReasonSystemField = {
defaultLabel: "location",
type: "radioInput",
@@ -62,6 +62,10 @@ export type BookerPlatformWrapperAtomProps = Omit<
notes?: string;
rescheduleReason?: string;
} & Record<string, string | string[]>;
readOnlyFormValues?: {
name?: boolean;
email?: boolean;
};
handleCreateBooking?: (input: UseCreateBookingInput) => void;
onCreateBookingSuccess?: (data: ApiSuccessResponse<BookingResponse>) => void;
onCreateBookingError?: (data: ApiErrorResponse | Error) => void;
@@ -150,7 +154,7 @@ export const BookerPlatformWrapper = (
isPending: isTeamPending,
data:
teamEventTypeData && teamEventTypeData.length > 0
? transformApiTeamEventTypeForAtom(teamEventTypeData[0], props.entity)
? transformApiTeamEventTypeForAtom(teamEventTypeData[0], props.entity, props.readOnlyFormValues)
: undefined,
};
}
@@ -159,7 +163,10 @@ export const BookerPlatformWrapper = (
isSuccess,
isError,
isPending,
data: data && data.length > 0 ? transformApiEventTypeForAtom(data[0], props.entity) : undefined,
data:
data && data.length > 0
? transformApiEventTypeForAtom(data[0], props.entity, props.readOnlyFormValues)
: undefined,
};
}, [
props.isTeamEvent,
@@ -1,4 +1,3 @@
import type { BookerProps } from "@calcom/features/bookings/Booker";
import { defaultEvents } from "@calcom/lib/defaultEvents";
import type { CustomField, SystemField } from "@calcom/lib/event-types/transformers";
import {
@@ -9,6 +8,8 @@ import {
systemBeforeFieldLocation,
systemAfterFieldRescheduleReason,
transformRecurrenceApiToInternal,
systemBeforeFieldNameReadOnly,
systemBeforeFieldEmailReadOnly,
} from "@calcom/lib/event-types/transformers";
import { getBookerBaseUrlSync } from "@calcom/lib/getBookerUrl/client";
import type {
@@ -24,9 +25,12 @@ import {
eventTypeBookingFields,
} from "@calcom/prisma/zod-utils";
import type { BookerPlatformWrapperAtomProps } from "../../booker/BookerPlatformWrapper";
export function transformApiEventTypeForAtom(
eventType: Omit<EventTypeOutput_2024_06_14, "ownerId">,
entity: BookerProps["entity"] | undefined
entity: BookerPlatformWrapperAtomProps["entity"] | undefined,
readOnlyFormValues: BookerPlatformWrapperAtomProps["readOnlyFormValues"] | undefined
) {
const { lengthInMinutes, locations, bookingFields, users, recurrence, ...rest } = eventType;
@@ -46,7 +50,7 @@ export function transformApiEventTypeForAtom(
...rest,
length: lengthInMinutes,
locations: getLocations(locations),
bookingFields: getBookingFields(bookingFields),
bookingFields: getBookingFields(bookingFields, readOnlyFormValues),
isDefault,
isDynamic: false,
profile: {
@@ -102,7 +106,8 @@ export function transformApiEventTypeForAtom(
export function transformApiTeamEventTypeForAtom(
eventType: TeamEventTypeOutput_2024_06_14,
entity: BookerProps["entity"] | undefined
entity: BookerPlatformWrapperAtomProps["entity"] | undefined,
readOnlyFormValues: BookerPlatformWrapperAtomProps["readOnlyFormValues"] | undefined
) {
const { lengthInMinutes, locations, hosts, bookingFields, recurrence, ...rest } = eventType;
@@ -121,7 +126,7 @@ export function transformApiTeamEventTypeForAtom(
...rest,
length: lengthInMinutes,
locations: getLocations(locations),
bookingFields: getBookingFields(bookingFields),
bookingFields: getBookingFields(bookingFields, readOnlyFormValues),
isDefault,
isDynamic: false,
profile: {
@@ -219,10 +224,13 @@ function getLocations(locations: EventTypeOutput_2024_06_14["locations"]) {
return withPrivateHidden;
}
function getBookingFields(bookingFields: EventTypeOutput_2024_06_14["bookingFields"]) {
function getBookingFields(
bookingFields: EventTypeOutput_2024_06_14["bookingFields"],
readOnlyFormValues: BookerPlatformWrapperAtomProps["readOnlyFormValues"] | undefined
) {
const systemBeforeFields: SystemField[] = [
systemBeforeFieldName,
systemBeforeFieldEmail,
readOnlyFormValues?.name ? systemBeforeFieldNameReadOnly : systemBeforeFieldName,
readOnlyFormValues?.email ? systemBeforeFieldEmailReadOnly : systemBeforeFieldEmail,
systemBeforeFieldLocation,
];