11import { useEffect , useCallback , useState , useMemo } from 'react' ;
22import { AddressBookEntriesResponse , AddressBookEntrySearchParams , ITask } from '@webex/contact-center' ;
3- import { useCallControlProps , UseTaskListProps , UseTaskProps , useOutdialCallProps } from './task.types' ;
3+ import {
4+ useCallControlProps ,
5+ UseTaskListProps ,
6+ UseTaskProps ,
7+ useOutdialCallProps ,
8+ TargetType ,
9+ TARGET_TYPE ,
10+ } from './task.types' ;
411import store , {
512 TASK_EVENTS ,
613 BuddyDetails ,
@@ -302,7 +309,7 @@ export const useCallControl = (props: useCallControlProps) => {
302309 // Consult timer labels and timestamps
303310 const [ consultTimerLabel , setConsultTimerLabel ] = useState < string > ( TIMER_LABEL_CONSULTING ) ;
304311 const [ consultTimerTimestamp , setConsultTimerTimestamp ] = useState < number > ( 0 ) ;
305- const [ lastTargetType , setLastTargetType ] = useState < 'agent' | 'queue' > ( 'agent' ) ;
312+ const [ lastTargetType , setLastTargetType ] = useState < TargetType > ( TARGET_TYPE . AGENT ) ;
306313 const [ conferenceParticipants , setConferenceParticipants ] = useState < Participant [ ] > ( [ ] ) ;
307314
308315 // Use custom hook for hold timer management
@@ -322,21 +329,111 @@ export const useCallControl = (props: useCallControlProps) => {
322329 const { interaction} = currentTask . data ;
323330 const myAgentId = store . cc . agentConfig ?. agentId ;
324331
325- // Find all agent participants except the current agent
326- const otherAgents = Object . values ( interaction . participants || { } ) . filter (
327- ( participant ) : participant is Participant =>
328- ( participant as Participant ) . pType === 'Agent' && ( participant as Participant ) . id !== myAgentId
329- ) ;
332+ // For Entry Point or Dial Number consults, check if destination agent has joined
333+ if ( lastTargetType === TARGET_TYPE . ENTRY_POINT || lastTargetType === TARGET_TYPE . DIAL_NUMBER ) {
334+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
335+ const consultDestinationAgentName = ( interaction as any ) . callProcessingDetails ?. consultDestinationAgentName ;
336+
337+ if ( consultDestinationAgentName ) {
338+ // Destination agent has joined, show their name
339+ setConsultAgentName ( consultDestinationAgentName ) ;
340+ logger . info ( `${ lastTargetType } consult answered - showing agent name: ${ consultDestinationAgentName } ` , {
341+ module : 'widget-cc-task#helper.ts' ,
342+ method : 'useCallControl#extractConsultingAgent' ,
343+ } ) ;
344+ } else {
345+ // Still ringing - find the EP/DN participant in the consult media
346+ const consultMediaResourceId = findMediaResourceId ( currentTask , 'consult' ) ;
347+
348+ if ( consultMediaResourceId && interaction . media ?. [ consultMediaResourceId ] ) {
349+ const consultMedia = interaction . media [ consultMediaResourceId ] ;
350+ // Find the participant in consult media who is not the current agent
351+ const consultParticipantId = consultMedia . participants ?. find (
352+ ( participantId : string ) => participantId !== myAgentId
353+ ) ;
354+
355+ if ( consultParticipantId && interaction . participants [ consultParticipantId ] ) {
356+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
357+ const participant = interaction . participants [ consultParticipantId ] as any ;
358+ const phoneNumber = participant . dn || participant . id ;
359+
360+ if ( phoneNumber && phoneNumber !== consultAgentName ) {
361+ setConsultAgentName ( phoneNumber ) ;
362+ logger . info ( `${ lastTargetType } consult ringing - showing phone number: ${ phoneNumber } ` , {
363+ module : 'widget-cc-task#helper.ts' ,
364+ method : 'useCallControl#extractConsultingAgent' ,
365+ } ) ;
366+ }
367+ }
368+ }
369+ }
370+ return ;
371+ }
330372
331- // Pick the first other agent (should only be one in a consult)
332- const foundAgent = otherAgents . length > 0 ? { id : otherAgents [ 0 ] . id , name : otherAgents [ 0 ] . name } : null ;
373+ // For regular agent consults, find the agent in the consult media
374+ const consultMediaResourceId = findMediaResourceId ( currentTask , 'consult' ) ;
333375
334- if ( foundAgent ) {
335- setConsultAgentName ( foundAgent . name ) ;
336- logger . info ( `Consulting agent detected: ${ foundAgent . name } ${ foundAgent . id } ` , {
337- module : 'widget-cc-task#helper.ts' ,
338- method : 'useCallControl#extractConsultingAgent' ,
376+ if ( consultMediaResourceId && interaction . media ?. [ consultMediaResourceId ] ) {
377+ const consultMedia = interaction . media [ consultMediaResourceId ] ;
378+ // Find the agent participant in consult media who is not the current agent
379+ const consultParticipantId = consultMedia . participants ?. find ( ( participantId : string ) => {
380+ const participant = interaction . participants [ participantId ] ;
381+ return participant && participant . id !== myAgentId && participant . pType === 'Agent' ;
339382 } ) ;
383+
384+ if ( consultParticipantId && interaction . participants [ consultParticipantId ] ) {
385+ const consultAgent = interaction . participants [ consultParticipantId ] ;
386+ setConsultAgentName ( consultAgent . name || consultAgent . id ) ;
387+ logger . info ( `Consulting agent detected: ${ consultAgent . name } ${ consultAgent . id } ` , {
388+ module : 'widget-cc-task#helper.ts' ,
389+ method : 'useCallControl#extractConsultingAgent' ,
390+ } ) ;
391+ }
392+ } else {
393+ // Fallback: Use old logic if consult media not found
394+ const otherAgents = Object . values ( interaction . participants || { } ) . filter (
395+ ( participant ) : participant is Participant =>
396+ ( participant as Participant ) . pType === 'Agent' && ( participant as Participant ) . id !== myAgentId
397+ ) ;
398+
399+ // In a conference with multiple agents, find the agent currently being consulted
400+ // Priority: 1) consultState="consulting" 2) most recent consultTimestamp
401+ let foundAgent : { id : string ; name : string } | null = null ;
402+
403+ if ( otherAgents . length > 0 ) {
404+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
405+ const consultingAgent = otherAgents . find ( ( agent : any ) => agent . consultState === 'consulting' ) ;
406+
407+ if ( consultingAgent ) {
408+ foundAgent = {
409+ id : consultingAgent . id ,
410+ name : consultingAgent . name ,
411+ } ;
412+ } else {
413+ // Fallback: Find agent with most recent consultTimestamp
414+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
415+ const agentWithMostRecentTimestamp = otherAgents . reduce ( ( latest : any , current : any ) => {
416+ const currentTimestamp = current . consultTimestamp || current . joinTimestamp || 0 ;
417+ const latestTimestamp = latest ? latest . consultTimestamp || latest . joinTimestamp || 0 : 0 ;
418+ return currentTimestamp >= latestTimestamp ? current : latest ;
419+ } , null ) ;
420+
421+ if ( agentWithMostRecentTimestamp ) {
422+ foundAgent = {
423+ id : agentWithMostRecentTimestamp . id ,
424+ name : agentWithMostRecentTimestamp . name ,
425+ } ;
426+ }
427+ }
428+ }
429+
430+ if ( foundAgent ) {
431+ setConsultAgentName ( foundAgent . name ) ;
432+ logger . info ( `Consulting agent detected (fallback): ${ foundAgent . name } ${ foundAgent . id } ` , {
433+ module : 'widget-cc-task#helper.ts' ,
434+ method : 'useCallControl#extractConsultingAgent' ,
435+ } ) ;
436+ }
340437 }
341438 } catch ( error ) {
342439 console . log ( 'error' , error ) ;
@@ -345,7 +442,7 @@ export const useCallControl = (props: useCallControlProps) => {
345442 method : 'extractConsultingAgent' ,
346443 } ) ;
347444 }
348- } , [ currentTask , logger ] ) ;
445+ } , [ currentTask , logger , lastTargetType , consultAgentName , setConsultAgentName ] ) ;
349446
350447 // Extract main call timestamp whenever currentTask changes
351448 useEffect ( ( ) => {
0 commit comments