feat: autosave availability after making changes (#14849)

* feat: availability after making changes

* update

* update

* Update Schedule.tsx

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
This commit is contained in:
Anik Dhabal Babu
2024-05-27 14:25:29 +00:00
committed by GitHub
co-authored by Peer Richelsen
parent d2bec46d89
commit be7d45afe2
2 changed files with 59 additions and 5 deletions
@@ -12,6 +12,7 @@ import type {
import { Controller, useFieldArray, useFormContext } from "react-hook-form";
import type { GroupBase, Props } from "react-select";
import type { AvailabilityFormValues } from "@calcom/atoms/availability/types";
import type { ConfigType } from "@calcom/dayjs";
import dayjs from "@calcom/dayjs";
import { defaultDayRange as DEFAULT_DAY_RANGE } from "@calcom/lib/availability";
@@ -47,6 +48,7 @@ export const ScheduleDay = <TFieldValues extends FieldValues>({
name,
weekday,
control,
handleSubmit,
CopyButton,
disabled,
labels,
@@ -56,6 +58,7 @@ export const ScheduleDay = <TFieldValues extends FieldValues>({
name: ArrayPath<TFieldValues>;
weekday: string;
control: Control<TFieldValues>;
handleSubmit?: (data: AvailabilityFormValues) => Promise<void>;
CopyButton: JSX.Element;
disabled?: boolean;
labels?: ScheduleLabelsType;
@@ -68,7 +71,7 @@ export const ScheduleDay = <TFieldValues extends FieldValues>({
scheduleContainer?: string;
};
}) => {
const { watch, setValue } = useFormContext();
const { watch, setValue, getValues } = useFormContext();
const watchDayRange = watch(name);
return (
@@ -94,6 +97,7 @@ export const ScheduleDay = <TFieldValues extends FieldValues>({
data-testid={`${weekday}-switch`}
onCheckedChange={(isChecked) => {
setValue(name, (isChecked ? [DEFAULT_DAY_RANGE] : []) as TFieldValues[typeof name]);
handleSubmit && handleSubmit(getValues() as AvailabilityFormValues);
}}
/>
</div>
@@ -111,6 +115,7 @@ export const ScheduleDay = <TFieldValues extends FieldValues>({
control={control}
name={name}
disabled={disabled}
handleSubmit={handleSubmit}
className={{
dayRanges: className?.dayRanges,
timeRangeField: className?.timeRangeField,
@@ -128,10 +133,12 @@ const CopyButton = ({
getValuesFromDayRange,
weekStart,
labels,
handleSubmit,
}: {
getValuesFromDayRange: string;
weekStart: number;
labels?: ScheduleLabelsType;
handleSubmit?: (data: AvailabilityFormValues) => Promise<void>;
}) => {
const { t } = useLocale();
const [open, setOpen] = useState(false);
@@ -160,6 +167,7 @@ const CopyButton = ({
onClick={(selected) => {
selected.forEach((day) => setValue(`${fieldArrayName}.${day}`, getValues(getValuesFromDayRange)));
setOpen(false);
handleSubmit && handleSubmit(getValues() as AvailabilityFormValues);
}}
onCancel={() => setOpen(false)}
/>
@@ -176,6 +184,7 @@ const Schedule = <
control: Control<TFieldValues>;
weekStart?: number;
disabled?: boolean;
handleSubmit?: (data: AvailabilityFormValues) => Promise<void>;
labels?: ScheduleLabelsType;
userTimeFormat?: number | null;
}) => {
@@ -191,6 +200,7 @@ export const ScheduleComponent = <
>({
name,
control,
handleSubmit,
disabled,
weekStart = 0,
labels,
@@ -199,6 +209,7 @@ export const ScheduleComponent = <
}: {
name: TPath;
control: Control<TFieldValues>;
handleSubmit?: (data: AvailabilityFormValues) => Promise<void>;
weekStart?: number;
disabled?: boolean;
labels?: ScheduleLabelsType;
@@ -234,8 +245,14 @@ export const ScheduleComponent = <
key={weekday}
weekday={weekday}
control={control}
handleSubmit={handleSubmit}
CopyButton={
<CopyButton weekStart={weekStart} labels={labels} getValuesFromDayRange={dayRangeName} />
<CopyButton
weekStart={weekStart}
labels={labels}
getValuesFromDayRange={dayRangeName}
handleSubmit={handleSubmit}
/>
}
/>
);
@@ -251,6 +268,7 @@ export const DayRanges = <TFieldValues extends FieldValues>({
labels,
userTimeFormat,
className,
handleSubmit,
}: {
name: ArrayPath<TFieldValues>;
control?: Control<TFieldValues>;
@@ -261,6 +279,7 @@ export const DayRanges = <TFieldValues extends FieldValues>({
dayRanges?: string;
timeRangeField?: string;
};
handleSubmit?: (data: AvailabilityFormValues) => Promise<void>;
}) => {
const { t } = useLocale();
const { getValues } = useFormContext();
@@ -283,6 +302,7 @@ export const DayRanges = <TFieldValues extends FieldValues>({
<TimeRangeField
className={className?.timeRangeField}
userTimeFormat={userTimeFormat}
handleSubmit={handleSubmit}
{...field}
/>
)}
@@ -306,16 +326,23 @@ export const DayRanges = <TFieldValues extends FieldValues>({
if (slotRange?.append) {
append(slotRange.append);
handleSubmit && handleSubmit(getValues() as AvailabilityFormValues);
}
if (slotRange?.prepend) {
prepend(slotRange.prepend);
handleSubmit && handleSubmit(getValues() as AvailabilityFormValues);
}
}}
/>
)}
{index !== 0 && (
<RemoveTimeButton index={index} remove={remove} className="text-default border-none" />
<RemoveTimeButton
index={index}
remove={remove}
handleSubmit={handleSubmit}
className="text-default mx-2 border-none"
/>
)}
</div>
</Fragment>
@@ -330,14 +357,17 @@ const RemoveTimeButton = ({
disabled,
className,
labels,
handleSubmit,
}: {
index: number | number[];
remove: UseFieldArrayRemove;
className?: string;
disabled?: boolean;
labels?: ScheduleLabelsType;
handleSubmit?: (data: AvailabilityFormValues) => Promise<void>;
}) => {
const { t } = useLocale();
const { getValues } = useFormContext();
return (
<Button
disabled={disabled}
@@ -345,7 +375,10 @@ const RemoveTimeButton = ({
variant="icon"
color="destructive"
StartIcon="trash"
onClick={() => remove(index)}
onClick={() => {
remove(index);
handleSubmit && handleSubmit(getValues() as AvailabilityFormValues);
}}
className={className}
tooltip={labels?.deleteTime ?? t("delete")}
/>
@@ -358,11 +391,14 @@ const TimeRangeField = ({
onChange,
disabled,
userTimeFormat,
handleSubmit,
}: {
className?: string;
disabled?: boolean;
userTimeFormat: number | null;
handleSubmit?: (data: AvailabilityFormValues) => Promise<void>;
} & ControllerRenderProps) => {
const { getValues } = useFormContext();
// this is a controlled component anyway given it uses LazySelect, so keep it RHF agnostic.
return (
<div className={classNames("flex flex-row gap-2 sm:gap-3", className)}>
@@ -375,6 +411,7 @@ const TimeRangeField = ({
max={value.end}
onChange={(option) => {
onChange({ ...value, start: new Date(option?.value as number) });
handleSubmit && handleSubmit(getValues() as AvailabilityFormValues);
}}
/>
<span className="text-default w-2 self-center"> - </span>
@@ -387,6 +424,7 @@ const TimeRangeField = ({
menuPlacement="bottom"
onChange={(option) => {
onChange({ ...value, end: new Date(option?.value as number) });
handleSubmit && handleSubmit(getValues() as AvailabilityFormValues);
}}
/>
</div>
@@ -1,4 +1,4 @@
import { useMemo, useState } from "react";
import { useMemo, useState, useEffect } from "react";
import { Controller, useFieldArray, useForm, useWatch } from "react-hook-form";
import dayjs from "@calcom/dayjs";
@@ -243,6 +243,21 @@ export function AvailabilitySettings({
},
});
useEffect(() => {
const subscription = form.watch(
(value, { name }) => {
console.log(name);
if (!!name && name.split(".")[0] !== "schedule" && name !== "name")
handleSubmit(value as AvailabilityFormValues);
},
{
...schedule,
schedule: schedule.availability || [],
}
);
return () => subscription.unsubscribe();
}, [form.watch]);
const [Shell, Schedule, TimezoneSelect] = useMemo(() => {
return isPlatform
? [PlatformShell, PlatformSchedule, PlatformTimzoneSelect]
@@ -478,6 +493,7 @@ export function AvailabilitySettings({
control={form.control}
name="schedule"
userTimeFormat={timeFormat}
handleSubmit={handleSubmit}
weekStart={
["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"].indexOf(
weekStart