2
0

first commit

This commit is contained in:
2024-08-09 00:39:27 +02:00
commit 79688abe2e
5698 changed files with 497838 additions and 0 deletions

View File

@@ -0,0 +1,152 @@
import type { ScheduleOutput_2024_06_11 } from "@calcom/platform-types";
import type { User } from "@calcom/prisma/client";
import { transformApiScheduleForAtom } from "./transformApiScheduleForAtom";
const SCHEDULE_OWNER_ID = 256;
describe("transformScheduleForAtom", () => {
const user: Pick<User, "id" | "defaultScheduleId" | "timeZone"> = {
id: SCHEDULE_OWNER_ID,
defaultScheduleId: 139,
timeZone: "America/New_York",
};
beforeEach(() => {
jest.resetAllMocks();
});
it("should return null if user is not provided", () => {
const schedule: ScheduleOutput_2024_06_11 | null = {
id: 139,
ownerId: SCHEDULE_OWNER_ID,
name: "Default",
timeZone: "America/Cancun",
availability: [
{
days: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
startTime: "09:00",
endTime: "17:00",
},
],
isDefault: true,
overrides: [],
};
expect(transformApiScheduleForAtom(undefined, schedule, 1)).toBeNull();
});
it("should return null if schedule is not provided", () => {
expect(transformApiScheduleForAtom(user, null, 1)).toBeNull();
});
it("should transform schedule correctly", () => {
const schedule: ScheduleOutput_2024_06_11 = {
id: 139,
ownerId: SCHEDULE_OWNER_ID,
name: "Default",
timeZone: "America/Cancun",
availability: [
{
days: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
startTime: "09:00",
endTime: "17:00",
},
],
isDefault: true,
overrides: [],
};
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const expectedResult = {
id: 139,
name: "Default",
isManaged: false,
workingHours: [
{
days: [1, 2, 3, 4, 5],
startTime: 540,
endTime: 1020,
userId: 256,
},
],
schedule: [
{
userId: 256,
scheduleId: 139,
days: [1, 2, 3, 4, 5],
startTime: new Date(Date.UTC(1970, 0, 1, 9, 0)),
endTime: new Date(Date.UTC(1970, 0, 1, 17, 0)),
date: null,
},
],
availability: [
[],
[
{
start: new Date(
`${year}-${month.toString().padStart(2, "0")}-${day.toString().padStart(2, "0")}T09:00:00.000Z`
),
end: new Date(
`${year}-${month.toString().padStart(2, "0")}-${day.toString().padStart(2, "0")}T17:00:00.000Z`
),
},
],
[
{
start: new Date(
`${year}-${month.toString().padStart(2, "0")}-${day.toString().padStart(2, "0")}T09:00:00.000Z`
),
end: new Date(
`${year}-${month.toString().padStart(2, "0")}-${day.toString().padStart(2, "0")}T17:00:00.000Z`
),
},
],
[
{
start: new Date(
`${year}-${month.toString().padStart(2, "0")}-${day.toString().padStart(2, "0")}T09:00:00.000Z`
),
end: new Date(
`${year}-${month.toString().padStart(2, "0")}-${day.toString().padStart(2, "0")}T17:00:00.000Z`
),
},
],
[
{
start: new Date(
`${year}-${month.toString().padStart(2, "0")}-${day.toString().padStart(2, "0")}T09:00:00.000Z`
),
end: new Date(
`${year}-${month.toString().padStart(2, "0")}-${day.toString().padStart(2, "0")}T17:00:00.000Z`
),
},
],
[
{
start: new Date(
`${year}-${month.toString().padStart(2, "0")}-${day.toString().padStart(2, "0")}T09:00:00.000Z`
),
end: new Date(
`${year}-${month.toString().padStart(2, "0")}-${day.toString().padStart(2, "0")}T17:00:00.000Z`
),
},
],
[],
],
timeZone: "America/Cancun",
dateOverrides: [],
isDefault: true,
isLastSchedule: true,
readOnly: false,
};
const result = transformApiScheduleForAtom(user, schedule, 1);
expect(result).toEqual(expectedResult);
});
});

View File

@@ -0,0 +1,59 @@
import {
transformAvailabilityForAtom,
transformDateOverridesForAtom,
transformApiScheduleAvailability,
transformApiScheduleOverrides,
transformWorkingHoursForAtom,
} from "@calcom/lib/schedules/transformers";
import type { ScheduleOutput_2024_06_11 } from "@calcom/platform-types";
import type { User } from "@calcom/prisma/client";
export function transformApiScheduleForAtom(
user: Pick<User, "id" | "defaultScheduleId" | "timeZone"> | undefined,
schedule: ScheduleOutput_2024_06_11 | null | undefined,
userSchedulesCount: number
) {
if (!user || !schedule) {
return null;
}
const transformedSchedule = {
...schedule,
availability: transformApiScheduleAvailability(schedule.availability),
overrides: transformApiScheduleOverrides(schedule.overrides),
};
const combined = [...transformedSchedule.availability, ...transformedSchedule.overrides];
const availability = combined.map((entry) => {
return {
...entry,
userId: schedule.ownerId,
scheduleId: schedule.id,
days: "days" in entry ? entry.days : [],
date: "date" in entry ? entry.date : null,
};
});
const atomSchedule = {
...schedule,
availability,
userId: schedule.ownerId,
};
const timeZone = schedule.timeZone || user.timeZone;
const defaultScheduleId = user.defaultScheduleId;
return {
id: schedule.id,
name: schedule.name,
isManaged: schedule.ownerId !== user.id,
workingHours: transformWorkingHoursForAtom(atomSchedule),
schedule: availability,
availability: transformAvailabilityForAtom(atomSchedule),
timeZone,
dateOverrides: transformDateOverridesForAtom(atomSchedule, timeZone),
isDefault: defaultScheduleId === schedule.id,
isLastSchedule: userSchedulesCount <= 1,
readOnly: schedule.ownerId !== user.id,
};
}

View File

@@ -0,0 +1,72 @@
import type { UpdateScheduleInput_2024_06_11 } from "@calcom/platform-types";
import type { AvailabilityFormValues } from "../types";
import { transformAtomScheduleForApi } from "./transformAtomScheduleForApi";
describe("transformAtomScheduleForApi", () => {
it("should transform atom schedule correctly to API format", () => {
const input: AvailabilityFormValues = {
name: "Default",
schedule: [
[],
[
{
start: new Date("2024-05-14T09:00:00.000Z"),
end: new Date("2024-05-14T17:00:00.000Z"),
},
],
[
{
start: new Date("2024-05-14T09:00:00.000Z"),
end: new Date("2024-05-14T17:00:00.000Z"),
},
],
[
{
start: new Date("2024-05-14T09:00:00.000Z"),
end: new Date("2024-05-14T17:00:00.000Z"),
},
],
[
{
start: new Date("2024-05-14T09:00:00.000Z"),
end: new Date("2024-05-14T17:00:00.000Z"),
},
],
[
{
start: new Date("2024-05-14T11:00:00.000Z"),
end: new Date("2024-05-14T12:00:00.000Z"),
},
],
[],
],
dateOverrides: [],
timeZone: "America/Cancun",
isDefault: true,
};
const expectedOutput: UpdateScheduleInput_2024_06_11 = {
name: "Default",
timeZone: "America/Cancun",
isDefault: true,
availability: [
{
days: ["Monday", "Tuesday", "Wednesday", "Thursday"],
startTime: "09:00",
endTime: "17:00",
},
{
days: ["Friday"],
startTime: "11:00",
endTime: "12:00",
},
],
overrides: [],
};
const result = transformAtomScheduleForApi(input);
expect(result).toEqual(expectedOutput);
});
});

View File

@@ -0,0 +1,88 @@
import type {
ScheduleAvailabilityInput_2024_06_11,
UpdateScheduleInput_2024_06_11,
WeekDay,
} from "@calcom/platform-types";
import type { AvailabilityFormValues } from "../types";
export function transformAtomScheduleForApi(body: AvailabilityFormValues): UpdateScheduleInput_2024_06_11 {
const { name, schedule, dateOverrides, timeZone, isDefault } = body;
const overrides =
dateOverrides.flatMap(
(dateOverridesRanges) =>
dateOverridesRanges?.ranges?.map((range) => transfromAtomOverrideForApi(range)) ?? []
) ?? [];
const availability = formatScheduleTime(schedule);
return { name, timeZone, isDefault, availability, overrides };
}
type AtomDateOverride = {
start: Date;
end: Date;
};
function transfromAtomOverrideForApi(override: AtomDateOverride) {
const date = `${override.start.getUTCFullYear()}-${(override.start.getUTCMonth() + 1)
.toString()
.padStart(2, "0")}-${override.start.getUTCDate().toString().padStart(2, "0")}`;
return {
date,
startTime: padHoursMinutesWithZeros(`${override.start.getUTCHours()}:${override.start.getUTCMinutes()}`),
endTime: padHoursMinutesWithZeros(`${override.end.getUTCHours()}:${override.end.getUTCMinutes()}`),
};
}
function padHoursMinutesWithZeros(hhMM: string) {
const [hours, minutes] = hhMM.split(":");
const formattedHours = hours.padStart(2, "0");
const formattedMinutes = minutes.padStart(2, "0");
return `${formattedHours}:${formattedMinutes}`;
}
function formatScheduleTime(
weekSchedule: AvailabilityFormValues["schedule"]
): UpdateScheduleInput_2024_06_11["availability"] {
const daysOfWeek: WeekDay[] = [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
];
const formattedSchedule = weekSchedule.map((daySchedule, index) =>
daySchedule.map((event) => ({
startTime: convertToHHMM(event.start.toISOString()),
endTime: convertToHHMM(event.end.toISOString()),
days: [daysOfWeek[index]],
}))
);
const timeMap: { [key: string]: ScheduleAvailabilityInput_2024_06_11 } = {};
formattedSchedule.flat().forEach((event) => {
const timeKey = `${event.startTime}-${event.endTime}`;
if (!timeMap[timeKey]) {
timeMap[timeKey] = { startTime: event.startTime, endTime: event.endTime, days: [] };
}
timeMap[timeKey].days.push(...event.days);
});
return Object.values(timeMap);
}
function convertToHHMM(isoDate: string): string {
const date = new Date(isoDate);
const hours = date.getUTCHours().toString().padStart(2, "0");
const minutes = date.getUTCMinutes().toString().padStart(2, "0");
return `${hours}:${minutes}`;
}