From 3dd47580c85db052f3ffb269903b58feed1725e5 Mon Sep 17 00:00:00 2001 From: Amit91848 Date: Mon, 13 Jan 2025 17:49:30 +0530 Subject: [PATCH] feat: Allow adding fixed hosts when 'add all team members' is enabled for RR --- .../components/AddMembersWithSwitch.tsx | 27 ++++++++++++--- .../components/CheckedTeamSelect.tsx | 29 +++++++++++++--- .../assignment/EventTeamAssignmentTab.tsx | 33 +++++++++++++++++-- 3 files changed, 78 insertions(+), 11 deletions(-) diff --git a/packages/features/eventtypes/components/AddMembersWithSwitch.tsx b/packages/features/eventtypes/components/AddMembersWithSwitch.tsx index 46274d6fa4c699..47ea58265540da 100644 --- a/packages/features/eventtypes/components/AddMembersWithSwitch.tsx +++ b/packages/features/eventtypes/components/AddMembersWithSwitch.tsx @@ -63,6 +63,7 @@ const CheckedHostField = ({ helperText, isRRWeightsEnabled, customClassNames, + assignAllTeamMembers, ...rest }: { labelText?: string; @@ -73,18 +74,26 @@ const CheckedHostField = ({ options?: Options; helperText?: React.ReactNode | string; isRRWeightsEnabled?: boolean; + assignAllTeamMembers?: boolean; } & Omit>, "onChange" | "value">) => { return (
{labelText ? : <>} !!value.find((host) => host.userId.toString() === option.value)} - onChange={(options) => { + assignAllTeamMembers={assignAllTeamMembers} + isFixed={isFixed} + isOptionDisabled={(option) => { + if (assignAllTeamMembers && isFixed) { + return !!value.find((host) => host.isFixed && host.userId.toString() === option.value); + } + return !!value.find((host) => host.userId.toString() === option.value); + }} + onOptionChange={(options) => { onChange && onChange( options.map((option) => ({ - isFixed, + isFixed: option.isFixed ?? isFixed, userId: parseInt(option.value, 10), priority: option.priority ?? 2, weight: option.weight ?? 100, @@ -181,6 +190,7 @@ export type AddMembersWithSwitchProps = { isSegmentApplicable?: boolean; "data-testid"?: string; customClassNames?: AddMembersWithSwitchCustomClassNames; + onClearAllClick?: VoidFunction; }; const enum AssignmentState { @@ -189,6 +199,7 @@ const enum AssignmentState { ALL_TEAM_MEMBERS_ENABLED_AND_SEGMENT_APPLICABLE = "ALL_TEAM_MEMBERS_ENABLED_AND_SEGMENT_APPLICABLE", ALL_TEAM_MEMBERS_ENABLED_AND_SEGMENT_NOT_APPLICABLE = "ALL_TEAM_MEMBERS_ENABLED_AND_SEGMENT_NOT_APPLICABLE", TEAM_MEMBERS_IN_SEGMENT_ENABLED = "TEAM_MEMBERS_IN_SEGMENT_ENABLED", + FIXED_HOSTS_STATE = "FIXED_HOSTS_STATE", } function getAssignmentState({ @@ -196,12 +207,15 @@ function getAssignmentState({ assignRRMembersUsingSegment, isAssigningAllTeamMembersApplicable, isSegmentApplicable, + isFixedHosts, }: { assignAllTeamMembers: boolean; assignRRMembersUsingSegment: boolean; isAssigningAllTeamMembersApplicable: boolean; isSegmentApplicable?: boolean; + isFixedHosts?: boolean; }) { + if (isFixedHosts) return AssignmentState.FIXED_HOSTS_STATE; if (assignAllTeamMembers) { return isSegmentApplicable ? AssignmentState.ALL_TEAM_MEMBERS_ENABLED_AND_SEGMENT_APPLICABLE @@ -246,6 +260,7 @@ export function AddMembersWithSwitch({ teamId, isSegmentApplicable, customClassNames, + onClearAllClick, ...rest }: AddMembersWithSwitchProps) { const { t } = useLocale(); @@ -262,6 +277,7 @@ export function AddMembersWithSwitch({ assignRRMembersUsingSegment, isAssigningAllTeamMembersApplicable: automaticAddAllEnabled, isSegmentApplicable, + isFixedHosts: isFixed, }); const onAssignAllTeamMembersInactive = () => { @@ -300,10 +316,11 @@ export function AddMembersWithSwitch({ case AssignmentState.TOGGLES_OFF_AND_ALL_TEAM_MEMBERS_NOT_APPLICABLE: case AssignmentState.TOGGLES_OFF_AND_ALL_TEAM_MEMBERS_APPLICABLE: + case AssignmentState.FIXED_HOSTS_STATE: return ( <>
- {assignmentState === AssignmentState.TOGGLES_OFF_AND_ALL_TEAM_MEMBERS_APPLICABLE && ( + {assignmentState === AssignmentState.TOGGLES_OFF_AND_ALL_TEAM_MEMBERS_APPLICABLE && !isFixed && (
diff --git a/packages/features/eventtypes/components/CheckedTeamSelect.tsx b/packages/features/eventtypes/components/CheckedTeamSelect.tsx index 35df4cdbf94675..bd950f80b0ab41 100644 --- a/packages/features/eventtypes/components/CheckedTeamSelect.tsx +++ b/packages/features/eventtypes/components/CheckedTeamSelect.tsx @@ -45,12 +45,19 @@ export const CheckedTeamSelect = ({ value = [], isRRWeightsEnabled, customClassNames, + onClearAllClick, + onOptionChange, + assignAllTeamMembers, + isFixed, ...props -}: Omit, "value" | "onChange"> & { +}: Omit, "value"> & { value?: readonly CheckedSelectOption[]; - onChange: (value: readonly CheckedSelectOption[]) => void; + onOptionChange: (value: readonly CheckedSelectOption[]) => void; isRRWeightsEnabled?: boolean; customClassNames?: CheckedTeamSelectCustomClassNames; + onClearAllClick?: () => void; + assignAllTeamMembers?: boolean; + isFixed?: boolean; }) => { const isPlatform = useIsPlatform(); const [priorityDialogOpen, setPriorityDialogOpen] = useState(false); @@ -72,6 +79,12 @@ export const CheckedTeamSelect = ({ isMulti className={customClassNames?.hostsSelect?.select} innerClassNames={customClassNames?.hostsSelect?.innerClassNames} + onChange={(newValue, { action }) => { + onOptionChange(newValue); + if (action === "clear" && onClearAllClick) { + onClearAllClick(); + } + }} {...props} /> {/* This class name conditional looks a bit odd but it allows a seemless transition when using autoanimate @@ -149,7 +162,13 @@ export const CheckedTeamSelect = ({ props.onChange(value.filter((item) => item.value !== option.value))} + onClick={() => { + let newOption: CheckedSelectOption[] = []; + if (isFixed && assignAllTeamMembers) { + newOption = [{ ...option, isFixed: false }]; + } + onOptionChange([...value.filter((item) => item.value !== option.value), ...newOption]); + }} className={classNames( "my-auto ml-2 h-4 w-4", customClassNames?.selectedHostList?.listItem?.removeButton @@ -166,14 +185,14 @@ export const CheckedTeamSelect = ({ isOpenDialog={priorityDialogOpen} setIsOpenDialog={setPriorityDialogOpen} option={currentOption} - onChange={props.onChange} + onChange={onOptionChange} customClassNames={customClassNames?.priorityDialog} /> diff --git a/packages/features/eventtypes/components/tabs/assignment/EventTeamAssignmentTab.tsx b/packages/features/eventtypes/components/tabs/assignment/EventTeamAssignmentTab.tsx index 2cd833a8cc6ccf..8e597433da8a43 100644 --- a/packages/features/eventtypes/components/tabs/assignment/EventTeamAssignmentTab.tsx +++ b/packages/features/eventtypes/components/tabs/assignment/EventTeamAssignmentTab.tsx @@ -148,10 +148,28 @@ const FixedHosts = ({ const { t } = useLocale(); const { getValues, setValue } = useFormContext(); - const hasActiveFixedHosts = isRoundRobinEvent && getValues("hosts").some((host) => host.isFixed); + const currentHosts = getValues("hosts"); + const hasActiveFixedHosts = isRoundRobinEvent && currentHosts.some((host) => host.isFixed); const [isDisabled, setIsDisabled] = useState(hasActiveFixedHosts); + const setAllHostsAsRR = () => + setValue( + "hosts", + teamMembers.map((teamMember) => { + const host = currentHosts.find((host) => host.userId === parseInt(teamMember.value, 10)); + return { + isFixed: false, + userId: parseInt(teamMember.value, 10), + priority: host?.priority ?? 2, + weight: host?.weight ?? 100, + // if host was already added, retain scheduleId + scheduleId: host?.scheduleId || teamMember.defaultScheduleId, + }; + }), + { shouldDirty: true } + ); + return (
{!isRoundRobinEvent ? ( @@ -216,6 +234,9 @@ const FixedHosts = ({ switchContainerClassName={customClassNames?.container} onCheckedChange={(checked) => { if (!checked) { + if (assignAllTeamMembers) { + setAllHostsAsRR(); + } const rrHosts = getValues("hosts") .filter((host) => !host.isFixed) .sort((a, b) => (b.priority ?? 2) - (a.priority ?? 2)); @@ -236,6 +257,7 @@ const FixedHosts = ({ setAssignAllTeamMembers={setAssignAllTeamMembers} automaticAddAllEnabled={!isRoundRobinEvent} isFixed={true} + onClearAllClick={() => setAllHostsAsRR()} onActive={() => { const currentHosts = getValues("hosts"); setValue( @@ -531,7 +553,14 @@ const Hosts = ({ teamMembers={teamMembers} value={value} onChange={(changeValue) => { - onChange([...value.filter((host: Host) => !host.isFixed), ...updatedHosts(changeValue)]); + onChange([ + ...value.filter( + (host: Host) => + !host.isFixed && + !changeValue.some((changedHost) => changedHost.userId === host.userId) + ), + ...updatedHosts(changeValue), + ]); }} assignAllTeamMembers={assignAllTeamMembers} setAssignAllTeamMembers={setAssignAllTeamMembers}