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:
co-authored by
Peer Richelsen
parent
d2bec46d89
commit
be7d45afe2
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user