Skip to content

Commit d2d7453

Browse files
RyukemeisterRajiv SahalsupalarryThyMinimalDev
authored
feat: add date overrides to availability settings atom (#15459)
* remove console.log * fixup: logic to convert overrides was not calling functions * refactor handleSubmit function * add portal to platform dialog component * cleanup * add props to enable and disable date overrides * show date overrides for availability settings atom * fix: date overrides formatting for api request --------- Co-authored-by: Rajiv Sahal <rajivsahal@Rajivs-MacBook-Pro.local> Co-authored-by: supalarry <laurisskraucis@gmail.com> Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
1 parent 87d2ec9 commit d2d7453

File tree

7 files changed

+74
-50
lines changed

7 files changed

+74
-50
lines changed

packages/features/schedules/components/DateOverrideInputDialog.tsx

+11-13
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,18 @@ const DateOverrideForm = ({
108108
<Form
109109
form={form}
110110
handleSubmit={(values) => {
111-
if (selectedDates.length === 0) return;
112-
113111
const datesInRanges: TimeRange[] = [];
114112

115-
if (!datesUnavailable) {
113+
if (selectedDates.length === 0) return;
114+
115+
if (datesUnavailable) {
116+
selectedDates.map((date) => {
117+
datesInRanges.push({
118+
start: date.utc(true).startOf("day").toDate(),
119+
end: date.utc(true).startOf("day").toDate(),
120+
});
121+
});
122+
} else {
116123
selectedDates.map((date) => {
117124
values.range.map((item) => {
118125
datesInRanges.push({
@@ -127,16 +134,7 @@ const DateOverrideForm = ({
127134
});
128135
}
129136

130-
onChange(
131-
datesUnavailable
132-
? selectedDates.map((date) => {
133-
return {
134-
start: date.utc(true).startOf("day").toDate(),
135-
end: date.utc(true).startOf("day").toDate(),
136-
};
137-
})
138-
: datesInRanges
139-
);
137+
onChange(datesInRanges);
140138
setSelectedDates([]);
141139
}}
142140
className="p-6 sm:flex sm:p-0 xl:flex-row">

packages/platform/atoms/availability/AvailabilitySettings.tsx

+13-18
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ type AvailabilitySettingsProps = {
8989
isPlatform?: boolean;
9090
customClassNames?: CustomClassNames;
9191
disableEditableHeading?: boolean;
92+
enableOverrides?: boolean;
9293
};
9394

9495
const DeleteDialogButton = ({
@@ -234,6 +235,7 @@ export function AvailabilitySettings({
234235
isPlatform = false,
235236
customClassNames,
236237
disableEditableHeading = false,
238+
enableOverrides = false,
237239
}: AvailabilitySettingsProps) {
238240
const [openSidebar, setOpenSidebar] = useState(false);
239241
const { t, i18n } = useLocale();
@@ -248,7 +250,6 @@ export function AvailabilitySettings({
248250
useEffect(() => {
249251
const subscription = form.watch(
250252
(value, { name }) => {
251-
console.log(name);
252253
if (!!name && name.split(".")[0] !== "schedule" && name !== "name")
253254
handleSubmit(value as AvailabilityFormValues);
254255
},
@@ -507,23 +508,17 @@ export function AvailabilitySettings({
507508
)}
508509
</div>
509510
</div>
510-
{!isPlatform ? (
511-
<div className="border-subtle my-6 rounded-md border">
512-
{schedule?.workingHours && (
513-
<DateOverride
514-
workingHours={schedule.workingHours}
515-
userTimeFormat={timeFormat}
516-
travelSchedules={travelSchedules}
517-
weekStart={
518-
["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"].indexOf(
519-
weekStart
520-
) as 0 | 1 | 2 | 3 | 4 | 5 | 6
521-
}
522-
/>
523-
)}
524-
</div>
525-
) : (
526-
<></>
511+
{enableOverrides && (
512+
<DateOverride
513+
workingHours={schedule.workingHours}
514+
userTimeFormat={timeFormat}
515+
travelSchedules={travelSchedules}
516+
weekStart={
517+
["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"].indexOf(
518+
weekStart
519+
) as 0 | 1 | 2 | 3 | 4 | 5 | 6
520+
}
521+
/>
527522
)}
528523
</div>
529524
<div className="min-w-40 col-span-3 hidden space-y-2 md:block lg:col-span-1">

packages/platform/atoms/availability/atom-api-transformers/transformAtomScheduleForApi.ts

+27-5
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,40 @@ export function transformAtomScheduleForApi(body: AvailabilityFormValues): Updat
1212
const overrides =
1313
dateOverrides.flatMap(
1414
(dateOverridesRanges) =>
15-
dateOverridesRanges?.ranges?.map((range) => ({
16-
date: `${range.start.getUTCFullYear}-${range.start.getUTCMonth}-${range.start.getUTCDate}`,
17-
startTime: `${range.start.getUTCHours}-${range.start.getUTCMinutes}`,
18-
endTime: `${range.end.getUTCHours}-${range.end.getUTCMinutes}`,
19-
})) ?? []
15+
dateOverridesRanges?.ranges?.map((range) => transfromAtomOverrideForApi(range)) ?? []
2016
) ?? [];
2117

2218
const availability = formatScheduleTime(schedule);
2319

2420
return { name, timeZone, isDefault, availability, overrides };
2521
}
2622

23+
type AtomDateOverride = {
24+
start: Date;
25+
end: Date;
26+
};
27+
28+
function transfromAtomOverrideForApi(override: AtomDateOverride) {
29+
const date = `${override.start.getUTCFullYear()}-${(override.start.getUTCMonth() + 1)
30+
.toString()
31+
.padStart(2, "0")}-${override.start.getUTCDate().toString().padStart(2, "0")}`;
32+
33+
return {
34+
date,
35+
startTime: padHoursMinutesWithZeros(`${override.start.getUTCHours()}:${override.start.getUTCMinutes()}`),
36+
endTime: padHoursMinutesWithZeros(`${override.end.getUTCHours()}:${override.end.getUTCMinutes()}`),
37+
};
38+
}
39+
40+
function padHoursMinutesWithZeros(hhMM: string) {
41+
const [hours, minutes] = hhMM.split(":");
42+
43+
const formattedHours = hours.padStart(2, "0");
44+
const formattedMinutes = minutes.padStart(2, "0");
45+
46+
return `${formattedHours}:${formattedMinutes}`;
47+
}
48+
2749
function formatScheduleTime(
2850
weekSchedule: AvailabilityFormValues["schedule"]
2951
): UpdateScheduleInput_2024_06_11["availability"] {

packages/platform/atoms/availability/wrappers/AvailabilitySettingsPlatformWrapper.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type AvailabilitySettingsPlatformWrapperProps = {
2626
onDeleteSuccess?: (res: ApiResponse) => void;
2727
onDeleteError?: (err: ApiErrorResponse) => void;
2828
disableEditableHeading?: boolean;
29+
enableOverrides?: boolean;
2930
};
3031

3132
export const AvailabilitySettingsPlatformWrapper = ({
@@ -36,6 +37,7 @@ export const AvailabilitySettingsPlatformWrapper = ({
3637
onUpdateError,
3738
onUpdateSuccess,
3839
disableEditableHeading = false,
40+
enableOverrides = false,
3941
}: AvailabilitySettingsPlatformWrapperProps) => {
4042
const { isLoading, data: schedule } = useSchedule(id);
4143
const { data: schedules } = useSchedules();
@@ -99,6 +101,7 @@ export const AvailabilitySettingsPlatformWrapper = ({
99101
}}
100102
weekStart="Sunday"
101103
timeFormat={timeFormat}
104+
enableOverrides={enableOverrides}
102105
isLoading={isLoading}
103106
schedule={{
104107
name: atomSchedule.name,

packages/platform/atoms/availability/wrappers/AvailabilitySettingsWebWrapper.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ export const AvailabilitySettingsWebWrapper = () => {
8686
isDeleting={deleteMutation.isPending}
8787
isLoading={isPending}
8888
isSaving={updateMutation.isPending}
89+
enableOverrides={true}
8990
timeFormat={timeFormat}
9091
weekStart={me.data?.weekStart || "Sunday"}
9192
backPath={fromEventType ? true : "/availability"}

packages/platform/atoms/src/components/ui/dialog.tsx

+18-14
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,24 @@ const DialogContent = React.forwardRef<
3333
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
3434
>(({ className, children, ...props }, ref) => (
3535
<>
36-
<DialogOverlay />
37-
<DialogPrimitive.Content
38-
ref={ref}
39-
className={cn(
40-
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg",
41-
className
42-
)}
43-
{...props}>
44-
{children}
45-
<DialogPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none">
46-
<Icon name="x" className="h-4 w-4" />
47-
<span className="sr-only">Close</span>
48-
</DialogPrimitive.Close>
49-
</DialogPrimitive.Content>
36+
<DialogPortal>
37+
<div className="calcom-atoms">
38+
<DialogOverlay />
39+
<DialogPrimitive.Content
40+
ref={ref}
41+
className={cn(
42+
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg",
43+
className
44+
)}
45+
{...props}>
46+
{children}
47+
<DialogPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none">
48+
<Icon name="x" className="h-4 w-4" />
49+
<span className="sr-only">Close</span>
50+
</DialogPrimitive.Close>
51+
</DialogPrimitive.Content>
52+
</div>
53+
</DialogPortal>
5054
</>
5155
));
5256
DialogContent.displayName = DialogPrimitive.Content.displayName;

packages/platform/examples/base/src/pages/availability.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export default function Availability(props: { calUsername: string; calEmail: str
1111
<Navbar username={props.calUsername} />
1212
<div>
1313
<AvailabilitySettings
14+
enableOverrides={true}
1415
customClassNames={{
1516
subtitlesClassName: "text-red-500",
1617
ctaClassName: "border p-4 rounded-md",

0 commit comments

Comments
 (0)