first commit
This commit is contained in:
@@ -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);
|
||||
});
|
||||
});
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
@@ -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}`;
|
||||
}
|
||||
Reference in New Issue
Block a user