From ad5d92dff027d27ec5c9454a8ad0562a604120ca Mon Sep 17 00:00:00 2001 From: Lauris Skraucis Date: Wed, 18 Dec 2024 13:36:26 +0100 Subject: [PATCH] refactor: v2 calendars busy-times (#18244) * refactor: make dateFrom and dateTo required * refactor: make dateFrom and dateTo required * refactor: useCalendarsBusyTimes enabled only if dateFrom & dateTo passed --- .../controllers/calendars.controller.ts | 12 +++++----- apps/api/v2/swagger/documentation.json | 21 ++++++++++++++++++ docs/api-reference/v2/openapi.json | 21 ++++++++++++++++++ .../atoms/hooks/useCalendarsBusyTimes.ts | 7 ++++-- packages/platform/types/calendars.ts | 16 +++++--------- .../types/validators/isYearMonthDays.ts | 22 ------------------- 6 files changed, 57 insertions(+), 42 deletions(-) delete mode 100644 packages/platform/types/validators/isYearMonthDays.ts diff --git a/apps/api/v2/src/ee/calendars/controllers/calendars.controller.ts b/apps/api/v2/src/ee/calendars/controllers/calendars.controller.ts index b12589e1fa..515aa64d5e 100644 --- a/apps/api/v2/src/ee/calendars/controllers/calendars.controller.ts +++ b/apps/api/v2/src/ee/calendars/controllers/calendars.controller.ts @@ -86,18 +86,16 @@ export class CalendarsController { @UseGuards(ApiAuthGuard) @Get("/busy-times") - @ApiOperation({ summary: "Get busy times" }) + @ApiOperation({ + summary: "Get busy times", + description: + "Get busy times from a calendar. Example request URL is `https://api.cal.com/v2/calendars/busy-times?loggedInUsersTz=Europe%2FMadrid&dateFrom=2024-12-18&dateTo=2024-12-18&calendarsToLoad[0][credentialId]=135&calendarsToLoad[0][externalId]=skrauciz%40gmail.com`", + }) async getBusyTimes( @Query() queryParams: CalendarBusyTimesInput, @GetUser() user: UserWithProfile ): Promise { const { loggedInUsersTz, dateFrom, dateTo, calendarsToLoad } = queryParams; - if (!dateFrom || !dateTo) { - return { - status: SUCCESS_STATUS, - data: [], - }; - } const busyTimes = await this.calendarsService.getBusyTimes( calendarsToLoad, diff --git a/apps/api/v2/swagger/documentation.json b/apps/api/v2/swagger/documentation.json index 47d7fe5bc1..e5fd9ae826 100644 --- a/apps/api/v2/swagger/documentation.json +++ b/apps/api/v2/swagger/documentation.json @@ -3592,6 +3592,7 @@ "get": { "operationId": "CalendarsController_getBusyTimes", "summary": "Get busy times", + "description": "Get busy times from a calendar. Example request URL is `https://api.cal.com/v2/calendars/busy-times?loggedInUsersTz=Europe%2FMadrid&dateFrom=2024-12-18&dateTo=2024-12-18&calendarsToLoad[0][credentialId]=135&calendarsToLoad[0][externalId]=skrauciz%40gmail.com`", "parameters": [ { "name": "loggedInUsersTz", @@ -3603,6 +3604,26 @@ "type": "string" } }, + { + "name": "dateFrom", + "required": false, + "in": "query", + "description": "The starting date for the busy times query", + "example": "2023-10-01", + "schema": { + "type": "string" + } + }, + { + "name": "dateTo", + "required": false, + "in": "query", + "description": "The ending date for the busy times query", + "example": "2023-10-31", + "schema": { + "type": "string" + } + }, { "name": "credentialId", "in": "query", diff --git a/docs/api-reference/v2/openapi.json b/docs/api-reference/v2/openapi.json index cf007dd321..a1878beb96 100644 --- a/docs/api-reference/v2/openapi.json +++ b/docs/api-reference/v2/openapi.json @@ -3408,6 +3408,7 @@ "get": { "operationId": "CalendarsController_getBusyTimes", "summary": "Get busy times", + "description": "Get busy times from a calendar. Example request URL is `https://api.cal.com/v2/calendars/busy-times?loggedInUsersTz=Europe%2FMadrid&dateFrom=2024-12-18&dateTo=2024-12-18&calendarsToLoad[0][credentialId]=135&calendarsToLoad[0][externalId]=skrauciz%40gmail.com`", "parameters": [ { "name": "loggedInUsersTz", @@ -3419,6 +3420,26 @@ "type": "string" } }, + { + "name": "dateFrom", + "required": false, + "in": "query", + "description": "The starting date for the busy times query", + "example": "2023-10-01", + "schema": { + "type": "string" + } + }, + { + "name": "dateTo", + "required": false, + "in": "query", + "description": "The ending date for the busy times query", + "example": "2023-10-31", + "schema": { + "type": "string" + } + }, { "name": "credentialId", "in": "query", diff --git a/packages/platform/atoms/hooks/useCalendarsBusyTimes.ts b/packages/platform/atoms/hooks/useCalendarsBusyTimes.ts index 6226d8dcae..facf64fd54 100644 --- a/packages/platform/atoms/hooks/useCalendarsBusyTimes.ts +++ b/packages/platform/atoms/hooks/useCalendarsBusyTimes.ts @@ -8,7 +8,10 @@ import http from "../lib/http"; export const QUERY_KEY = "get-calendars-busy-times"; -type UseCalendarsBusyTimesProps = CalendarBusyTimesInput & { onError?: () => void; enabled: boolean }; +type UseCalendarsBusyTimesProps = Omit & { + dateFrom: string | null; + dateTo: string | null; +} & { onError?: () => void; enabled: boolean }; export const useCalendarsBusyTimes = ({ onError, enabled, ...rest }: UseCalendarsBusyTimesProps) => { const availableSlots = useQuery({ @@ -32,7 +35,7 @@ export const useCalendarsBusyTimes = ({ onError, enabled, ...rest }: UseCalendar throw new Error(res.data.error.message); }); }, - enabled, + enabled: enabled && !!rest.dateFrom && !!rest.dateTo, }); return availableSlots; }; diff --git a/packages/platform/types/calendars.ts b/packages/platform/types/calendars.ts index 3ea42a10ed..4feb14ae62 100644 --- a/packages/platform/types/calendars.ts +++ b/packages/platform/types/calendars.ts @@ -1,9 +1,7 @@ import { ApiProperty } from "@nestjs/swagger"; import { Type } from "class-transformer"; import { Transform } from "class-transformer"; -import { IsNumber, IsString, IsOptional, IsArray, ValidateNested, Validate } from "class-validator"; - -import { IsYearMonthDays } from "./validators/isYearMonthDays"; +import { IsNumber, IsString, IsArray, ValidateNested, IsDateString } from "class-validator"; export class Calendar { @Transform(({ value }: { value: string }) => value && parseInt(value)) @@ -29,23 +27,19 @@ export class CalendarBusyTimesInput { required: false, description: "The starting date for the busy times query", example: "2023-10-01", - nullable: true, }) @IsString() - @IsOptional() - @Validate(IsYearMonthDays) - dateFrom?: string | null; + @IsDateString() + dateFrom!: string; @ApiProperty({ required: false, description: "The ending date for the busy times query", example: "2023-10-31", - nullable: true, }) @IsString() - @IsOptional() - @Validate(IsYearMonthDays) - dateTo?: string | null; + @IsDateString() + dateTo!: string; @ApiProperty({ type: [Calendar], diff --git a/packages/platform/types/validators/isYearMonthDays.ts b/packages/platform/types/validators/isYearMonthDays.ts deleted file mode 100644 index f4c51ea7be..0000000000 --- a/packages/platform/types/validators/isYearMonthDays.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { ValidatorConstraintInterface } from "class-validator"; -import { ValidatorConstraint } from "class-validator"; -import { DateTime } from "luxon"; - -@ValidatorConstraint({ name: "IsYearMonthDays", async: false }) -export class IsYearMonthDays implements ValidatorConstraintInterface { - validate(dateString: string): boolean { - try { - // Attempt to parse the date string - const dateTime = DateTime.fromFormat(dateString, "yyyy-MM-dd"); - - // Check if the parsed date is valid - return dateTime.isValid; - } catch (error) { - return false; - } - } - - defaultMessage() { - return "time format must be YEAR-MONTH-DAYS (e.g. 2022-01-01)"; - } -}