docs: v2 team event schedulingType (#20289)

* refactor: input scheduling type

* refactor: output scheduling type
This commit is contained in:
Lauris Skraucis authored and GitHub committed 2025-03-21 13:25:59 +00:00
1 parent 2e86f8404f
commit c0ecfcd910
7 files changed
+162 -32

No files matched your search

@@ -324,7 +324,7 @@ describe("Organizations Event Types Endpoints", () => {
const data = responseBody.data;
expect(data.title).toEqual(body.title);
expect(data.hosts.length).toEqual(2);
expect(data.schedulingType).toEqual("COLLECTIVE");
expect(data.schedulingType).toEqual("collective");
evaluateHost(body.hosts[0], data.hosts[0]);
evaluateHost(body.hosts[1], data.hosts[1]);
expect(data.bookingLimitsCount).toEqual(body.bookingLimitsCount);
@@ -457,8 +457,8 @@ describe("Organizations Event Types Endpoints", () => {
const data = responseBody.data;
expect(data.length).toEqual(2);
const eventTypeCollective = data.find((eventType) => eventType.schedulingType === "COLLECTIVE");
const eventTypeManaged = data.find((eventType) => eventType.schedulingType === "MANAGED");
const eventTypeCollective = data.find((eventType) => eventType.schedulingType === "collective");
const eventTypeManaged = data.find((eventType) => eventType.schedulingType === "managed");
expect(eventTypeCollective?.title).toEqual(collectiveEventType.title);
expect(eventTypeCollective?.hosts.length).toEqual(2);
@@ -564,7 +564,7 @@ describe("Organizations Event Types Endpoints", () => {
).toEqual(newTitle);
const responseTeamEvent = responseBody.data.find(
(eventType) => eventType.schedulingType === "MANAGED"
(eventType) => eventType.schedulingType === "managed"
);
expect(responseTeamEvent).toBeDefined();
expect(responseTeamEvent?.title).toEqual(newTitle);
@@ -823,7 +823,7 @@ describe("Organizations Event Types Endpoints", () => {
expect(managedTeamEventTypes[0].assignAllTeamMembers).toEqual(true);
const responseTeamEvent = responseBody.data.find(
(eventType) => eventType.schedulingType === "MANAGED"
(eventType) => eventType.schedulingType === "managed"
);
expect(responseTeamEvent).toBeDefined();
expect(responseTeamEvent?.teamId).toEqual(team.id);
@@ -954,6 +954,117 @@ describe("Organizations Event Types Endpoints", () => {
});
});
it("should create a round robin team event-type", async () => {
const body: CreateTeamEventTypeInput_2024_06_14 = {
successRedirectUrl: "https://masterchief.com/argentina/flan/video/1234",
title: "Coding consultation round robin",
slug: `organizations-event-types-round-robin-${randomString()}`,
description: "Our team will review your codebase.",
lengthInMinutes: 60,
locations: [
{
type: "integration",
integration: "cal-video",
},
],
bookingFields: [
{
type: "select",
label: "select which language is your codebase in",
slug: "select-language",
required: true,
placeholder: "select language",
options: ["javascript", "python", "cobol"],
},
],
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
schedulingType: "roundRobin",
hosts: [
{
userId: teammate1.id,
mandatory: true,
priority: "high",
},
{
userId: teammate2.id,
mandatory: false,
priority: "medium",
},
],
bookingLimitsCount: {
day: 2,
week: 5,
},
onlyShowFirstAvailableSlot: true,
bookingLimitsDuration: {
day: 60,
week: 100,
},
offsetStart: 30,
bookingWindow: {
type: BookingWindowPeriodInputTypeEnum_2024_06_14.calendarDays,
value: 30,
rolling: true,
},
bookerLayouts: {
enabledLayouts: [
BookerLayoutsInputEnum_2024_06_14.column,
BookerLayoutsInputEnum_2024_06_14.month,
BookerLayoutsInputEnum_2024_06_14.week,
],
defaultLayout: BookerLayoutsInputEnum_2024_06_14.month,
},
confirmationPolicy: {
type: ConfirmationPolicyEnum.TIME,
noticeThreshold: {
count: 60,
unit: NoticeThresholdUnitEnum.MINUTES,
},
blockUnconfirmedBookingsInBooker: true,
},
requiresBookerEmailVerification: true,
hideCalendarNotes: true,
hideCalendarEventDetails: true,
lockTimeZoneToggleOnBookingPage: true,
color: {
darkThemeHex: "#292929",
lightThemeHex: "#fafafa",
},
};
return request(app.getHttpServer())
.post(`/v2/organizations/${org.id}/teams/${team.id}/event-types`)
.send(body)
.expect(201)
.then((response) => {
const responseBody: ApiSuccessResponse<TeamEventTypeOutput_2024_06_14> = response.body;
expect(responseBody.status).toEqual(SUCCESS_STATUS);
const data = responseBody.data;
expect(data.title).toEqual(body.title);
expect(data.hosts.length).toEqual(2);
expect(data.schedulingType).toEqual("roundRobin");
evaluateHost(body.hosts[0], data.hosts[0]);
evaluateHost(body.hosts[1], data.hosts[1]);
expect(data.bookingLimitsCount).toEqual(body.bookingLimitsCount);
expect(data.onlyShowFirstAvailableSlot).toEqual(body.onlyShowFirstAvailableSlot);
expect(data.bookingLimitsDuration).toEqual(body.bookingLimitsDuration);
expect(data.offsetStart).toEqual(body.offsetStart);
expect(data.bookingWindow).toEqual(body.bookingWindow);
expect(data.bookerLayouts).toEqual(body.bookerLayouts);
expect(data.confirmationPolicy).toEqual(body.confirmationPolicy);
expect(data.requiresBookerEmailVerification).toEqual(body.requiresBookerEmailVerification);
expect(data.hideCalendarNotes).toEqual(body.hideCalendarNotes);
expect(data.hideCalendarEventDetails).toEqual(body.hideCalendarEventDetails);
expect(data.lockTimeZoneToggleOnBookingPage).toEqual(body.lockTimeZoneToggleOnBookingPage);
expect(data.color).toEqual(body.color);
expect(data.successRedirectUrl).toEqual("https://masterchief.com/argentina/flan/video/1234");
collectiveEventType = responseBody.data;
});
});
function evaluateHost(expected: Host, received: Host | undefined) {
expect(expected.userId).toEqual(received?.userId);
expect(expected.mandatory).toEqual(received?.mandatory);
@@ -100,7 +100,9 @@ export class OutputOrganizationsEventTypesService {
teamId,
ownerId: userId,
parentEventTypeId: parentId,
schedulingType: databaseEventType.schedulingType,
schedulingType: databaseEventType.schedulingType
? this.getResponseSchedulingType(databaseEventType.schedulingType)
: databaseEventType.schedulingType,
assignAllTeamMembers: teamId ? assignAllTeamMembers : undefined,
team: {
id: teamId,
@@ -116,6 +118,19 @@ export class OutputOrganizationsEventTypesService {
};
}
getResponseSchedulingType(schedulingType: SchedulingType) {
if (schedulingType === SchedulingType.COLLECTIVE) {
return "collective";
}
if (schedulingType === SchedulingType.ROUND_ROBIN) {
return "roundRobin";
}
if (schedulingType === SchedulingType.MANAGED) {
return "managed";
}
return schedulingType;
}
async getManagedEventTypeHosts(eventTypeId: number) {
const children = await this.teamsEventTypesRepository.getEventTypeChildren(eventTypeId);
const transformedHosts: TeamEventTypeResponseHost[] = [];
@@ -144,7 +159,7 @@ export class OutputOrganizationsEventTypesService {
transformedHosts.push({
userId: databaseHost.userId,
name: databaseUser?.name || "",
mandatory: databaseHost.isFixed,
mandatory: !!databaseHost.isFixed,
priority: getPriorityLabel(databaseHost.priority || 2),
avatarUrl: databaseUser?.avatarUrl,
});
@@ -303,7 +303,7 @@ describe("Organizations Event Types Endpoints", () => {
const data = responseBody.data;
expect(data.title).toEqual(body.title);
expect(data.hosts.length).toEqual(2);
expect(data.schedulingType).toEqual("COLLECTIVE");
expect(data.schedulingType).toEqual("collective");
evaluateHost(body.hosts[0], data.hosts[0]);
evaluateHost(body.hosts[1], data.hosts[1]);
expect(data.bookingLimitsCount).toEqual(body.bookingLimitsCount);
@@ -423,8 +423,8 @@ describe("Organizations Event Types Endpoints", () => {
const data = responseBody.data;
expect(data.length).toEqual(2);
const eventTypeCollective = data.find((eventType) => eventType.schedulingType === "COLLECTIVE");
const eventTypeManaged = data.find((eventType) => eventType.schedulingType === "MANAGED");
const eventTypeCollective = data.find((eventType) => eventType.schedulingType === "collective");
const eventTypeManaged = data.find((eventType) => eventType.schedulingType === "managed");
expect(eventTypeCollective?.title).toEqual(collectiveEventType.title);
expect(eventTypeCollective?.hosts.length).toEqual(2);
@@ -516,7 +516,7 @@ describe("Organizations Event Types Endpoints", () => {
).toEqual(newTitle);
const responseTeamEvent = responseBody.data.find(
(eventType) => eventType.schedulingType === "MANAGED"
(eventType) => eventType.schedulingType === "managed"
);
expect(responseTeamEvent).toBeDefined();
expect(responseTeamEvent?.title).toEqual(newTitle);
@@ -562,7 +562,7 @@ describe("Organizations Event Types Endpoints", () => {
expect(managedTeamEventTypes[0].assignAllTeamMembers).toEqual(true);
const responseTeamEvent = responseBody.data.find(
(eventType) => eventType.schedulingType === "MANAGED"
(eventType) => eventType.schedulingType === "managed"
);
expect(responseTeamEvent).toBeDefined();
expect(responseTeamEvent?.teamId).toEqual(team.id);
+11 -5
View File
@@ -13182,7 +13182,14 @@
"example": "https://masterchief.com/argentina/flan/video/9129412"
},
"schedulingType": {
"type": "object"
"type": "string",
"enum": [
"collective",
"roundRobin",
"managed"
],
"example": "collective",
"description": "The scheduling type for the team event - collective, roundRobin or managed."
},
"hosts": {
"type": "array",
@@ -13613,11 +13620,10 @@
},
"schedulingType": {
"type": "string",
"nullable": true,
"enum": [
"ROUND_ROBIN",
"COLLECTIVE",
"MANAGED"
"roundRobin",
"collective",
"managed"
]
},
"team": {
+5 -3
View File
@@ -12020,7 +12020,10 @@
"example": "https://masterchief.com/argentina/flan/video/9129412"
},
"schedulingType": {
"type": "object"
"type": "string",
"enum": ["collective", "roundRobin", "managed"],
"example": "collective",
"description": "The scheduling type for the team event - collective, roundRobin or managed."
},
"hosts": {
"type": "array",
@@ -12424,8 +12427,7 @@
},
"schedulingType": {
"type": "string",
"nullable": true,
"enum": ["ROUND_ROBIN", "COLLECTIVE", "MANAGED"]
"enum": ["roundRobin", "collective", "managed"]
},
"team": {
"$ref": "#/components/schemas/EventTypeTeam"
@@ -460,7 +460,11 @@ export class CreateTeamEventTypeInput_2024_06_14 extends BaseCreateEventTypeInpu
return value;
})
@IsEnum(SchedulingType)
@DocsProperty()
@DocsProperty({
enum: ["collective", "roundRobin", "managed"],
example: "collective",
description: "The scheduling type for the team event - collective, roundRobin or managed.",
})
schedulingType!: keyof typeof SchedulingType;
@ValidateNested({ each: true })
@@ -68,14 +68,6 @@ import {
ValidateOutputLocations_2024_06_14,
} from "./locations.output";
enum SchedulingTypeEnum {
ROUND_ROBIN = "ROUND_ROBIN",
COLLECTIVE = "COLLECTIVE",
MANAGED = "MANAGED",
}
export type EventTypesOutputSchedulingType = "ROUND_ROBIN" | "COLLECTIVE" | "MANAGED";
class User_2024_06_14 {
@IsInt()
@DocsProperty()
@@ -486,9 +478,9 @@ export class TeamEventTypeOutput_2024_06_14 extends BaseEventTypeOutput_2024_06_
@ApiPropertyOptional()
assignAllTeamMembers?: boolean;
@IsEnum(SchedulingTypeEnum)
@DocsProperty({ enum: SchedulingTypeEnum, nullable: true })
schedulingType!: EventTypesOutputSchedulingType | null;
@IsEnum(["roundRobin", "collective", "managed"] as const)
@DocsProperty({ enum: ["roundRobin", "collective", "managed"] })
schedulingType!: "roundRobin" | "collective" | "managed" | null;
@IsOptional()
@IsBoolean()