From 14dff38bf5cd7d15ce9c6dfb9d19dcc48fe69995 Mon Sep 17 00:00:00 2001 From: Shreyas Sharma Date: Mon, 1 Jun 2026 12:51:38 +0530 Subject: [PATCH 1/3] fix(store): fixes after bug bash --- .../contact-center/store/src/task-utils.ts | 46 +++++++++++++++++-- packages/contact-center/task/src/helper.ts | 29 +++++++++++- 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/packages/contact-center/store/src/task-utils.ts b/packages/contact-center/store/src/task-utils.ts index 1b5144e24..ad7d9c032 100644 --- a/packages/contact-center/store/src/task-utils.ts +++ b/packages/contact-center/store/src/task-utils.ts @@ -109,13 +109,49 @@ export const setmTypeForEPDN = (task: ITask, mType: string) => { return mType; }; export const findMediaResourceId = (task: ITask, mType: string) => { - for (const key in task.data.interaction.media) { - if (task.data.interaction.media[key].mType === mType) { - return task.data.interaction.media[key].mediaResourceId; - } + if (!task?.data?.interaction?.media) { + return ''; + } + + const matchingMedia = Object.values(task.data.interaction.media).filter((media) => media.mType === mType); + + if (matchingMedia.length === 0) { + return ''; + } + + if (matchingMedia.length === 1) { + return matchingMedia[0].mediaResourceId; } - return ''; + // In some consult flows, stale consult legs are retained in media. Prefer the + // latest snapshot to avoid resolving an older consulted agent. + const getMediaRecencyScore = (media: Record, fallbackIndex: number): number => { + const candidateTimestamps = [ + media.lastUpdated, + media.joinTimestamp, + media.consultTimestamp, + media.holdTimestamp, + media.eventTime, + media.createdAt, + ]; + + for (const value of candidateTimestamps) { + if (typeof value === 'number' && Number.isFinite(value) && value > 0) { + return value; + } + } + + // Fall back to the object traversal order if no timestamp exists. + return fallbackIndex; + }; + + const latestMedia = matchingMedia.reduce((latest, media, index) => { + const latestScore = getMediaRecencyScore(latest as Record, index - 1); + const currentScore = getMediaRecencyScore(media as Record, index); + return currentScore >= latestScore ? media : latest; + }); + + return latestMedia.mediaResourceId || ''; }; /** diff --git a/packages/contact-center/task/src/helper.ts b/packages/contact-center/task/src/helper.ts index 42564dbf6..d4d337762 100644 --- a/packages/contact-center/task/src/helper.ts +++ b/packages/contact-center/task/src/helper.ts @@ -322,6 +322,9 @@ export const useCallControl = (props: useCallControlProps) => { const prevIsConsultingRef = useRef( !!(initialControls?.consult?.endConsult?.isVisible || initialControls?.main?.endConsult?.isVisible) ); + const consultVisibilityRef = useRef( + !!(initialControls?.consult?.endConsult?.isVisible || initialControls?.main?.endConsult?.isVisible) + ); const [lastTargetType, setLastTargetType] = useState(TARGET_TYPE.AGENT); const [conferenceParticipants, setConferenceParticipants] = useState([]); const lastWrapupAuxCodeIdRef = useRef(null); @@ -415,6 +418,24 @@ export const useCallControl = (props: useCallControlProps) => { // Use custom hook for hold timer management const holdTime = useHoldTimer(currentTask, controls); + useEffect(() => { + const isConsulting = !!(controls?.consult?.endConsult?.isVisible || controls?.main?.endConsult?.isVisible); + const wasConsulting = consultVisibilityRef.current; + + if (wasConsulting && !isConsulting) { + setConsultAgentName('Consult Agent'); + setConsultTimerLabel(TIMER_LABEL_CONSULTING); + setConsultTimerTimestamp(0); + setLastTargetType(TARGET_TYPE.AGENT); + store.setIsQueueConsultInProgress(false); + store.setCurrentConsultQueueId(null); + store.setLastConsultDestination(null); + store.setConsultStartTimeStamp(null); + } + + consultVisibilityRef.current = isConsulting; + }, [controls?.consult?.endConsult?.isVisible, controls?.main?.endConsult?.isVisible]); + useEffect(() => { if (currentTask && store?.cc?.agentConfig?.agentId) { const participants = getConferenceParticipants(currentTask, store.cc.agentConfig.agentId); @@ -424,9 +445,13 @@ export const useCallControl = (props: useCallControlProps) => { // Function to extract consulting agent information const extractConsultingAgent = useCallback(() => { try { - if (!currentTask?.data?.interaction?.participants) return; + // currentTask.data can briefly lag behind the freshest state-machine snapshot. + // Prefer the latest taskData so consult UI always reflects the newest consult leg. + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const latestTaskData = (currentTask as any)?.state?.context?.taskData; + const interaction = latestTaskData?.interaction ?? currentTask?.data?.interaction; + if (!interaction?.participants) return; - const {interaction} = currentTask.data; const myAgentId = store.cc.agentConfig?.agentId; const currentDestination = store.lastConsultDestination; const destinationType = currentDestination?.destinationType; From e59d589d7a2e5fec16083c4670106ca41c453161 Mon Sep 17 00:00:00 2001 From: Shreyas Sharma Date: Mon, 1 Jun 2026 17:58:06 +0530 Subject: [PATCH 2/3] fix(task-refactor): more fixes --- .../task/CallControlCAD/call-control-cad.tsx | 3 +- .../task/CallControlCAD/call-control-cad.tsx | 29 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/contact-center/cc-components/src/components/task/CallControlCAD/call-control-cad.tsx b/packages/contact-center/cc-components/src/components/task/CallControlCAD/call-control-cad.tsx index 037638787..a04f46774 100644 --- a/packages/contact-center/cc-components/src/components/task/CallControlCAD/call-control-cad.tsx +++ b/packages/contact-center/cc-components/src/components/task/CallControlCAD/call-control-cad.tsx @@ -63,6 +63,7 @@ const CallControlCADComponent: React.FC = (props) => const isTelephony = mediaChannel === MediaChannelType.TELEPHONY; const participantsCount = conferenceParticipants?.length || 1; const participantsLabel = participantsCount === 1 ? 'Participant' : 'Participants'; + const shouldShowParticipantsList = (conferenceParticipants?.length || 0) > 1; const customerName = currentTask?.data?.interaction?.callAssociatedDetails?.customerName; @@ -188,7 +189,7 @@ const CallControlCADComponent: React.FC = (props) => )} - {controls?.main?.exitConference?.isVisible && !controls?.main?.wrapup?.isVisible && ( + {shouldShowParticipantsList && !controls?.main?.wrapup?.isVisible && ( <>
diff --git a/packages/contact-center/cc-components/tests/components/task/CallControlCAD/call-control-cad.tsx b/packages/contact-center/cc-components/tests/components/task/CallControlCAD/call-control-cad.tsx index bd2f66e45..f076fc90f 100644 --- a/packages/contact-center/cc-components/tests/components/task/CallControlCAD/call-control-cad.tsx +++ b/packages/contact-center/cc-components/tests/components/task/CallControlCAD/call-control-cad.tsx @@ -379,4 +379,33 @@ describe('CallControlCADComponent', () => { expect(screen.queryByText(/On hold/)).not.toBeInTheDocument(); }); }); + + describe('conference participants list visibility', () => { + it('shows participants list when there are more than two participants total', () => { + const screen = render( + + ); + + expect(screen.getByTestId('call-control:participants-trigger')).toBeInTheDocument(); + }); + + it('hides participants list when two or fewer participants are present in total', () => { + const screen = render( + + ); + + expect(screen.queryByTestId('call-control:participants-trigger')).not.toBeInTheDocument(); + }); + }); }); From 4ee2720458523d2019e1c68cb1608eafe0258c5b Mon Sep 17 00:00:00 2001 From: Shreyas Sharma Date: Tue, 2 Jun 2026 08:32:51 +0530 Subject: [PATCH 3/3] fix(store): bump contact-center sdk task-refactor build Update @webex/contact-center from task-refactor.6 to task-refactor.7 in store dependencies and lockfile so this branch uses the latest SDK fixes. Co-authored-by: Cursor --- packages/contact-center/store/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/contact-center/store/package.json b/packages/contact-center/store/package.json index 64c8ed028..be8affc80 100644 --- a/packages/contact-center/store/package.json +++ b/packages/contact-center/store/package.json @@ -23,7 +23,7 @@ "deploy:npm": "yarn npm publish" }, "dependencies": { - "@webex/contact-center": "3.12.0-task-refactor.6", + "@webex/contact-center": "3.12.0-task-refactor.7", "mobx": "6.13.5", "typescript": "5.6.3" }, diff --git a/yarn.lock b/yarn.lock index c6e19aded..2c6ac27b1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9544,7 +9544,7 @@ __metadata: "@testing-library/react": "npm:16.0.1" "@types/jest": "npm:29.5.14" "@types/react-test-renderer": "npm:18" - "@webex/contact-center": "npm:3.12.0-task-refactor.6" + "@webex/contact-center": "npm:3.12.0-task-refactor.7" "@webex/test-fixtures": "workspace:*" babel-jest: "npm:29.7.0" babel-loader: "npm:9.2.1" @@ -9937,9 +9937,9 @@ __metadata: languageName: node linkType: hard -"@webex/contact-center@npm:3.12.0-task-refactor.6": - version: 3.12.0-task-refactor.6 - resolution: "@webex/contact-center@npm:3.12.0-task-refactor.6" +"@webex/contact-center@npm:3.12.0-task-refactor.7": + version: 3.12.0-task-refactor.7 + resolution: "@webex/contact-center@npm:3.12.0-task-refactor.7" dependencies: "@types/platform": "npm:1.3.4" "@webex/calling": "npm:3.12.0-task-refactor.1" @@ -9953,7 +9953,7 @@ __metadata: lodash: "npm:^4.17.21" uuid: "npm:^3.3.2" xstate: "npm:5.24.0" - checksum: 10c0/e529d6ca11cec201e116cb655407a26c88f5c4c08d8b5b2c0a603e6b9c029fc893945c8035ec8d6fdd5d5e87d600483246aa87d66999a5348064fabbe9110322 + checksum: 10c0/663407a7eb7003f46c9b8efaa3c8a711a2e883a94b341810d8d7a5e2fc106e88f311824ed0dff6e5a03fea0da814298bc5ea184fee14470bdf09d42f810cdfef languageName: node linkType: hard