feat: add callback for handleFormSubmit in EventType and AvailabilitySettings atoms (#22911)
* feat: Implement callback pattern in handleFormSubmit of EventTypePlatformWrapper * feat: Implement callback pattern in handleFormSubmit of AvailabilitySettingsPlatformWrapper * docs: add handleFormSubmit callback documentation for EventType and AvailabilitySettings atoms * Update availability.tsx * chore:added changelog * update docs --------- Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
This commit is contained in:
co-authored by
Rajiv Sahal
parent
cfda4757e4
commit
d3fbc73a39
@@ -0,0 +1,9 @@
|
||||
---
|
||||
"@calcom/atoms": minor
|
||||
---
|
||||
|
||||
Added new callback functions to the handleFormSubmit method in the EventTypeSettings and AvailabilitySettings atoms. The handleFormSubmit method now accepts an optional callbacks object with the following properties:
|
||||
|
||||
- **onSuccess**: Called when the form submission is successful, allowing additional logic to be executed after the update.
|
||||
|
||||
- **onError**: Called when an error occurs during form submission, providing details about the error to handle specific cases or display custom messages.
|
||||
@@ -156,7 +156,16 @@ export function AvailabilityWithValidation() {
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
availabilityRef.current?.handleFormSubmit();
|
||||
availabilityRef.current?.handleFormSubmit({
|
||||
onSuccess: () => {
|
||||
// Additional success handling logic here
|
||||
console.log('Availability updated successfully');
|
||||
},
|
||||
onError: (error) => {
|
||||
// Additional error handling logic here
|
||||
console.error('Error updating availability:', error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -184,6 +193,20 @@ export function AvailabilityWithValidation() {
|
||||
| validateForm | Validates the current availability form state and returns a promise with validation results. |
|
||||
| handleFormSubmit | Programmatically submits the availability form, triggering the same validation and submission flow as clicking the save button. Unlike `validateForm`, this method will check required fields and prevent submission unless all required fields are set |
|
||||
|
||||
### Callbacks
|
||||
|
||||
The `handleFormSubmit` method accepts an optional callbacks object with the following properties:
|
||||
|
||||
```typescript
|
||||
type AvailabilitySettingsFormCallbacks = {
|
||||
onSuccess?: () => void;
|
||||
onError?: (error: Error) => void;
|
||||
};
|
||||
```
|
||||
|
||||
- **onSuccess**: Called when the form submission is successful. This allows you to execute additional logic after a successful update.
|
||||
- **onError**: Called when an error occurs during form submission. The error parameter contains details about what went wrong, allowing you to handle specific error cases or display custom error messages.
|
||||
|
||||
The `validateForm` method returns an `AvailabilityFormValidationResult` object with:
|
||||
- `isValid`: Boolean indicating if the form passed validation
|
||||
- `errors`: Object containing any validation errors found
|
||||
|
||||
@@ -218,7 +218,16 @@ export function EventTypeWithValidation(eventTypeId: number) {
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
eventTypeRef.current?.handleFormSubmit();
|
||||
eventTypeRef.current?.handleFormSubmit({
|
||||
onSuccess: () => {
|
||||
// Additional success handling logic here
|
||||
console.log('Event type updated successfully');
|
||||
},
|
||||
onError: (error) => {
|
||||
// Additional error handling logic here
|
||||
console.error('Error updating event type:', error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -244,6 +253,20 @@ export function EventTypeWithValidation(eventTypeId: number) {
|
||||
| validateForm | Validates the current event type form state and returns a promise with validation results. |
|
||||
| handleFormSubmit | Programmatically submits the event type form, triggering the same validation and submission flow as clicking the save button. Unlike `validateForm`, this method will check required fields and prevent submission unless all required fields are set |
|
||||
|
||||
### Callbacks
|
||||
|
||||
The `handleFormSubmit` method accepts an optional callbacks object with the following properties:
|
||||
|
||||
```typescript
|
||||
type EventTypeFormCallbacks = {
|
||||
onSuccess?: () => void;
|
||||
onError?: (error: Error) => void;
|
||||
};
|
||||
```
|
||||
|
||||
- **onSuccess**: Called when the form submission is successful. This allows you to execute additional logic after a successful update.
|
||||
- **onError**: Called when an error occurs during form submission. The error parameter contains details about what went wrong, allowing you to handle specific error cases or display custom error messages.
|
||||
|
||||
The `validateForm` method returns an `EventTypeFormValidationResult` object with:
|
||||
- `isValid`: Boolean indicating if the form passed validation
|
||||
- `errors`: Object containing any validation errors found
|
||||
|
||||
@@ -236,5 +236,5 @@ export type FormValidationResult = {
|
||||
|
||||
export interface EventTypePlatformWrapperRef {
|
||||
validateForm: () => Promise<FormValidationResult>;
|
||||
handleFormSubmit: () => void;
|
||||
handleFormSubmit: (callbacks?: { onSuccess?: () => void; onError?: (error: Error) => void }) => void;
|
||||
}
|
||||
|
||||
@@ -316,11 +316,24 @@ export const AvailabilitySettings = forwardRef<AvailabilitySettingsFormRef, Avai
|
||||
|
||||
const saveButtonRef = useRef<HTMLButtonElement>(null);
|
||||
|
||||
const handleFormSubmit = useCallback(() => {
|
||||
const callbacksRef = useRef<{ onSuccess?: () => void; onError?: (error: Error) => void }>({});
|
||||
|
||||
const handleFormSubmit = useCallback((customCallbacks?: { onSuccess?: () => void; onError?: (error: Error) => void }) => {
|
||||
if (customCallbacks) {
|
||||
callbacksRef.current = customCallbacks;
|
||||
}
|
||||
|
||||
if (saveButtonRef.current) {
|
||||
saveButtonRef.current.click();
|
||||
} else {
|
||||
form.handleSubmit(handleSubmit)();
|
||||
form.handleSubmit(async (data) => {
|
||||
try {
|
||||
await handleSubmit(data);
|
||||
callbacksRef.current?.onSuccess?.();
|
||||
} catch (error) {
|
||||
callbacksRef.current?.onError?.(error as Error);
|
||||
}
|
||||
})();
|
||||
}
|
||||
}, [form, handleSubmit]);
|
||||
|
||||
|
||||
@@ -35,7 +35,12 @@ export type AvailabilityFormValidationResult = {
|
||||
errors: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export interface AvailabilitySettingsFormCallbacks {
|
||||
onSuccess?: () => void;
|
||||
onError?: (error: Error) => void;
|
||||
}
|
||||
|
||||
export interface AvailabilitySettingsFormRef {
|
||||
validateForm: () => Promise<AvailabilityFormValidationResult>;
|
||||
handleFormSubmit: () => void;
|
||||
handleFormSubmit: (callbacks?: AvailabilitySettingsFormCallbacks) => void;
|
||||
}
|
||||
|
||||
+8
-4
@@ -1,5 +1,5 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { forwardRef } from "react";
|
||||
import { forwardRef, useRef } from "react";
|
||||
|
||||
import type { ScheduleLabelsType } from "@calcom/features/schedules/components/Schedule";
|
||||
import type { UpdateScheduleResponse } from "@calcom/lib/schedules/updateSchedule";
|
||||
@@ -12,9 +12,9 @@ import { useMe } from "../../hooks/useMe";
|
||||
import { AtomsWrapper } from "../../src/components/atoms-wrapper";
|
||||
import { useToast } from "../../src/components/ui/use-toast";
|
||||
import type { Availability } from "../AvailabilitySettings";
|
||||
import type { CustomClassNames, AvailabilitySettingsFormRef } from "../AvailabilitySettings";
|
||||
import type { CustomClassNames } from "../AvailabilitySettings";
|
||||
import { AvailabilitySettings } from "../AvailabilitySettings";
|
||||
import type { AvailabilityFormValues } from "../types";
|
||||
import type { AvailabilityFormValues, AvailabilitySettingsFormRef } from "../types";
|
||||
|
||||
export type AvailabilitySettingsPlatformWrapperProps = {
|
||||
id?: string;
|
||||
@@ -39,7 +39,7 @@ export type AvailabilitySettingsPlatformWrapperProps = {
|
||||
};
|
||||
|
||||
export const AvailabilitySettingsPlatformWrapper = forwardRef<
|
||||
AvailabilitySettingsFormRef,
|
||||
AvailabilitySettingsFormRef,
|
||||
AvailabilitySettingsPlatformWrapperProps
|
||||
>(function AvailabilitySettingsPlatformWrapper(props, ref) {
|
||||
const {
|
||||
@@ -84,6 +84,8 @@ export const AvailabilitySettingsPlatformWrapper = forwardRef<
|
||||
},
|
||||
});
|
||||
|
||||
const callbacksRef = useRef<{ onSuccess?: () => void; onError?: (error: Error) => void }>({});
|
||||
|
||||
const { mutate: updateSchedule, isPending: isSavingInProgress } = useAtomUpdateSchedule({
|
||||
onSuccess: (res) => {
|
||||
onUpdateSuccess?.(res);
|
||||
@@ -92,6 +94,7 @@ export const AvailabilitySettingsPlatformWrapper = forwardRef<
|
||||
description: "Schedule updated successfully",
|
||||
});
|
||||
}
|
||||
callbacksRef.current?.onSuccess?.();
|
||||
},
|
||||
onError: (err) => {
|
||||
onUpdateError?.(err);
|
||||
@@ -100,6 +103,7 @@ export const AvailabilitySettingsPlatformWrapper = forwardRef<
|
||||
description: "Could not update schedule",
|
||||
});
|
||||
}
|
||||
callbacksRef.current?.onError?.(err);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -139,6 +139,7 @@ const EventType = forwardRef<
|
||||
form.reset(currentValues);
|
||||
toast({ description: t("event_type_updated_successfully", { eventTypeTitle: eventType.title }) });
|
||||
onSuccess?.(currentValues);
|
||||
callbacksRef.current?.onSuccess?.();
|
||||
},
|
||||
async onSettled() {
|
||||
return;
|
||||
@@ -146,8 +147,12 @@ const EventType = forwardRef<
|
||||
onError: (err: Error) => {
|
||||
const currentValues = form.getValues();
|
||||
const message = err?.message;
|
||||
toast({ description: message ? t(message) : t(err.message) });
|
||||
const description = message ? t(message) : t(err.message);
|
||||
toast({ description });
|
||||
onError?.(currentValues, err);
|
||||
|
||||
const errorObj = new Error(description);
|
||||
callbacksRef.current?.onError?.(errorObj);
|
||||
},
|
||||
teamId: team?.id,
|
||||
});
|
||||
@@ -159,6 +164,7 @@ const EventType = forwardRef<
|
||||
updateMutation.mutate(data);
|
||||
} else {
|
||||
toast({ description: t("event_type_updated_successfully", { eventTypeTitle: eventType.title }) });
|
||||
callbacksRef.current?.onSuccess?.();
|
||||
}
|
||||
},
|
||||
onFormStateChange: onFormStateChange,
|
||||
@@ -167,11 +173,24 @@ const EventType = forwardRef<
|
||||
// Create a ref for the save button to trigger its click
|
||||
const saveButtonRef = useRef<HTMLButtonElement>(null);
|
||||
|
||||
const handleFormSubmit = useCallback(() => {
|
||||
const callbacksRef = useRef<{ onSuccess?: () => void; onError?: (error: Error) => void }>({});
|
||||
|
||||
const handleFormSubmit = useCallback((customCallbacks?: { onSuccess?: () => void; onError?: (error: Error) => void }) => {
|
||||
if (customCallbacks) {
|
||||
callbacksRef.current = customCallbacks;
|
||||
}
|
||||
|
||||
if (saveButtonRef.current) {
|
||||
saveButtonRef.current.click();
|
||||
} else {
|
||||
form.handleSubmit(handleSubmit)();
|
||||
form.handleSubmit((data) => {
|
||||
try {
|
||||
handleSubmit(data);
|
||||
customCallbacks?.onSuccess?.();
|
||||
} catch (error) {
|
||||
customCallbacks?.onError?.(error as Error);
|
||||
}
|
||||
})();
|
||||
}
|
||||
}, [handleSubmit, form]);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Navbar } from "@/components/Navbar";
|
||||
import { Inter } from "next/font/google";
|
||||
import { useRef, useCallback } from "react";
|
||||
import { useRef, useCallback, useState } from "react";
|
||||
|
||||
import type { AvailabilitySettingsFormRef } from "@calcom/atoms";
|
||||
import { AvailabilitySettings } from "@calcom/atoms";
|
||||
@@ -20,7 +20,14 @@ export default function Availability(props: { calUsername: string; calEmail: str
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
availabilityRef.current?.handleFormSubmit();
|
||||
availabilityRef.current?.handleFormSubmit({
|
||||
onSuccess: () => {
|
||||
console.log("Form submitted successfully");
|
||||
},
|
||||
onError: (error) => {
|
||||
console.error("Form submission failed:", error);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -29,7 +36,7 @@ export default function Availability(props: { calUsername: string; calEmail: str
|
||||
<div>
|
||||
<h1 className="mx-10 my-4 text-2xl font-semibold">Availability Settings</h1>
|
||||
|
||||
<div className="mx-10 mb-4 flex gap-4">
|
||||
<div className="mx-10 mb-4 flex flex-col gap-4">
|
||||
<button
|
||||
onClick={handleValidate}
|
||||
className="rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50">
|
||||
|
||||
@@ -31,7 +31,16 @@ export default function Bookings(props: { calUsername: string; calEmail: string
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
eventTypeRef.current?.handleFormSubmit();
|
||||
eventTypeRef.current?.handleFormSubmit({
|
||||
onSuccess: () => {
|
||||
console.log('Event type updated successfully');
|
||||
// Additional success handling logic here
|
||||
},
|
||||
onError: (error) => {
|
||||
console.error('Error updating event type:', error);
|
||||
// Additional error handling logic here
|
||||
}
|
||||
});
|
||||
};
|
||||
const { isLoading: isLoadingEvents, data: eventTypes, refetch } = useEventTypes(props.calUsername);
|
||||
const { data: teams } = useTeams();
|
||||
|
||||
Reference in New Issue
Block a user