fix: resolve 404 error when rescheduling seated event bookings (#23956)
* fix: skip select field validation for existing responses during reschedule - Modify hasRequiredBookingFieldsResponses to detect reschedule context - Skip validation for select, multiselect, checkbox, and radio fields during reschedule to preserve existing responses - Fixes validation error when rescheduling bookings with select field responses that may no longer match current field options Resolves issue where reschedule operations fail with 'Value Travel, Adventure & Wildlife is not valid for type select for field Niche-project' error Co-Authored-By: anik@cal.com <adhabal2002@gmail.com> * fix: skip frontend validation for existing select field responses during reschedule - Revert backend changes in bookings.service.ts as the issue is frontend-only - Add reschedule detection in getBookingResponsesSchema.ts preprocess function - Skip option validation for select, radio, multiselect, and checkbox fields during reschedule - Preserves existing booking responses that may no longer match current field options - Fixes error 'Value Travel, Adventure & Wildlife is not valid for type select for field Niche-project' during slot selection Co-Authored-By: anik@cal.com <adhabal2002@gmail.com> * fix: extend reschedule validation skip to handle multiemail fields like guests - Add reschedule-aware logic to multiemail validation in getBookingResponsesSchema.ts - Skip validation for existing multiemail responses during reschedule to avoid type mismatch errors - Fixes 'Value is not valid for type text for field guests' error during slot selection - Complements existing fix for select/radio field validation during reschedule Co-Authored-By: anik@cal.com <adhabal2002@gmail.com> * fix: disable guests field inputs for seated events - Disable type SelectField for guests field in seated events - Disable identifier InputField for guests field in seated events - Add validation to prevent saving guests field changes for seated events - Pass seatsEnabled prop from EventAdvancedTab to FormBuilder - Use condition: seatsEnabled && formFieldType === 'multiemail' && fieldForm.getValues('name') === 'guests' - Fix linting warnings: remove unused variable and add missing dependency Co-Authored-By: anik@cal.com <adhabal2002@gmail.com> * Update getBookingResponsesSchema.ts * Update FormBuilder.tsx * Update FormBuilder.tsx * update --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
anik@cal.com <adhabal2002@gmail.com>
Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent
5463dc261c
commit
f3d60b141f
@@ -2202,6 +2202,7 @@
|
||||
"booking_confirmation_failed": "Booking confirmation failed",
|
||||
"not_enough_seats": "Not enough seats",
|
||||
"form_builder_field_already_exists": "A field with this name already exists",
|
||||
"guests_field_must_be_multiemail": "Guests field must be of type 'Multiple emails'",
|
||||
"show_on_booking_page": "Show on booking page",
|
||||
"visit_cancelled_booking": "You can visit the canceled booking page",
|
||||
"get_started_zapier_templates": "Get started with Zapier templates",
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { TooltipProvider } from "@radix-ui/react-tooltip";
|
||||
import { render } from "@testing-library/react";
|
||||
import { render, screen, waitFor } from "@testing-library/react";
|
||||
import type { ReactNode } from "react";
|
||||
import * as React from "react";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { vi } from "vitest";
|
||||
|
||||
import { showToast } from "@calcom/ui/components/toast";
|
||||
|
||||
import { FormBuilder } from "./FormBuilder";
|
||||
import {
|
||||
mockProps,
|
||||
@@ -32,6 +34,10 @@ vi.mock("next/navigation", async (importOriginal) => {
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("@calcom/ui/components/toast", () => ({
|
||||
showToast: vi.fn(),
|
||||
}));
|
||||
|
||||
const renderComponent = ({
|
||||
formBuilderProps: formBuilderProps,
|
||||
formDefaultValues: formDefaultValues,
|
||||
@@ -219,7 +225,6 @@ describe("FormBuilder", () => {
|
||||
],
|
||||
});
|
||||
|
||||
|
||||
verifier.verifyOptionPrices({ identifier, prices: [20, 25] });
|
||||
});
|
||||
|
||||
@@ -271,4 +276,40 @@ describe("FormBuilder", () => {
|
||||
verifier.verifyOptionPrices({ identifier, prices: [50, 75, 100] });
|
||||
});
|
||||
});
|
||||
|
||||
describe("Guests Field Validation Tests", () => {
|
||||
beforeEach(() => {
|
||||
renderComponent({ formBuilderProps: mockProps, formDefaultValues: {} });
|
||||
});
|
||||
|
||||
it("Should prevent saving guests field with non-multiemail type", async () => {
|
||||
const dialog = pageObject.openAddFieldDialog();
|
||||
|
||||
pageObject.dialog.selectFieldType({ dialog, fieldType: "text" });
|
||||
pageObject.dialog.fillInFieldIdentifier({ dialog, identifier: "guests" });
|
||||
pageObject.dialog.fillInFieldLabel({ dialog, label: "Guests", fieldType: "text" });
|
||||
|
||||
pageObject.dialog.saveField({ dialog });
|
||||
|
||||
await waitFor(() => {
|
||||
expect(showToast).toHaveBeenCalledWith("guests_field_must_be_multiemail", "error");
|
||||
});
|
||||
|
||||
expect(screen.queryByTestId("field-guests")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("Should allow saving guests field with multiemail type", async () => {
|
||||
const dialog = pageObject.openAddFieldDialog();
|
||||
|
||||
pageObject.dialog.selectFieldType({ dialog, fieldType: "multiemail" });
|
||||
pageObject.dialog.fillInFieldIdentifier({ dialog, identifier: "guests" });
|
||||
pageObject.dialog.fillInFieldLabel({ dialog, label: "Guests", fieldType: "multiemail" });
|
||||
|
||||
pageObject.dialog.saveField({ dialog });
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("field-guests")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -380,6 +380,12 @@ export const FormBuilder = function FormBuilder({
|
||||
handleSubmit={(data: Parameters<SubmitHandler<RhfFormField>>[0]) => {
|
||||
const type = data.type || "text";
|
||||
const isNewField = !fieldDialog.data;
|
||||
|
||||
if (data.name === "guests" && type !== "multiemail") {
|
||||
showToast(t("guests_field_must_be_multiemail"), "error");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNewField && fields.some((f) => f.name === data.name)) {
|
||||
showToast(t("form_builder_field_already_exists"), "error");
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user