Skip to content

Commit

Permalink
feat: autosave availability after making changes (calcom#14849)
Browse files Browse the repository at this point in the history
* feat: availability after making changes

* update

* update

* Update Schedule.tsx

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
  • Loading branch information
anikdhabal and PeerRich authored May 27, 2024
1 parent d2bec46 commit be7d45a
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 5 deletions.
46 changes: 42 additions & 4 deletions packages/features/schedules/components/Schedule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -47,6 +48,7 @@ export const ScheduleDay = <TFieldValues extends FieldValues>({
name,
weekday,
control,
handleSubmit,
CopyButton,
disabled,
labels,
Expand All @@ -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;
Expand All @@ -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 (
Expand All @@ -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>
Expand All @@ -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,
Expand All @@ -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);
Expand Down Expand Up @@ -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)}
/>
Expand All @@ -176,6 +184,7 @@ const Schedule = <
control: Control<TFieldValues>;
weekStart?: number;
disabled?: boolean;
handleSubmit?: (data: AvailabilityFormValues) => Promise<void>;
labels?: ScheduleLabelsType;
userTimeFormat?: number | null;
}) => {
Expand All @@ -191,6 +200,7 @@ export const ScheduleComponent = <
>({
name,
control,
handleSubmit,
disabled,
weekStart = 0,
labels,
Expand All @@ -199,6 +209,7 @@ export const ScheduleComponent = <
}: {
name: TPath;
control: Control<TFieldValues>;
handleSubmit?: (data: AvailabilityFormValues) => Promise<void>;
weekStart?: number;
disabled?: boolean;
labels?: ScheduleLabelsType;
Expand Down Expand Up @@ -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}
/>
}
/>
);
Expand All @@ -251,6 +268,7 @@ export const DayRanges = <TFieldValues extends FieldValues>({
labels,
userTimeFormat,
className,
handleSubmit,
}: {
name: ArrayPath<TFieldValues>;
control?: Control<TFieldValues>;
Expand All @@ -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();
Expand All @@ -283,6 +302,7 @@ export const DayRanges = <TFieldValues extends FieldValues>({
<TimeRangeField
className={className?.timeRangeField}
userTimeFormat={userTimeFormat}
handleSubmit={handleSubmit}
{...field}
/>
)}
Expand All @@ -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>
Expand All @@ -330,22 +357,28 @@ 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}
type="button"
variant="icon"
color="destructive"
StartIcon="trash"
onClick={() => remove(index)}
onClick={() => {
remove(index);
handleSubmit && handleSubmit(getValues() as AvailabilityFormValues);
}}
className={className}
tooltip={labels?.deleteTime ?? t("delete")}
/>
Expand All @@ -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)}>
Expand All @@ -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>
Expand All @@ -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>
Expand Down
18 changes: 17 additions & 1 deletion packages/platform/atoms/availability/AvailabilitySettings.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit be7d45a

Please sign in to comment.