@@ -15,7 +15,7 @@ import findDurationType from "@calcom/lib/findDurationType";
1515import { useLocale } from "@calcom/lib/hooks/useLocale" ;
1616import { ascendingLimitKeys , intervalLimitKeyToUnit } from "@calcom/lib/intervalLimits/intervalLimit" ;
1717import type { IntervalLimit } from "@calcom/lib/intervalLimits/intervalLimitSchema" ;
18- import { PeriodType } from "@calcom/prisma/enums" ;
18+ import { PeriodType , SchedulingType } from "@calcom/prisma/enums" ;
1919import classNames from "@calcom/ui/classNames" ;
2020import { Button } from "@calcom/ui/components/button" ;
2121import {
@@ -28,6 +28,7 @@ import {
2828} from "@calcom/ui/components/form" ;
2929import { Icon } from "@calcom/ui/components/icon" ;
3030import { Tooltip } from "@calcom/ui/components/tooltip" ;
31+ import { Badge } from "@calcom/ui/components/badge" ;
3132import { LearnMoreLink } from "@calcom/web/modules/event-types/components/LearnMoreLink" ;
3233import { useAutoAnimate } from "@formkit/auto-animate/react" ;
3334import * as RadioGroup from "@radix-ui/react-radio-group" ;
@@ -36,6 +37,7 @@ import React, { useEffect, useState } from "react";
3637import type { UseFormRegisterReturn , UseFormReturn } from "react-hook-form" ;
3738import { Controller , useFormContext } from "react-hook-form" ;
3839import type { SingleValue } from "react-select" ;
40+ import Link from "next/link" ;
3941
4042import MaxActiveBookingsPerBookerController from "./MaxActiveBookingsPerBookerController" ;
4143
@@ -135,13 +137,13 @@ function RangeLimitRadioItem({
135137 "text-default mb-2 flex flex-col items-start text-sm sm:flex-row sm:items-center" ,
136138 customClassNames ?. wrapper
137139 ) } >
138- < div className = "flex w-full items-center sm:w-auto" >
140+ < div className = "flex items-center w-full sm:w-auto" >
139141 { ! isDisabled && (
140142 < RadioGroup . Item
141143 id = { radioValue }
142144 value = { radioValue }
143- className = "bg-default border-default flex h-4 w-4 min-w-4 cursor-pointer items-center rounded-full border focus:border-2 focus:outline-none ltr:mr-2 rtl:ml-2" >
144- < RadioGroup . Indicator className = "after:bg-inverted relative flex h-4 w-4 items-center justify-center after:block after:h-2 after:w-2 after:rounded-full" />
145+ className = "flex items-center w-4 h-4 rounded-full border cursor-pointer bg-default border-default min-w-4 focus:border-2 focus:outline-none ltr:mr-2 rtl:ml-2" >
146+ < RadioGroup . Indicator className = "flex relative justify-center items-center w-4 h-4 after:bg-inverted after:block after:h-2 after:w-2 after:rounded-full" />
145147 </ RadioGroup . Item >
146148 ) }
147149 < span > { t ( "within_date_range" ) } </ span >
@@ -223,8 +225,8 @@ function RollingLimitRadioItem({
223225 < RadioGroup . Item
224226 id = { radioValue }
225227 value = { radioValue }
226- className = "bg-default border-default flex h-4 w-4 min-w-4 cursor-pointer items-center rounded-full border focus:border-2 focus:outline-none ltr:mr-2 rtl:ml-2" >
227- < RadioGroup . Indicator className = "after:bg-inverted relative flex h-4 w-4 items-center justify-center after:block after:h-2 after:w-2 after:rounded-full" />
228+ className = "flex items-center w-4 h-4 rounded-full border cursor-pointer bg-default border-default min-w-4 focus:border-2 focus:outline-none ltr:mr-2 rtl:ml-2" >
229+ < RadioGroup . Indicator className = "flex relative justify-center items-center w-4 h-4 after:bg-inverted after:block after:h-2 after:w-2 after:rounded-full" />
228230 </ RadioGroup . Item >
229231 ) }
230232
@@ -259,7 +261,7 @@ function RollingLimitRadioItem({
259261 />
260262 < span className = "me-2 ms-2" > { t ( "into_the_future" ) } </ span >
261263 </ div >
262- < div className = "-ml-6 flex flex-col py-2" >
264+ < div className = "flex flex-col py-2 -ml-6 " >
263265 < div className = "flex items-center" >
264266 < CheckboxField
265267 checked = { ! ! rollingExcludeUnavailableDays }
@@ -289,7 +291,7 @@ function RollingLimitRadioItem({
289291 } ) } >
290292 < Icon
291293 name = "info"
292- className = "text-default hover:text-attention hover:bg-attention ms-1 inline h-4 w-4 rounded-md "
294+ className = "inline w-4 h-4 rounded-md text-default hover:text-attention hover:bg-attention ms-1"
293295 />
294296 </ Tooltip >
295297 </ div >
@@ -350,7 +352,7 @@ const MinimumBookingNoticeInput = React.forwardRef<
350352 } , [ minimumBookingNoticeDisplayValues , setValue , passThroughProps . name ] ) ;
351353
352354 return (
353- < div className = "flex items -end justify -end" >
355+ < div className = "flex justify -end items -end" >
354356 < div className = "w-1/2 md:w-full" >
355357 < InputField
356358 required
@@ -399,7 +401,54 @@ export const EventLimitsTab = ({ eventType, customClassNames }: EventLimitsTabPr
399401 const { t, i18n } = useLocale ( ) ;
400402 const formMethods = useFormContext < FormValues > ( ) ;
401403
402- const isRecurringEvent = ! ! formMethods . getValues ( "recurringEvent" ) ;
404+
405+ const hasTeamLimits = ( ) => {
406+ const team = eventType . team as { bookingLimits ?: IntervalLimit | null ; includeManagedEventsInLimits ?: boolean } | null | undefined ;
407+ const parentTeam = ( eventType . parent as { team ?: { bookingLimits ?: IntervalLimit | null ; includeManagedEventsInLimits ?: boolean } } | null | undefined ) ?. team ;
408+
409+ const teamHasLimits =
410+ ! ! team ?. bookingLimits && Object . keys ( team . bookingLimits ) . length > 0 ;
411+
412+ const parentTeamHasLimits =
413+ ! ! parentTeam ?. bookingLimits &&
414+ Object . keys ( parentTeam . bookingLimits ) . length > 0 ;
415+
416+ const includeManaged =
417+ ! ! parentTeam ?. includeManagedEventsInLimits ||
418+ ! ! team ?. includeManagedEventsInLimits ;
419+
420+ if ( teamHasLimits ) {
421+ if ( eventType . schedulingType === SchedulingType . MANAGED ) return includeManaged ;
422+ return true ;
423+ }
424+
425+ return parentTeamHasLimits && includeManaged ;
426+ } ;
427+
428+ const TeamLimitsBadge = ( { isManagedChild, teamId } : { isManagedChild : boolean , teamId ?: number | null } ) => {
429+ const badge = (
430+ < Badge variant = "blue" className = "text-xs cursor-pointer hover:opacity-80" >
431+ { t ( "team_limits_apply" ) }
432+ </ Badge >
433+ ) ;
434+
435+ if ( isManagedChild ) {
436+ return < Tooltip content = { t ( "managed_by_team_admins" ) } > { badge } </ Tooltip > ;
437+ }
438+
439+ if ( teamId ) {
440+ return (
441+ < Link
442+ href = { `/settings/teams/${ teamId } /settings` }
443+ target = "_blank"
444+ rel = "noopener noreferrer"
445+ >
446+ { badge }
447+ </ Link >
448+ ) ;
449+ }
450+ return null ;
451+ } ;
403452
404453 const { shouldLockIndicator, shouldLockDisableProps } = useLockedFieldsManager ( {
405454 eventType,
@@ -432,7 +481,7 @@ export const EventLimitsTab = ({ eventType, customClassNames }: EventLimitsTabPr
432481 "border-subtle stack-y-6 rounded-lg border p-6" ,
433482 customClassNames ?. bufferAndNoticeSection ?. container
434483 ) } >
435- < div className = "stack-y-4 lg:stack-y-0 flex flex-col lg:flex-row lg:space-x-4" >
484+ < div className = "flex flex-col stack-y-4 lg:stack-y-0 lg:flex-row lg:space-x-4" >
436485 < div
437486 className = { classNames (
438487 "w-full" ,
@@ -526,7 +575,7 @@ export const EventLimitsTab = ({ eventType, customClassNames }: EventLimitsTabPr
526575 />
527576 </ div >
528577 </ div >
529- < div className = "stack-y-4 lg:stack-y-0 flex flex-col lg:flex-row lg:space-x-4" >
578+ < div className = "flex flex-col stack-y-4 lg:stack-y-0 lg:flex-row lg:space-x-4" >
530579 < div
531580 className = { classNames (
532581 "w-full" ,
@@ -603,6 +652,10 @@ export const EventLimitsTab = ({ eventType, customClassNames }: EventLimitsTabPr
603652 toggleSwitchAtTheEnd = { true }
604653 labelClassName = { classNames ( "text-sm" , customClassNames ?. bookingFrequencyLimit ?. label ) }
605654 title = { t ( "limit_booking_frequency" ) }
655+ Badge = {
656+ hasTeamLimits ( )
657+ ? TeamLimitsBadge ( { isManagedChild : ! ! eventType . parent , teamId : eventType . team ?. id } ) : null
658+ }
606659 { ...bookingLimitsLocked }
607660 description = {
608661 < LearnMoreLink
@@ -703,7 +756,7 @@ export const EventLimitsTab = ({ eventType, customClassNames }: EventLimitsTabPr
703756 onChange ( { } ) ;
704757 }
705758 } } >
706- < div className = "border-subtle rounded-b-lg border border-t-0 p-6 " >
759+ < div className = "p-6 rounded-b-lg border border-t-0 border-subtle " >
707760 < IntervalLimitsManager
708761 propertyName = "durationLimits"
709762 defaultLimit = { 60 }
@@ -756,7 +809,7 @@ export const EventLimitsTab = ({ eventType, customClassNames }: EventLimitsTabPr
756809 }
757810 return onChange ( isEnabled ? PeriodType . ROLLING : PeriodType . UNLIMITED ) ;
758811 } } >
759- < div className = "border-subtle rounded-b-lg border border-t-0 p-6 " >
812+ < div className = "p-6 rounded-b-lg border border-t-0 border-subtle " >
760813 < RadioGroup . Root
761814 value = { watchPeriodTypeUiValue }
762815 onValueChange = { ( val ) => {
@@ -821,7 +874,7 @@ export const EventLimitsTab = ({ eventType, customClassNames }: EventLimitsTabPr
821874 formMethods . setValue ( "offsetStart" , 0 , { shouldDirty : true } ) ;
822875 }
823876 } } >
824- < div className = { classNames ( "border-subtle rounded-b-lg border border-t-0 p-6 " ) } >
877+ < div className = { classNames ( "p-6 rounded-b-lg border border-t-0 border-subtle " ) } >
825878 < TextField
826879 required
827880 type = "number"
0 commit comments