When unchecking the common schedule, schedule should be nulled (#6898)

This commit is contained in:
Alex van Andel 2023-02-06 14:01:54 +00:00 committed by zomars
parent 5719700d2b
commit f7fbfeccbd
4 changed files with 84 additions and 62 deletions

View File

@ -99,18 +99,77 @@ const format = (date: Date, hour12: boolean) =>
new Date(dayjs.utc(date).format("YYYY-MM-DDTHH:mm:ss"))
);
const EventTypeSchedule = () => {
const me = useMeQuery();
const timeFormat = me?.data?.timeFormat;
const EventTypeScheduleDetails = () => {
const { data: loggedInUser } = useMeQuery();
const timeFormat = loggedInUser?.timeFormat;
const { t, i18n } = useLocale();
const { watch } = useFormContext<FormValues>();
const scheduleId = watch("schedule");
const { isLoading, data: schedule } = trpc.viewer.availability.schedule.get.useQuery({ scheduleId });
const { isLoading, data: schedule } = trpc.viewer.availability.schedule.get.useQuery(
{ scheduleId: scheduleId || loggedInUser?.defaultScheduleId || undefined },
{ enabled: !!scheduleId || !!loggedInUser?.defaultScheduleId }
);
const filterDays = (dayNum: number) =>
schedule?.schedule.availability.filter((item) => item.days.includes((dayNum + 1) % 7)) || [];
return (
<div className="space-y-4 rounded border px-6 pb-4">
<ol className="table border-collapse text-sm">
{weekdayNames(i18n.language, 1, "long").map((day, index) => {
const isAvailable = !!filterDays(index).length;
return (
<li key={day} className="my-6 flex border-transparent last:mb-2">
<span
className={classNames(
"w-20 font-medium sm:w-32",
!isAvailable && "text-gray-500 opacity-50"
)}>
{day}
</span>
{isLoading ? (
<SkeletonText className="block h-5 w-60" />
) : isAvailable ? (
<div className="space-y-3 text-right">
{filterDays(index).map((dayRange, i) => (
<div key={i} className="flex items-center leading-4">
<span className="w-16 sm:w-28 sm:text-left">
{format(dayRange.startTime, timeFormat === 12)}
</span>
<span className="ltr:ml-4 rtl:mr-4">-</span>
<div className="ml-6">{format(dayRange.endTime, timeFormat === 12)}</div>
</div>
))}
</div>
) : (
<span className="ml-6 text-gray-500 opacity-50 sm:ml-0">{t("unavailable")}</span>
)}
</li>
);
})}
</ol>
<hr />
<div className="flex flex-col justify-center gap-2 sm:flex-row sm:justify-between">
<span className="flex items-center justify-center text-sm text-gray-600 sm:justify-start">
<FiGlobe className="ltr:mr-2 rtl:ml-2" />
{schedule?.timeZone || <SkeletonText className="block h-5 w-32" />}
</span>
<Button
href={`/availability/${schedule?.schedule.id}`}
color="minimal"
EndIcon={FiExternalLink}
target="_blank"
rel="noopener noreferrer">
{t("edit_availability")}
</Button>
</div>
</div>
);
};
const EventTypeSchedule = () => {
const { t } = useLocale();
return (
<div className="space-y-4">
<div>
@ -131,67 +190,14 @@ const EventTypeSchedule = () => {
)}
/>
</div>
<div className="space-y-4 rounded border px-6 pb-4">
<ol className="table border-collapse text-sm">
{weekdayNames(i18n.language, 1, "long").map((day, index) => {
const isAvailable = !!filterDays(index).length;
return (
<li key={day} className="my-6 flex border-transparent last:mb-2">
<span
className={classNames(
"w-20 font-medium sm:w-32",
!isAvailable && "text-gray-500 opacity-50"
)}>
{day}
</span>
{isLoading ? (
<SkeletonText className="block h-5 w-60" />
) : isAvailable ? (
<div className="space-y-3 text-right">
{filterDays(index).map((dayRange, i) => (
<div key={i} className="flex items-center leading-4">
<span className="w-16 sm:w-28 sm:text-left">
{format(dayRange.startTime, timeFormat === 12)}
</span>
<span className="ltr:ml-4 rtl:mr-4">-</span>
<div className="ml-6">{format(dayRange.endTime, timeFormat === 12)}</div>
</div>
))}
</div>
) : (
<span className="ml-6 text-gray-500 opacity-50 sm:ml-0">{t("unavailable")}</span>
)}
</li>
);
})}
</ol>
<hr />
<div className="flex flex-col justify-center gap-2 sm:flex-row sm:justify-between">
<span className="flex items-center justify-center text-sm text-gray-600 sm:justify-start">
<FiGlobe className="ltr:mr-2 rtl:ml-2" />
{schedule?.timeZone || <SkeletonText className="block h-5 w-32" />}
</span>
<Button
href={`/availability/${schedule?.schedule.id}`}
color="minimal"
EndIcon={FiExternalLink}
target="_blank"
rel="noopener noreferrer">
{t("edit_availability")}
</Button>
</div>
</div>
<EventTypeScheduleDetails />
</div>
);
};
export const AvailabilityTab = ({ isTeamEvent }: { isTeamEvent: boolean }) => {
const UseCommonScheduleSettingsToggle = () => {
const { t } = useLocale();
if (!isTeamEvent) {
return <EventTypeSchedule />;
}
const { resetField, setValue } = useFormContext<FormValues>();
return (
<Controller
name="metadata.config.useHostSchedulesForTeamEvent"
@ -200,6 +206,11 @@ export const AvailabilityTab = ({ isTeamEvent }: { isTeamEvent: boolean }) => {
checked={!value}
onCheckedChange={(checked) => {
onChange(!checked);
if (checked) {
resetField("schedule");
} else {
setValue("schedule", null);
}
}}
title={t("choose_common_schedule_team_event")}
description={t("choose_common_schedule_team_event_description")}>
@ -209,3 +220,7 @@ export const AvailabilityTab = ({ isTeamEvent }: { isTeamEvent: boolean }) => {
/>
);
};
export const AvailabilityTab = ({ isTeamEvent }: { isTeamEvent: boolean }) => {
return isTeamEvent ? <UseCommonScheduleSettingsToggle /> : <EventTypeSchedule />;
};

View File

@ -62,7 +62,7 @@ export type FormValues = {
phone?: string;
}[];
customInputs: CustomInputParsed[];
schedule: number;
schedule: number | null;
periodType: PeriodType;
periodDays: number;
periodCountCalendarDays: "1" | "0";

View File

@ -162,6 +162,7 @@ const loggedInViewerRouter = router({
avatar: user.avatar,
createdDate: user.createdDate,
trialEndsAt: user.trialEndsAt,
defaultScheduleId: user.defaultScheduleId,
completedOnboarding: user.completedOnboarding,
twoFactorEnabled: user.twoFactorEnabled,
disableImpersonation: user.disableImpersonation,

View File

@ -92,7 +92,7 @@ const EventTypeUpdateInput = _EventTypeModel
})
)
.optional(),
schedule: z.number().optional(),
schedule: z.number().nullable().optional(),
hashedLink: z.string(),
})
.partial()
@ -564,6 +564,12 @@ export const eventTypesRouter = router({
};
}
}
// allows unsetting a schedule through { schedule: null, ... }
else if (null === schedule) {
data.schedule = {
disconnect: true,
};
}
if (users) {
data.users = {