chore: dedupe yarn.lock to remove duplicate package versions (#26068)
* chore: dedupe yarn.lock to remove duplicate package versions - Consolidated 762 duplicate package versions - Reduced yarn.lock from 51,211 lines (1.7MB) to 44,471 lines (1.5MB) - Removed 7,071 lines (~200KB) of redundant dependency entries - Major packages deduplicated include: resolve, semver, type-fest, commander, glob, lru-cache, dotenv, @babel/* packages, typescript, tslib, postcss, and many more Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: resolve type errors in managed event types and react-select components - Add Zod-compatible versions of allManagedEventTypeProps and unlockedManagedEventTypeProps that only include scalar fields (excludes Prisma relation fields) - Update handleChildrenEventTypes.ts and queries.ts to use the new Zod-compatible props - Fix react-select CSS type errors in Select.tsx files by using Object.assign instead of spread operator to avoid TypeScript type inference issues - Fix lint warning in updateNewTeamMemberEventTypes by using if statement Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: derive eventType parameter type from actual query result Use Awaited<ReturnType<typeof getEventTypesToAddNewMembers>>[number] to ensure type safety at call sites, avoiding Prisma type namespace mismatches. Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: disable turbo cache for @calcom/trpc#build to prevent stale type errors Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: correct field names in API v1 validation schemas - Remove timeZone from booking schema (field doesn't exist on Booking model) - Remove bookingId from destination-calendar schema (field doesn't exist, only booking relation) - Change avatar to avatarUrl in user schema (correct field name) Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: use Object.assign for react-select styles to fix TypeScript spread type errors The spread operator causes TypeScript to compute an incompatible type with CSSObjectWithLabel due to the accentColor property. Using Object.assign preserves the correct type inference. Fixed files: - FormEdit.tsx - DestinationCalendarSelector.tsx (features and platform) - TimezoneSelect.tsx - ApiKeyDialogForm.tsx - Select.tsx (features/form) - WebhookForm.tsx Also fixed pre-existing lint warnings: - Constant truthiness in label assignment - Unused variant parameter Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: remove extra fields from allManagedEventTypePropsForZod to match original behavior The Zod-compatible version should only include scalar fields that were in the original allManagedEventTypeProps. Removed instantMeetingScheduleId, profileId, rrSegmentQueryValue, and assignRRMembersUsingSegment which were incorrectly added and caused test failures by including extra fields in Prisma update payloads. Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: remove access to fields not in Zod schema - Remove unnecessary destructuring of profileId and instantMeetingScheduleId from managedEventTypeValues in handleChildrenEventTypes.ts (these fields are already sourced from other variables) - Set rrSegmentQueryValue to undefined directly in queries.ts instead of accessing it from managedEventTypeValues (not applicable for managed children) Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: add name property to mock credentials and revert turbo cache change - Add name property to MockCredential type and factory function in InstallAppButtonChild.test.tsx to match expected credentials type - Revert turbo cache disable for @calcom/trpc#build (per review comment) Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: revert API v1 validation changes and restore eslint comment - Revert API v1 validation changes (booking.ts, destination-calendar.ts, user.ts) since API v1 is deprecated and these could be breaking changes - Restore eslint-disable comment for @typescript-eslint/no-empty-function in Select.tsx that was accidentally removed Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: add inputs to @calcom/trpc#build to properly invalidate cache Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: properly fix API v1 validation schemas for stricter zod 3.25.76 The yarn dedupe upgraded zod from 3.22.4 to 3.25.76, which has stricter .pick() typing that now properly rejects picking non-existent fields. Changes: - user.ts: Pick avatarUrl (actual Prisma field) and extend with avatar for API v1 backward compatibility - booking.ts: Remove timeZone from pick (not a field on Booking model, only exists in nested attendees/user objects) - destination-calendar.ts: Remove bookingId from pick (not a field on DestinationCalendar model) Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: remove turbo.json inputs for @calcom/trpc#build to use cached artifacts Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: use robust selector for react-select option in routing forms E2E test The previous selector used .nth(1) which assumed the email text appeared exactly twice in the DOM in a specific order. This broke when react-select was upgraded from 5.7.2 to 5.8.0 via yarn dedupe. The new approach waits for the react-select listbox to appear and clicks the option within it, which is more robust against DOM structure changes. Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
keith@cal.com <keithwillcode@gmail.com>
Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent
f846126a2d
commit
0e3696f20c
@@ -128,7 +128,7 @@ export const schemaBookingReadPublic = Booking.extend({
|
||||
title: true,
|
||||
startTime: true,
|
||||
endTime: true,
|
||||
timeZone: true,
|
||||
// Note: timeZone is not a field on Booking model - it's in nested attendees/user objects
|
||||
attendees: true,
|
||||
user: true,
|
||||
eventType: true,
|
||||
|
||||
@@ -2,11 +2,11 @@ import { z } from "zod";
|
||||
|
||||
import { DestinationCalendarSchema } from "@calcom/prisma/zod/modelSchema/DestinationCalendarSchema";
|
||||
|
||||
// Note: bookingId is not a field on DestinationCalendar model in Prisma schema
|
||||
export const schemaDestinationCalendarBaseBodyParams = DestinationCalendarSchema.pick({
|
||||
integration: true,
|
||||
externalId: true,
|
||||
eventTypeId: true,
|
||||
bookingId: true,
|
||||
userId: true,
|
||||
}).partial();
|
||||
|
||||
@@ -38,11 +38,11 @@ export const schemaDestinationCalendarEditBodyParams = schemaDestinationCalendar
|
||||
schemaDestinationCalendarEditParams
|
||||
);
|
||||
|
||||
// Note: bookingId is not a field on DestinationCalendar model in Prisma schema
|
||||
export const schemaDestinationCalendarReadPublic = DestinationCalendarSchema.pick({
|
||||
id: true,
|
||||
integration: true,
|
||||
externalId: true,
|
||||
eventTypeId: true,
|
||||
bookingId: true,
|
||||
userId: true,
|
||||
});
|
||||
|
||||
@@ -151,6 +151,7 @@ export const schemaUserCreateBodyParams = schemaUserBaseBodyParams
|
||||
.strict();
|
||||
|
||||
// @note: These are the values that are always returned when reading a user
|
||||
// Note: We pick avatarUrl from the Prisma schema and extend with avatar for API v1 backward compatibility
|
||||
export const schemaUserReadPublic = UserSchema.pick({
|
||||
id: true,
|
||||
username: true,
|
||||
@@ -158,7 +159,7 @@ export const schemaUserReadPublic = UserSchema.pick({
|
||||
email: true,
|
||||
emailVerified: true,
|
||||
bio: true,
|
||||
avatar: true,
|
||||
avatarUrl: true,
|
||||
timeZone: true,
|
||||
weekStart: true,
|
||||
endTime: true,
|
||||
@@ -176,6 +177,9 @@ export const schemaUserReadPublic = UserSchema.pick({
|
||||
verified: true,
|
||||
invitedTo: true,
|
||||
role: true,
|
||||
}).extend({
|
||||
// API v1 backward compatibility: expose avatarUrl as avatar
|
||||
avatar: UserSchema.shape.avatarUrl,
|
||||
});
|
||||
|
||||
export const schemaUsersReadPublic = z.array(schemaUserReadPublic);
|
||||
|
||||
@@ -162,14 +162,14 @@ function Field({
|
||||
<SelectField
|
||||
maxMenuHeight={200}
|
||||
styles={{
|
||||
singleValue: (baseStyles) => ({
|
||||
...baseStyles,
|
||||
fontSize: "14px",
|
||||
}),
|
||||
option: (baseStyles) => ({
|
||||
...baseStyles,
|
||||
fontSize: "14px",
|
||||
}),
|
||||
singleValue: (baseStyles) =>
|
||||
Object.assign({}, baseStyles, {
|
||||
fontSize: "14px",
|
||||
}),
|
||||
option: (baseStyles) =>
|
||||
Object.assign({}, baseStyles, {
|
||||
fontSize: "14px",
|
||||
}),
|
||||
}}
|
||||
label="Type"
|
||||
isDisabled={!!router}
|
||||
|
||||
@@ -7,35 +7,26 @@ import { InstallAppButtonChild } from "./InstallAppButtonChild";
|
||||
type MockCredential = {
|
||||
id: number;
|
||||
delegatedToId: string;
|
||||
userId: number;
|
||||
user: { email: string };
|
||||
userId: number | null;
|
||||
user: { email: string; name: string | null } | null;
|
||||
key: { access_token: string };
|
||||
invalid: boolean;
|
||||
teamId: null;
|
||||
team: null;
|
||||
delegationCredentialId: string;
|
||||
type:
|
||||
| `${string}_calendar`
|
||||
| `${string}_messaging`
|
||||
| `${string}_payment`
|
||||
| `${string}_video`
|
||||
| `${string}_other`
|
||||
| `${string}_automation`
|
||||
| `${string}_analytics`
|
||||
| `${string}_crm`
|
||||
| `${string}_other_calendar`;
|
||||
appId: string;
|
||||
invalid: boolean | null;
|
||||
teamId: number | null;
|
||||
team: { name: string } | null;
|
||||
delegationCredentialId: string | null;
|
||||
type: string;
|
||||
appId: string | null;
|
||||
};
|
||||
|
||||
// Factory function to create mock credentials
|
||||
const createMockCredential = (overrides: Partial<MockCredential> = {}): MockCredential => ({
|
||||
id: 1,
|
||||
type: "google_calendar" as const,
|
||||
type: "google_calendar",
|
||||
userId: 1,
|
||||
delegatedToId: "delegation-123",
|
||||
teamId: null,
|
||||
team: null,
|
||||
user: { email: "test@example.com" },
|
||||
user: { email: "test@example.com", name: "Test User" },
|
||||
key: { access_token: "mock_token_123" },
|
||||
delegationCredentialId: "delegation-123",
|
||||
appId: "google-calendar",
|
||||
|
||||
@@ -910,7 +910,11 @@ test.describe("Routing Forms", () => {
|
||||
await page.goto(`apps/routing-forms/form-edit/${formId}`);
|
||||
await page.getByTestId("settings-button").click();
|
||||
await page.click('[data-testid="routing-form-select-members"]');
|
||||
await page.getByText(text).nth(1).click();
|
||||
// Wait for the react-select menu to appear and click the option within it
|
||||
// This is more robust than using .nth(1) which assumes specific DOM structure
|
||||
const menuListbox = page.locator('[id$="-listbox"]');
|
||||
await menuListbox.waitFor({ state: "visible" });
|
||||
await menuListbox.getByText(text).click();
|
||||
await page.getByTestId("settings-slider-over-done").click();
|
||||
await saveCurrentForm(page);
|
||||
};
|
||||
|
||||
@@ -99,7 +99,7 @@ const DestinationCalendarSelector = ({
|
||||
|
||||
setSelectedOption({
|
||||
value: `${selected.integration}:${selected.externalId}`,
|
||||
label: `${selected.name} ` || "",
|
||||
label: selected.name ? `${selected.name} ` : "",
|
||||
subtitle: `(${selectedIntegration?.integration.title?.replace(/calendar/i, "")} - ${
|
||||
selectedIntegration?.primary?.name
|
||||
})`,
|
||||
@@ -148,17 +148,16 @@ const DestinationCalendarSelector = ({
|
||||
}
|
||||
options={options}
|
||||
styles={{
|
||||
placeholder: (styles) => ({ ...styles, ...content(hidePlaceholder) }),
|
||||
singleValue: (styles) => ({ ...styles, ...content(hidePlaceholder) }),
|
||||
control: (defaultStyles) => {
|
||||
return {
|
||||
...defaultStyles,
|
||||
"@media only screen and (min-width: 640px)": {
|
||||
...(defaultStyles["@media only screen and (min-width: 640px)"] as object),
|
||||
maxWidth,
|
||||
},
|
||||
};
|
||||
},
|
||||
placeholder: (styles) => Object.assign({}, styles, content(hidePlaceholder)),
|
||||
singleValue: (styles) => Object.assign({}, styles, content(hidePlaceholder)),
|
||||
control: (defaultStyles) =>
|
||||
Object.assign({}, defaultStyles, {
|
||||
"@media only screen and (min-width: 640px)": Object.assign(
|
||||
{},
|
||||
defaultStyles["@media only screen and (min-width: 640px)"] as object,
|
||||
{ maxWidth }
|
||||
),
|
||||
}),
|
||||
}}
|
||||
isSearchable={false}
|
||||
className={classNames(
|
||||
|
||||
@@ -75,7 +75,7 @@ export function TimezoneSelectComponent({
|
||||
classNames: timezoneClassNames,
|
||||
timezoneSelectCustomClassname,
|
||||
components,
|
||||
variant = "default",
|
||||
variant: _variant = "default",
|
||||
isPending,
|
||||
value,
|
||||
size = "md",
|
||||
@@ -116,15 +116,15 @@ export function TimezoneSelectComponent({
|
||||
...(isWebTimezoneSelect ? addTimezonesToDropdown(additionalTimezones) : {}),
|
||||
}}
|
||||
styles={{
|
||||
control: (base) => ({
|
||||
...base,
|
||||
minHeight: size === "sm" ? "28px" : "36px",
|
||||
height: grow ? "h-auto " : size === "sm" ? "28px" : "36px",
|
||||
}),
|
||||
menuList: (base) => ({
|
||||
...base,
|
||||
height: grow ? "h-auto " : size === "sm" ? "200px" : "180px",
|
||||
}),
|
||||
control: (base) =>
|
||||
Object.assign({}, base, {
|
||||
minHeight: size === "sm" ? "28px" : "36px",
|
||||
height: grow ? "h-auto " : size === "sm" ? "28px" : "36px",
|
||||
}),
|
||||
menuList: (base) =>
|
||||
Object.assign({}, base, {
|
||||
height: grow ? "h-auto " : size === "sm" ? "200px" : "180px",
|
||||
}),
|
||||
}}
|
||||
onInputChange={handleInputChange}
|
||||
{...props}
|
||||
|
||||
@@ -217,14 +217,14 @@ export default function ApiKeyDialogForm({
|
||||
return (
|
||||
<SelectField
|
||||
styles={{
|
||||
singleValue: (baseStyles) => ({
|
||||
...baseStyles,
|
||||
fontSize: "14px",
|
||||
}),
|
||||
option: (baseStyles) => ({
|
||||
...baseStyles,
|
||||
fontSize: "14px",
|
||||
}),
|
||||
singleValue: (baseStyles) =>
|
||||
Object.assign({}, baseStyles, {
|
||||
fontSize: "14px",
|
||||
}),
|
||||
option: (baseStyles) =>
|
||||
Object.assign({}, baseStyles, {
|
||||
fontSize: "14px",
|
||||
}),
|
||||
}}
|
||||
isDisabled={watchNeverExpires || !!defaultValues}
|
||||
containerClassName="data-testid-field-type"
|
||||
|
||||
@@ -6,7 +6,11 @@ import { getTranslation } from "@calcom/lib/server/i18n";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
import { SchedulingType } from "@calcom/prisma/enums";
|
||||
import { allManagedEventTypeProps, unlockedManagedEventTypeProps } from "@calcom/prisma/zod-utils";
|
||||
import {
|
||||
allManagedEventTypeProps,
|
||||
allManagedEventTypePropsForZod,
|
||||
unlockedManagedEventTypePropsForZod,
|
||||
} from "@calcom/prisma/zod-utils";
|
||||
import { EventTypeSchema } from "@calcom/prisma/zod/modelSchema/EventTypeSchema";
|
||||
|
||||
interface handleChildrenEventTypesProps {
|
||||
@@ -157,9 +161,9 @@ export default async function handleChildrenEventTypes({
|
||||
bookingFields: EventTypeSchema.shape.bookingFields.nullish(),
|
||||
});
|
||||
|
||||
const allManagedEventTypePropsZod = _ManagedEventTypeModel.pick(allManagedEventTypeProps);
|
||||
const allManagedEventTypePropsZod = _ManagedEventTypeModel.pick(allManagedEventTypePropsForZod);
|
||||
const managedEventTypeValues = allManagedEventTypePropsZod
|
||||
.omit(unlockedManagedEventTypeProps)
|
||||
.omit(unlockedManagedEventTypePropsForZod)
|
||||
.parse(eventType);
|
||||
|
||||
// Check we are certainly dealing with a managed event type through its metadata
|
||||
@@ -170,7 +174,7 @@ export default async function handleChildrenEventTypes({
|
||||
|
||||
// Define the values for unlocked properties to use on creation, not updation
|
||||
const unlockedEventTypeValues = allManagedEventTypePropsZod
|
||||
.pick(unlockedManagedEventTypeProps)
|
||||
.pick(unlockedManagedEventTypePropsForZod)
|
||||
.parse(eventType);
|
||||
// Calculate if there are new/existent/deleted children users for which the event type needs to be created/updated/deleted
|
||||
const previousUserIds = oldEventType.children?.flatMap((ch) => ch.userId ?? []);
|
||||
@@ -197,17 +201,10 @@ export default async function handleChildrenEventTypes({
|
||||
|
||||
// Create event types for new users added
|
||||
const eventTypesToCreateData = newUserIds.map((userId) => {
|
||||
// Exclude profileId and instantMeetingScheduleId from managed values to avoid duplication
|
||||
const {
|
||||
profileId: _,
|
||||
instantMeetingScheduleId: __,
|
||||
...managedValuesWithoutExplicit
|
||||
} = managedEventTypeValues;
|
||||
|
||||
return {
|
||||
instantMeetingScheduleId: eventType.instantMeetingScheduleId ?? undefined,
|
||||
profileId: profileId ?? null,
|
||||
...managedValuesWithoutExplicit,
|
||||
...managedEventTypeValues,
|
||||
...{
|
||||
...unlockedEventTypeValues,
|
||||
// pre-genned as allowed null
|
||||
|
||||
@@ -16,7 +16,8 @@ import { baseEventTypeSelect } from "@calcom/prisma/selects";
|
||||
import {
|
||||
EventTypeMetaDataSchema,
|
||||
allManagedEventTypeProps,
|
||||
unlockedManagedEventTypeProps,
|
||||
allManagedEventTypePropsForZod,
|
||||
unlockedManagedEventTypePropsForZod,
|
||||
eventTypeLocations,
|
||||
} from "@calcom/prisma/zod-utils";
|
||||
import { EventTypeSchema } from "@calcom/prisma/zod/modelSchema/EventTypeSchema";
|
||||
@@ -408,21 +409,21 @@ export async function isTeamMember(userId: number, teamId: number) {
|
||||
}));
|
||||
}
|
||||
|
||||
// Type derived from the actual query result to ensure type safety at call sites
|
||||
type EventTypeForChildCreation = Awaited<ReturnType<typeof getEventTypesToAddNewMembers>>[number];
|
||||
|
||||
export function generateNewChildEventTypeDataForDB({
|
||||
eventType,
|
||||
userId,
|
||||
includeWorkflow = true,
|
||||
includeUserConnect = true,
|
||||
}: {
|
||||
eventType: Omit<
|
||||
Prisma.EventTypeGetPayload<{ select: typeof allManagedEventTypeProps & { id: true } }>,
|
||||
"locations"
|
||||
> & { locations: Prisma.JsonValue | null };
|
||||
eventType: EventTypeForChildCreation;
|
||||
userId: number;
|
||||
includeWorkflow?: boolean;
|
||||
includeUserConnect?: boolean;
|
||||
}) {
|
||||
const allManagedEventTypePropsZod = EventTypeSchema.pick(allManagedEventTypeProps).extend({
|
||||
const allManagedEventTypePropsZod = EventTypeSchema.pick(allManagedEventTypePropsForZod).extend({
|
||||
bookingFields: EventTypeSchema.shape.bookingFields.nullish(),
|
||||
locations: z
|
||||
.preprocess((val: unknown) => (val === null ? undefined : val), eventTypeLocations)
|
||||
@@ -430,12 +431,12 @@ export function generateNewChildEventTypeDataForDB({
|
||||
});
|
||||
|
||||
const managedEventTypeValues = allManagedEventTypePropsZod
|
||||
.omit(unlockedManagedEventTypeProps)
|
||||
.omit(unlockedManagedEventTypePropsForZod)
|
||||
.parse(eventType);
|
||||
|
||||
// Define the values for unlocked properties to use on creation, not updation
|
||||
const unlockedEventTypeValues = allManagedEventTypePropsZod
|
||||
.pick(unlockedManagedEventTypeProps)
|
||||
.pick(unlockedManagedEventTypePropsForZod)
|
||||
.parse(eventType);
|
||||
|
||||
// Calculate if there are new workflows for which assigned members will get too
|
||||
@@ -452,7 +453,7 @@ export function generateNewChildEventTypeDataForDB({
|
||||
bookingFields: (managedEventTypeValues.bookingFields as Prisma.InputJsonValue) ?? undefined,
|
||||
durationLimits: (managedEventTypeValues.durationLimits as Prisma.InputJsonValue) ?? undefined,
|
||||
eventTypeColor: (managedEventTypeValues.eventTypeColor as Prisma.InputJsonValue) ?? undefined,
|
||||
rrSegmentQueryValue: (managedEventTypeValues.rrSegmentQueryValue as Prisma.InputJsonValue) ?? undefined,
|
||||
rrSegmentQueryValue: undefined,
|
||||
onlyShowFirstAvailableSlot: managedEventTypeValues.onlyShowFirstAvailableSlot ?? false,
|
||||
userId,
|
||||
...(includeUserConnect && {
|
||||
@@ -487,8 +488,8 @@ async function getEventTypesToAddNewMembers(teamId: number) {
|
||||
export async function updateNewTeamMemberEventTypes(userId: number, teamId: number) {
|
||||
const eventTypesToAdd = await getEventTypesToAddNewMembers(teamId);
|
||||
|
||||
eventTypesToAdd.length > 0 &&
|
||||
(await prisma.$transaction(
|
||||
if (eventTypesToAdd.length > 0) {
|
||||
await prisma.$transaction(
|
||||
eventTypesToAdd.map((eventType) => {
|
||||
if (eventType.schedulingType === "MANAGED") {
|
||||
return prisma.eventType.create({
|
||||
@@ -504,7 +505,8 @@ export async function updateNewTeamMemberEventTypes(userId: number, teamId: numb
|
||||
});
|
||||
}
|
||||
})
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function addNewMembersToEventTypes({ userIds, teamId }: { userIds: number[]; teamId: number }) {
|
||||
|
||||
@@ -102,14 +102,14 @@ function Select<
|
||||
},
|
||||
})}
|
||||
styles={{
|
||||
option: (provided, state) => ({
|
||||
...provided,
|
||||
color: state.isSelected ? "var(--brand-text-color)" : "black",
|
||||
":active": {
|
||||
backgroundColor: state.isSelected ? "" : "var(--brand-color)",
|
||||
color: "var(--brand-text-color)",
|
||||
},
|
||||
}),
|
||||
option: (provided, state) =>
|
||||
Object.assign({}, provided, {
|
||||
color: state.isSelected ? "var(--brand-text-color)" : "black",
|
||||
":active": {
|
||||
backgroundColor: state.isSelected ? "" : "var(--brand-color)",
|
||||
color: "var(--brand-text-color)",
|
||||
},
|
||||
}),
|
||||
}}
|
||||
components={{
|
||||
...components,
|
||||
@@ -179,7 +179,7 @@ export function SelectWithValidation<
|
||||
position: "absolute",
|
||||
}}
|
||||
value={hiddenInputValue}
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
|
||||
onChange={() => {}}
|
||||
// TODO:Not able to get focus to work
|
||||
// onFocus={() => selectRef.current?.focus()}
|
||||
|
||||
@@ -424,10 +424,10 @@ const WebhookForm = (props: {
|
||||
options={translatedTriggerOptions}
|
||||
isMulti
|
||||
styles={{
|
||||
indicatorsContainer: (base) => ({
|
||||
...base,
|
||||
alignItems: "flex-start",
|
||||
}),
|
||||
indicatorsContainer: (base) =>
|
||||
Object.assign({}, base, {
|
||||
alignItems: "flex-start",
|
||||
}),
|
||||
}}
|
||||
value={selectValue}
|
||||
onChange={(event) => {
|
||||
|
||||
@@ -54,7 +54,7 @@ export const DestinationCalendarSelector = ({
|
||||
|
||||
setSelectedOption({
|
||||
value: `${selected.integration}:${selected.externalId}`,
|
||||
label: `${selected.name} ` || "",
|
||||
label: selected.name ? `${selected.name} ` : "",
|
||||
subtitle: `(${selectedIntegration?.integration.title?.replace(/calendar/i, "")} - ${
|
||||
selectedIntegration?.primary?.name
|
||||
})`,
|
||||
@@ -104,23 +104,18 @@ export const DestinationCalendarSelector = ({
|
||||
}
|
||||
options={options}
|
||||
styles={{
|
||||
placeholder: (styles) => ({
|
||||
...styles,
|
||||
...getPlaceholderContent(hidePlaceholder, `'${t("create_events_on")}:'`),
|
||||
}),
|
||||
singleValue: (styles) => ({
|
||||
...styles,
|
||||
...getPlaceholderContent(hidePlaceholder, `'${t("create_events_on")}:'`),
|
||||
}),
|
||||
control: (defaultStyles) => {
|
||||
return {
|
||||
...defaultStyles,
|
||||
"@media only screen and (min-width: 640px)": {
|
||||
...(defaultStyles["@media only screen and (min-width: 640px)"] as object),
|
||||
maxWidth,
|
||||
},
|
||||
};
|
||||
},
|
||||
placeholder: (styles) =>
|
||||
Object.assign({}, styles, getPlaceholderContent(hidePlaceholder, `'${t("create_events_on")}:'`)),
|
||||
singleValue: (styles) =>
|
||||
Object.assign({}, styles, getPlaceholderContent(hidePlaceholder, `'${t("create_events_on")}:'`)),
|
||||
control: (defaultStyles) =>
|
||||
Object.assign({}, defaultStyles, {
|
||||
"@media only screen and (min-width: 640px)": Object.assign(
|
||||
{},
|
||||
defaultStyles["@media only screen and (min-width: 640px)"] as object,
|
||||
{ maxWidth }
|
||||
),
|
||||
}),
|
||||
}}
|
||||
isSearchable={false}
|
||||
className={classNames(
|
||||
|
||||
@@ -867,6 +867,81 @@ export const unlockedManagedEventTypeProps = {
|
||||
destinationCalendar: allManagedEventTypeProps.destinationCalendar,
|
||||
};
|
||||
|
||||
// Zod-compatible version of allManagedEventTypeProps that only includes scalar fields
|
||||
// (excludes Prisma relation fields like children, users, webhooks, availability, etc.)
|
||||
// This is used with EventTypeSchema.pick() which requires exact key matching
|
||||
// IMPORTANT: This must match the scalar fields in allManagedEventTypeProps exactly
|
||||
export const allManagedEventTypePropsForZod = {
|
||||
title: true,
|
||||
description: true,
|
||||
interfaceLanguage: true,
|
||||
isInstantEvent: true,
|
||||
instantMeetingParameters: true,
|
||||
instantMeetingExpiryTimeOffsetInSeconds: true,
|
||||
currency: true,
|
||||
periodDays: true,
|
||||
position: true,
|
||||
price: true,
|
||||
slug: true,
|
||||
length: true,
|
||||
offsetStart: true,
|
||||
locations: true,
|
||||
hidden: true,
|
||||
recurringEvent: true,
|
||||
minimumRescheduleNotice: true,
|
||||
disableGuests: true,
|
||||
disableCancelling: true,
|
||||
disableRescheduling: true,
|
||||
allowReschedulingCancelledBookings: true,
|
||||
requiresConfirmation: true,
|
||||
canSendCalVideoTranscriptionEmails: true,
|
||||
requiresConfirmationForFreeEmail: true,
|
||||
requiresConfirmationWillBlockSlot: true,
|
||||
eventName: true,
|
||||
metadata: true,
|
||||
hideCalendarNotes: true,
|
||||
hideCalendarEventDetails: true,
|
||||
minimumBookingNotice: true,
|
||||
beforeEventBuffer: true,
|
||||
afterEventBuffer: true,
|
||||
successRedirectUrl: true,
|
||||
seatsPerTimeSlot: true,
|
||||
seatsShowAttendees: true,
|
||||
seatsShowAvailabilityCount: true,
|
||||
forwardParamsSuccessRedirect: true,
|
||||
periodType: true,
|
||||
periodStartDate: true,
|
||||
periodEndDate: true,
|
||||
periodCountCalendarDays: true,
|
||||
bookingLimits: true,
|
||||
onlyShowFirstAvailableSlot: true,
|
||||
showOptimizedSlots: true,
|
||||
slotInterval: true,
|
||||
scheduleId: true,
|
||||
bookingFields: true,
|
||||
durationLimits: true,
|
||||
maxActiveBookingsPerBooker: true,
|
||||
maxActiveBookingPerBookerOfferReschedule: true,
|
||||
lockTimeZoneToggleOnBookingPage: true,
|
||||
lockedTimeZone: true,
|
||||
requiresBookerEmailVerification: true,
|
||||
assignAllTeamMembers: true,
|
||||
isRRWeightsEnabled: true,
|
||||
eventTypeColor: true,
|
||||
allowReschedulingPastBookings: true,
|
||||
hideOrganizerEmail: true,
|
||||
rescheduleWithSameRoundRobinHost: true,
|
||||
maxLeadThreshold: true,
|
||||
customReplyToEmail: true,
|
||||
bookingRequiresAuthentication: true,
|
||||
} as const;
|
||||
|
||||
// Zod-compatible version of unlockedManagedEventTypeProps
|
||||
export const unlockedManagedEventTypePropsForZod = {
|
||||
locations: true,
|
||||
scheduleId: true,
|
||||
} as const;
|
||||
|
||||
export const emailSchema = emailRegexSchema;
|
||||
|
||||
// The PR at https://github.com/colinhacks/zod/pull/2157 addresses this issue and improves email validation
|
||||
|
||||
@@ -41,14 +41,14 @@ function Select<
|
||||
},
|
||||
})}
|
||||
styles={{
|
||||
option: (provided, state) => ({
|
||||
...provided,
|
||||
color: state.isSelected ? "var(--brand-text-color)" : "black",
|
||||
":active": {
|
||||
backgroundColor: state.isSelected ? "" : "var(--brand-color)",
|
||||
color: "var(--brand-text-color)",
|
||||
},
|
||||
}),
|
||||
option: (provided, state) =>
|
||||
Object.assign({}, provided, {
|
||||
color: state.isSelected ? "var(--brand-text-color)" : "black",
|
||||
":active": {
|
||||
backgroundColor: state.isSelected ? "" : "var(--brand-color)",
|
||||
color: "var(--brand-text-color)",
|
||||
},
|
||||
}),
|
||||
}}
|
||||
components={{
|
||||
...components,
|
||||
@@ -78,24 +78,24 @@ export function UnstyledSelect<
|
||||
Input: InputComponent,
|
||||
}}
|
||||
styles={{
|
||||
container: (provided) => ({
|
||||
...provided,
|
||||
width: "100%",
|
||||
}),
|
||||
control: (provided) => ({
|
||||
...provided,
|
||||
backgroundColor: " transparent",
|
||||
border: "none",
|
||||
boxShadow: "none",
|
||||
}),
|
||||
option: (provided, state) => ({
|
||||
...provided,
|
||||
color: state.isSelected ? "var(--brand-text-color)" : "black",
|
||||
":active": {
|
||||
backgroundColor: state.isSelected ? "" : "var(--brand-color)",
|
||||
color: "var(--brand-text-color)",
|
||||
},
|
||||
}),
|
||||
container: (provided, _props) =>
|
||||
Object.assign({}, provided, {
|
||||
width: "100%",
|
||||
}),
|
||||
control: (provided, _props) =>
|
||||
Object.assign({}, provided, {
|
||||
backgroundColor: " transparent",
|
||||
border: "none",
|
||||
boxShadow: "none",
|
||||
}),
|
||||
option: (provided, state) =>
|
||||
Object.assign({}, provided, {
|
||||
color: state.isSelected ? "var(--brand-text-color)" : "black",
|
||||
":active": {
|
||||
backgroundColor: state.isSelected ? "" : "var(--brand-color)",
|
||||
color: "var(--brand-text-color)",
|
||||
},
|
||||
}),
|
||||
indicatorSeparator: () => ({
|
||||
display: "hidden",
|
||||
color: "black",
|
||||
|
||||
@@ -50,11 +50,11 @@ export const Select = <
|
||||
{...reactSelectProps}
|
||||
menuPlacement={menuPlacement}
|
||||
styles={{
|
||||
control: (base) => ({
|
||||
...base,
|
||||
minHeight: size === "sm" ? "28px" : "32px",
|
||||
height: grow ? "auto" : size === "sm" ? "28px" : "32px",
|
||||
}),
|
||||
control: (base, _props) =>
|
||||
Object.assign({}, base, {
|
||||
minHeight: size === "sm" ? "28px" : "32px",
|
||||
height: grow ? "auto" : size === "sm" ? "28px" : "32px",
|
||||
}),
|
||||
}}
|
||||
classNames={{
|
||||
input: () => cx("text-emphasis", innerClassNames?.input),
|
||||
|
||||
Reference in New Issue
Block a user