feat: max-seats-per-time-slot (#20213)

* feat: max-seats-per-time-slot

* fix : test

* enhancements

* enhancements

* fix:test

* fix:test
This commit is contained in:
Tushar Bhatt
2025-04-03 15:29:57 -04:00
committed by GitHub
parent cb365117b3
commit 8d59c2fc16
7 changed files with 32 additions and 9 deletions
+2 -1
View File
@@ -1,5 +1,6 @@
import { z } from "zod";
import { MAX_SEATS_PER_TIME_SLOT } from "@calcom/lib/constants";
import slugify from "@calcom/lib/slugify";
import { _EventTypeModel as EventType, _HostModel } from "@calcom/prisma/zod";
import { customInputSchema, eventTypeBookingFields } from "@calcom/prisma/zod-utils";
@@ -103,7 +104,7 @@ const schemaEventTypeEditParams = z
.transform((s) => slugify(s))
.optional(),
length: z.number().int().optional(),
seatsPerTimeSlot: z.number().optional(),
seatsPerTimeSlot: z.number().min(1).max(MAX_SEATS_PER_TIME_SLOT).nullable().optional(),
seatsShowAttendees: z.boolean().optional(),
seatsShowAvailabilityCount: z.boolean().optional(),
bookingFields: eventTypeBookingFields.optional(),
@@ -10,6 +10,7 @@ import {
IsOptional,
ValidateNested,
Min,
Max,
IsInt,
IsEnum,
IsArray,
@@ -17,6 +18,8 @@ import {
IsNumber,
} from "class-validator";
import { MAX_SEATS_PER_TIME_SLOT } from "@calcom/platform-constants";
// note(Lauris): We will gradually expose more properties if any customer needs them.
// Just uncomment any below when requested. Go to bottom of file to see UpdateEventTypeInput.
@@ -414,9 +417,12 @@ export class UpdateEventTypeInput_2024_04_15 {
@ApiPropertyOptional()
afterEventBuffer?: number;
// @IsInt()
// @IsOptional()
// seatsPerTimeSlot?: number;
@IsInt()
@Min(1)
@Max(MAX_SEATS_PER_TIME_SLOT)
@IsOptional()
@ApiPropertyOptional()
seatsPerTimeSlot?: number;
// @IsBoolean()
// @IsOptional()
@@ -30,7 +30,12 @@ import { FormBuilder } from "@calcom/features/form-builder/FormBuilder";
import type { fieldSchema } from "@calcom/features/form-builder/schema";
import type { EditableSchema } from "@calcom/features/form-builder/schema";
import { BookerLayoutSelector } from "@calcom/features/settings/BookerLayoutSelector";
import { DEFAULT_LIGHT_BRAND_COLOR, DEFAULT_DARK_BRAND_COLOR, APP_NAME } from "@calcom/lib/constants";
import {
DEFAULT_LIGHT_BRAND_COLOR,
DEFAULT_DARK_BRAND_COLOR,
APP_NAME,
MAX_SEATS_PER_TIME_SLOT,
} from "@calcom/lib/constants";
import type { EventNameObjectType } from "@calcom/lib/event";
import { getEventName } from "@calcom/lib/event";
import { generateHashedLink } from "@calcom/lib/generateHashedLink";
@@ -831,8 +836,10 @@ export const EventAdvancedTab = ({
label={t("number_of_seats")}
type="number"
disabled={seatsLocked.disabled}
defaultValue={value}
//For old events if value > MAX_SEATS_PER_TIME_SLOT
value={value > MAX_SEATS_PER_TIME_SLOT ? MAX_SEATS_PER_TIME_SLOT : value ?? 1}
min={1}
max={MAX_SEATS_PER_TIME_SLOT}
containerClassName={classNames(
"max-w-80",
customClassNames?.seatsOptions?.seatsInput.container
@@ -840,9 +847,11 @@ export const EventAdvancedTab = ({
addOnClassname={customClassNames?.seatsOptions?.seatsInput.addOn}
className={customClassNames?.seatsOptions?.seatsInput?.input}
labelClassName={customClassNames?.seatsOptions?.seatsInput?.label}
addOnSuffix={<>{t("seats")}</>}
addOnSuffix={t("seats")}
onChange={(e) => {
onChange(Math.abs(Number(e.target.value)));
let enteredValue = Number(e.target.value);
if (enteredValue < 1) enteredValue = 1;
onChange(Math.min(enteredValue, MAX_SEATS_PER_TIME_SLOT));
}}
data-testid="seats-per-time-slot"
/>
+1
View File
@@ -58,6 +58,7 @@ export const IS_SELF_HOSTED = !(
);
export const EMBED_LIB_URL = process.env.NEXT_PUBLIC_EMBED_LIB_URL || `${WEBAPP_URL}/embed/embed.js`;
export const TRIAL_LIMIT_DAYS = 14;
export const MAX_SEATS_PER_TIME_SLOT = 1000;
export const HOSTED_CAL_FEATURES = process.env.NEXT_PUBLIC_HOSTED_CAL_FEATURES || !IS_SELF_HOSTED;
+1
View File
@@ -70,3 +70,4 @@ export const API_VERSIONS = [
export type API_VERSIONS_ENUM = (typeof API_VERSIONS)[number];
export type API_VERSIONS_TYPE = typeof API_VERSIONS;
export const CAL_API_VERSION_HEADER = "cal-api-version";
export const MAX_SEATS_PER_TIME_SLOT = 1000;
@@ -1,10 +1,13 @@
import { ApiProperty } from "@nestjs/swagger";
import { IsBoolean, IsInt, IsOptional, Min } from "class-validator";
import { IsBoolean, IsInt, IsOptional, Min, Max } from "class-validator";
import { MAX_SEATS_PER_TIME_SLOT } from "@calcom/platform-constants";
// Class representing the seat options
export class Seats_2024_06_14 {
@IsInt()
@Min(1)
@Max(MAX_SEATS_PER_TIME_SLOT)
@ApiProperty({
description: "Number of seats available per time slot",
example: 4,
@@ -1,6 +1,7 @@
import { z } from "zod";
import { templateTypeEnum } from "@calcom/features/ee/cal-ai-phone/zod-utils";
import { MAX_SEATS_PER_TIME_SLOT } from "@calcom/lib/constants";
import { _DestinationCalendarModel, _EventTypeModel } from "@calcom/prisma/zod";
import {
customInputSchema,
@@ -71,6 +72,7 @@ const BaseEventTypeUpdateInput = _EventTypeModel
assignRRMembersUsingSegment: z.boolean().optional(),
rrSegmentQueryValue: rrSegmentQueryValueSchema.optional(),
useEventLevelSelectedCalendars: z.boolean().optional(),
seatsPerTimeSlot: z.number().min(1).max(MAX_SEATS_PER_TIME_SLOT).nullable().optional(),
})
.partial()
.extend(_EventTypeModel.pick({ id: true }).shape);