Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ import {
import { showToast } from "@calcom/ui/components/toast";

import {
useTeamMembersWithSegment,
useTeamMembersWithSegmentPlatform,
} from "../../../../../packages/platform/atoms/event-types/hooks/useTeamMembersWithSegment";
} from "@calcom/atoms/event-types/hooks/useTeamMembersWithSegmentPlatform";
import { useTeamMembersWithSegment } from "@calcom/web/modules/event-types/hooks/useTeamMembersWithSegment";

type TeamMemberItemProps = {
member: Omit<TeamMember, "defaultScheduleId"> & { weight?: number };
Expand Down Expand Up @@ -125,7 +125,7 @@ export const EditWeightsForAllTeamMembers = ({

const useTeamMembersHook = isPlatform ? useTeamMembersWithSegmentPlatform : useTeamMembersWithSegment;

const { teamMembers, localWeightsInitialValues } = useTeamMembersHook({
const { teamMembers, localWeightsInitialValues, isPending } = useTeamMembersHook({
initialTeamMembers,
assignRRMembersUsingSegment,
teamId,
Expand Down Expand Up @@ -301,10 +301,10 @@ export const EditWeightsForAllTeamMembers = ({
/>

<div className="flex max-h-[80dvh] flex-col overflow-y-auto rounded-md border">
{filteredMembers.map((member) => (
{teamMembers.map((member) => (
<TeamMemberItem key={member.value} member={member} onWeightChange={handleWeightChange} />
))}
{filteredMembers.length === 0 && (
{teamMembers.length === 0 && (
<div className="text-subtle py-4 text-center text-sm">{t("no_members_found")}</div>
)}
Comment on lines +304 to 309
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical regression: Rendering bypasses search filter and weight merging.

The list now renders teamMembers directly instead of filteredMembers, which breaks:

  1. Search functionality - searchQuery filtering is no longer applied
  2. Weight display - localWeights values are not merged into the rendered members
  3. Member filtering - The assignAllTeamMembers condition (lines 242-248) is bypassed

The filteredMembers memo (lines 231-249) is still computed but unused.

🐛 Proposed fix to restore filteredMembers usage
               <div className="flex max-h-[80dvh] flex-col overflow-y-auto rounded-md border">
-                {teamMembers.map((member) => (
+                {filteredMembers.map((member) => (
                   <TeamMemberItem key={member.value} member={member} onWeightChange={handleWeightChange} />
                 ))}
-                {teamMembers.length === 0 && (
+                {filteredMembers.length === 0 && (
                   <div className="text-subtle py-4 text-center text-sm">{t("no_members_found")}</div>
                 )}
               </div>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{teamMembers.map((member) => (
<TeamMemberItem key={member.value} member={member} onWeightChange={handleWeightChange} />
))}
{filteredMembers.length === 0 && (
{teamMembers.length === 0 && (
<div className="text-subtle py-4 text-center text-sm">{t("no_members_found")}</div>
)}
{filteredMembers.map((member) => (
<TeamMemberItem key={member.value} member={member} onWeightChange={handleWeightChange} />
))}
{filteredMembers.length === 0 && (
<div className="text-subtle py-4 text-center text-sm">{t("no_members_found")}</div>
)}
🤖 Prompt for AI Agents
In `@apps/web/modules/event-types/components/EditWeightsForAllTeamMembers.tsx`
around lines 304 - 309, The list rendering in EditWeightsForAllTeamMembers
incorrectly maps over teamMembers, bypassing the filteredMembers memo and
breaking search/filter/weight merging; update the render to map over
filteredMembers (which already accounts for assignAllTeamMembers and
searchQuery) and ensure each item passed to TeamMemberItem reflects merged
weights from localWeights (use the same merge logic used when computing
filteredMembers) and still passes onWeightChange={handleWeightChange}; this
restores search filtering, localWeights display, and the assignAllTeamMembers
behavior.

</div>
Expand Down
37 changes: 37 additions & 0 deletions apps/web/modules/event-types/hooks/useTeamMembersWithSegment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useQuery } from "@tanstack/react-query";
import type { AttributesQueryValue } from "@calcom/lib/raqb/types";
import { trpc } from "@calcom/trpc/react";
import { type UseTeamMembersWithSegmentProps, useProcessTeamMembersData } from "@calcom/atoms/event-types/hooks/useTeamMembersWithSegmentPlatform";

export const useTeamMembersWithSegment = ({
initialTeamMembers,
assignRRMembersUsingSegment,
teamId,
queryValue,
value,
}: UseTeamMembersWithSegmentProps) => {
const { data: matchingTeamMembersWithResult, isPending } =
trpc.viewer.attributes.findTeamMembersMatchingAttributeLogic.useQuery(
{
teamId: teamId || 0,
attributesQueryValue: queryValue as AttributesQueryValue,
_enablePerf: true,
},
{
enabled: assignRRMembersUsingSegment && !!queryValue && !!teamId,
}
);

const { teamMembers, localWeightsInitialValues } = useProcessTeamMembersData({
initialTeamMembers,
assignRRMembersUsingSegment,
matchingTeamMembersWithResult: matchingTeamMembersWithResult?.result ? { result: matchingTeamMembersWithResult.result } : matchingTeamMembersWithResult,
value,
});

return {
teamMembers,
localWeightsInitialValues,
isPending,
};
};
32 changes: 32 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,38 @@
}
}
}
},
{
"includes": [
"packages/platform/atoms/**/*.{ts,tsx,js,jsx,mts,mjs,cjs,cts}"
],
"linter": {
"rules": {
"style": {
"noRestrictedImports": {
"level": "error",
"options": {
"patterns": [
{
"group": [
"@calcom/trpc/react",
"@calcom/trpc/react/**"
],
"message": "atoms package should not import from @calcom/trpc/react."
},
{
"group": [
"../../trpc/react",
"../../trpc/react/**"
],
"message": "atoms package should not import from trpc/react."
}
]
}
}
}
}
}
}
]
}
8 changes: 4 additions & 4 deletions packages/platform/atoms/availability/AvailabilitySettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import WebSchedule, {
import { availabilityAsString } from "@calcom/lib/availability";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { sortAvailabilityStrings } from "@calcom/lib/weekstart";
import type { RouterOutputs } from "@calcom/trpc/react";
import type { TravelScheduleRepository } from "@calcom/features/travelSchedule/repositories/TravelScheduleRepository";
import type { TimeRange, WorkingHours } from "@calcom/types/schedule";
import classNames from "@calcom/ui/classNames";
import { Button } from "@calcom/ui/components/button";
Expand Down Expand Up @@ -99,7 +99,7 @@ export type AvailabilitySettingsScheduleType = {
type AvailabilitySettingsProps = {
skeletonLabel?: string;
schedule: AvailabilitySettingsScheduleType;
travelSchedules?: RouterOutputs["viewer"]["travelSchedules"]["get"];
travelSchedules?: Awaited<ReturnType<typeof TravelScheduleRepository.findTravelSchedulesByUserId>>;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find all usages of AvailabilitySettings component
rg -n '<AvailabilitySettings' --type=tsx -g '!**/AvailabilitySettings.tsx'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 113


🏁 Script executed:

#!/bin/bash
# Find the AvailabilitySettings file and examine lines 102 and 198
fd -e tsx -p '*AvailabilitySettings.tsx' | head -5

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 390


🏁 Script executed:

#!/bin/bash
# Count lines to understand file size before reading
wc -l packages/platform/atoms/availability/AvailabilitySettings.tsx

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 151


🏁 Script executed:

#!/bin/bash
# Read the AvailabilitySettings file to see lines 102 and 198
sed -n '95,110p; 190,205p' packages/platform/atoms/availability/AvailabilitySettings.tsx

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 994


🏁 Script executed:

#!/bin/bash
# Find all usages of AvailabilitySettings component - search for the component name being used
rg -n '<AvailabilitySettings' --type=ts | head -20

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 888


🏁 Script executed:

#!/bin/bash
# Find where travelSchedules prop is passed to AvailabilitySettings
rg -n 'travelSchedules' packages/platform/atoms/availability/ -A2 -B2

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 3178


🏁 Script executed:

#!/bin/bash
# Find TravelScheduleRepository to understand the return type
fd -name '*TravelScheduleRepository*'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 316


🏁 Script executed:

#!/bin/bash
# Find TravelScheduleRepository file with corrected syntax
fd 'TravelScheduleRepository'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 159


🏁 Script executed:

#!/bin/bash
# Check the consumer files to see what types they pass for travelSchedules
cat -n packages/platform/atoms/availability/wrappers/AvailabilitySettingsPlatformWrapper.tsx | sed -n '145,160p'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 552


🏁 Script executed:

#!/bin/bash
# Check another consumer file
cat -n apps/web/modules/availability/[schedule]/schedule-view.tsx | sed -n '100,120p'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 909


🏁 Script executed:

#!/bin/bash
# Search for the old type RouterOutputs to see if it's still used
rg 'RouterOutputs.*travelSchedules.*get'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 473


🏁 Script executed:

#!/bin/bash
# Find where TravelScheduleRepository.findTravelSchedulesByUserId is used/called
rg 'findTravelSchedulesByUserId'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 933


🏁 Script executed:

#!/bin/bash
# Check the handler to see what it returns
cat -n packages/trpc/server/routers/viewer/travelSchedules/getTravelSchedules.handler.ts

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 617


🏁 Script executed:

#!/bin/bash
# Check schedule-view.tsx more broadly to understand types
cat -n apps/web/modules/availability/[schedule]/schedule-view.tsx | sed -n '1,50p'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 2619


🏁 Script executed:

#!/bin/bash
# Check what RouterOutputs["viewer"]["travelSchedules"]["get"] is
rg -A5 '"viewer".*travelSchedules' --type=ts | head -30

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 1763


🏁 Script executed:

#!/bin/bash
# Check TravelScheduleRepository.findTravelSchedulesByUserId implementation
cat -n packages/features/travelSchedule/repositories/TravelScheduleRepository.ts

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 632


🏁 Script executed:

#!/bin/bash
# Check how the TRPC route is structured
fd '*travelSchedules*' -t f | grep -E '(router|procedures)'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 382


🏁 Script executed:

#!/bin/bash
# Look for the TRPC route definition for travelSchedules
rg 'travelSchedules.*procedure' -A5

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 68


🏁 Script executed:

#!/bin/bash
# Look for the TRPC router structure
fd -name '*.ts' --type f -path '*/routers/viewer/*' | grep -i travel

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 316


🏁 Script executed:

#!/bin/bash
# Check the TRPC router definition for travelSchedules
rg -A10 'travelSchedules.*:' packages/trpc/server/routers/viewer/ | head -30

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 2267


🏁 Script executed:

#!/bin/bash
# Check if there are any TS compilation errors or type mismatches by looking at type definitions
cat -n packages/trpc/react/index.ts | sed -n '1,50p'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 263


🏁 Script executed:

#!/bin/bash
# Find the travelSchedules router
fd 'travelSchedules' --type f -path '*/routers/viewer/*'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 254


🏁 Script executed:

#!/bin/bash
# Check the structure of the travelSchedules router
find packages/trpc/server/routers/viewer -name '*travelSchedule*' -type f

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 68


🏁 Script executed:

#!/bin/bash
# Look at the structure of the handler being exported
rg -B5 -A15 'getTravelSchedulesHandler' packages/trpc/server/routers/viewer/travelSchedules/

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 1889


🏁 Script executed:

#!/bin/bash
# Check the procedure definition in the router
cat packages/trpc/server/routers/viewer/travelSchedules/getTravelSchedules.handler.ts
cat packages/trpc/server/routers/viewer/travelSchedules/getTravelSchedules.ts 2>/dev/null || echo "File not found, checking for other files:"
find packages/trpc/server/routers/viewer/travelSchedules -type f

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 802


🏁 Script executed:

#!/bin/bash
# Check for any TypeScript compilation errors or type issues
# Look at the actual types that should be inferred
rg 'Awaited<ReturnType' packages/platform/atoms/availability/AvailabilitySettings.tsx

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 289


🏁 Script executed:

#!/bin/bash
# Check if schedule-view.tsx actually compiles/uses the type correctly
cat -n apps/web/modules/availability/[schedule]/schedule-view.tsx | sed -n '108,115p'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 414


🏁 Script executed:

#!/bin/bash
# Check what DateOverrideList expects (it receives travelSchedules)
cat -n packages/features/schedules/components/DateOverrideList.tsx | sed -n '1,40p'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 1799


🏁 Script executed:

#!/bin/bash
# Confirm that the schema or any other constraints don't differ
cat packages/trpc/server/routers/viewer/travelSchedules/getTravelSchedules.schema.ts

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 96


🏁 Script executed:

#!/bin/bash
# Check what AvailabilitySettings passes to DateOverrideList
cat -n packages/platform/atoms/availability/AvailabilitySettings.tsx | sed -n '240,250p'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 558


🏁 Script executed:

#!/bin/bash
# Search for where DateOverrideList receives the travelSchedules prop from AvailabilitySettings
rg -B3 -A3 'DateOverrideList' packages/platform/atoms/availability/AvailabilitySettings.tsx | head -40

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 805


🏁 Script executed:

#!/bin/bash
# Check what type the function accepts
cat -n packages/platform/atoms/availability/AvailabilitySettings.tsx | sed -n '230,260p'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 1412


🏁 Script executed:

#!/bin/bash
# Check if there's a type mismatch between what AvailabilitySettings provides and what DateOverrideList expects
# Look at the exact parameter type definition in DateOverrideList
cat -n packages/features/schedules/components/DateOverrideList.tsx | sed -n '36,42p'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 391


🏁 Script executed:

#!/bin/bash
# Verify the actual usage - does AvailabilitySettings pass the prop directly?
# Check the exact line where travelSchedules is passed from AvailabilitySettings to DateOverrideList
rg -n 'travelSchedules=' packages/platform/atoms/availability/AvailabilitySettings.tsx

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 193


🏁 Script executed:

#!/bin/bash
# Check if there are any type assertions or workarounds in AvailabilitySettings
cat -n packages/platform/atoms/availability/AvailabilitySettings.tsx | sed -n '100,115p'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 765


Type mismatch requires fixing: DateOverrideList incompatibility.

The prop type change at line 102 creates a type compatibility issue. AvailabilitySettings now declares travelSchedules as Awaited<ReturnType<typeof TravelScheduleRepository.findTravelSchedulesByUserId>>, but passes it to DateOverrideList (line 246), which expects RouterOutputs["viewer"]["travelSchedules"]["get"].

Although both types resolve to the same runtime shape, TypeScript treats them as different types. Either align DateOverrideList to accept the repository type, or use RouterOutputs["viewer"]["travelSchedules"]["get"] consistently in AvailabilitySettings.

🤖 Prompt for AI Agents
In `@packages/platform/atoms/availability/AvailabilitySettings.tsx` at line 102,
The prop type for travelSchedules in AvailabilitySettings was changed to
Awaited<ReturnType<typeof TravelScheduleRepository.findTravelSchedulesByUserId>>
which is structurally compatible but incompatible with the DateOverrideList prop
type RouterOutputs["viewer"]["travelSchedules"]["get"]; fix by making the types
identical: either change AvailabilitySettings' travelSchedules type to
RouterOutputs["viewer"]["travelSchedules"]["get"] or update DateOverrideList's
prop to accept Awaited<ReturnType<typeof
TravelScheduleRepository.findTravelSchedulesByUserId>> (or a shared alias/type
exported and used by both), referencing the symbols AvailabilitySettings,
travelSchedules, DateOverrideList,
RouterOutputs["viewer"]["travelSchedules"]["get"], and
TravelScheduleRepository.findTravelSchedulesByUserId so the compiler sees the
same declared type.

handleDelete: () => void;
allowDelete?: boolean;
allowSetToDefault?: boolean;
Expand Down Expand Up @@ -195,7 +195,7 @@ const DateOverride = ({
}: {
workingHours: WorkingHours[];
userTimeFormat: number | null;
travelSchedules?: RouterOutputs["viewer"]["travelSchedules"]["get"];
travelSchedules?: Awaited<ReturnType<typeof TravelScheduleRepository.findTravelSchedulesByUserId>>;
weekStart: 0 | 1 | 2 | 3 | 4 | 5 | 6;
overridesModalClassNames?: string;
classNames?: {
Expand Down Expand Up @@ -642,7 +642,7 @@ export const AvailabilitySettings = forwardRef<AvailabilitySettingsFormRef, Avai
form="availability-form"
loading={isSaving}
disabled={isLoading || !formHasChanges}
>
>
{t("save")}
</Button>
<Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { trpc } from "@calcom/trpc/react";
import { useAtomsContext } from "../../hooks/useAtomsContext";
import http from "../../lib/http";

interface UseTeamMembersWithSegmentProps {
export interface UseTeamMembersWithSegmentProps {
initialTeamMembers: TeamMember[];
assignRRMembersUsingSegment: boolean;
teamId?: number;
Expand All @@ -24,7 +24,7 @@ interface UseTeamMembersWithSegmentProps {
value: Host[];
}

const useProcessTeamMembersData = ({
export const useProcessTeamMembersData = ({
initialTeamMembers,
assignRRMembersUsingSegment,
matchingTeamMembersWithResult,
Expand Down Expand Up @@ -105,37 +105,4 @@ export const useTeamMembersWithSegmentPlatform = ({
localWeightsInitialValues,
isPending,
};
};

export const useTeamMembersWithSegment = ({
initialTeamMembers,
assignRRMembersUsingSegment,
teamId,
queryValue,
value,
}: UseTeamMembersWithSegmentProps) => {
const { data: matchingTeamMembersWithResult, isPending } =
trpc.viewer.attributes.findTeamMembersMatchingAttributeLogic.useQuery(
{
teamId: teamId || 0,
attributesQueryValue: queryValue as AttributesQueryValue,
_enablePerf: true,
},
{
enabled: assignRRMembersUsingSegment && !!queryValue && !!teamId,
}
);

const { teamMembers, localWeightsInitialValues } = useProcessTeamMembersData({
initialTeamMembers,
assignRRMembersUsingSegment,
matchingTeamMembersWithResult,
value,
});

return {
teamMembers,
localWeightsInitialValues,
isPending,
};
};
};
1 change: 1 addition & 0 deletions packages/platform/atoms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"./event-types/hooks/useEventTypeForm": "./event-types/hooks/useEventTypeForm.ts",
"./event-types/hooks/useHandleRouteChange": "./event-types/hooks/useHandleRouteChange.ts",
"./event-types/hooks/useTabsNavigations": "./event-types/hooks/useTabsNavigations.tsx",
"./event-types/hooks/useTeamMembersWithSegmentPlatform": "./event-types/hooks/useTeamMembersWithSegmentPlatform.tsx",
"./timezone": "./timezone/index.tsx"
},
"types": "./dist/index.d.ts",
Expand Down
1 change: 0 additions & 1 deletion packages/platform/atoms/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
"../../dayjs",
"../../prisma/zod-utils.ts",
"../../prisma/zod",
"../../trpc/react",
"../../trpc/server/routers/viewer/slots",
"../../trpc/server/types",
"../../features/eventtypes",
Expand Down
Loading