@webex/contact-center 3.12.0-task-refactor.1 → 3.12.0-task-refactor.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/services/task/TaskManager.js +12 -1
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/state-machine/actions.js +7 -1
- package/dist/services/task/state-machine/actions.js.map +1 -1
- package/dist/services/task/state-machine/guards.js +8 -1
- package/dist/services/task/state-machine/guards.js.map +1 -1
- package/dist/services/task/state-machine/uiControlsComputer.js +15 -7
- package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -1
- package/dist/webex.js +1 -1
- package/package.json +1 -1
- package/src/services/task/TaskManager.ts +13 -1
- package/src/services/task/state-machine/actions.ts +14 -1
- package/src/services/task/state-machine/guards.ts +9 -1
- package/src/services/task/state-machine/uiControlsComputer.ts +22 -9
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_types","require","_constants","_TaskUtils","DISABLED","isVisible","isEnabled","VISIBLE_ENABLED","VISIBLE_DISABLED","getDefaultInteractionUIControls","accept","decline","hold","mute","end","transfer","consult","consultTransfer","endConsult","recording","conference","wrapup","exitConference","transferConference","mergeToConference","switch","createTaskUIControls","main","activeLeg","getDefaultUIControls","computeVoiceInteractionUIControls","state","context","config","fallbackTaskData","currentLeg","TaskState","IDLE","taskData","interaction","mainCallId","mainInteractionId","interactionId","isWebrtc","voiceVariant","VOICE_VARIANT","WEBRTC","isOutdial","outboundType","serverHold","getServerHoldStateForControls","customerInCall","getIsCustomerInCall","customerPresent","Boolean","participants","Object","values","some","p","pType","hasLeft","participantCount","getConferenceParticipantsCount","maxParticipants","MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE","selfAgentId","agentId","consultInProgress","getIsConsultInProgressForConferenceControls","conferenceFromBackend","getIsConferenceInProgress","consultInitiator","consultDestinationAgentJoined","consultCallHeld","consultFromConference","recordingControlsAvailable","stateImpliesHeld","HELD","RESUME_INITIATING","stateImpliesConnected","CONNECTED","HOLD_INITIATING","isHeld","isConnected","isConsulting","CONSULTING","CONSULT_INITIATING","CONF_INITIATING","isConferencing","CONFERENCING","isWrappingUp","WRAPPING_UP","selfInMainCall","media","includes","conferenceActive","inConference","isSoleAgentOnCall","isConsulted","getIsConsultedAgentForControls","isActive","hasFullControls","consultOwnedBySelf","consultingAgentId","hasConsultMedia","consultMediaResourceId","mType","hasParallelConsultLeg","consultLegOnHold","OFFERED","isTerminated","canHold","isEndTaskEnabled","isConnectedOrHeld","canFromConnected","canFromConference","isEndConsultEnabled","isRecordingEnabled","consultingFromConference","computeDigitalInteractionUIControls","getVoiceLegState","currentState","hasConsultLeg","mainState","consultState","isConsultingState","computeUIControls","TERMINATED","COMPLETED","uiControlConfig","channelType","TASK_CHANNEL_TYPE","VOICE","mainControls","consultControls","DIGITAL","haveInteractionUIControlsChanged","previous","next","keys","key","prev","curr","haveUIControlsChanged"],"sources":["uiControlsComputer.ts"],"sourcesContent":["/**\n * UI Controls Computer - Centralized logic for computing UI control states\n */\n\nimport {\n InteractionUIControls,\n TASK_CHANNEL_TYPE,\n TaskData,\n TaskUILeg,\n TaskUIControls,\n VOICE_VARIANT,\n} from '../types';\nimport {TaskContext, UIControlConfig} from './types';\nimport {TaskState, MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE} from './constants';\nimport {\n getIsCustomerInCall,\n getConferenceParticipantsCount,\n getIsConferenceInProgress,\n getIsConsultInProgressForConferenceControls,\n getIsConsultedAgentForControls,\n getServerHoldStateForControls,\n} from '../TaskUtils';\n\nconst DISABLED = {isVisible: false, isEnabled: false} as const;\nconst VISIBLE_ENABLED = {isVisible: true, isEnabled: true} as const;\nconst VISIBLE_DISABLED = {isVisible: true, isEnabled: false} as const;\n\nfunction getDefaultInteractionUIControls(): InteractionUIControls {\n return {\n accept: DISABLED,\n decline: DISABLED,\n hold: DISABLED,\n mute: DISABLED,\n end: DISABLED,\n transfer: DISABLED,\n consult: DISABLED,\n consultTransfer: DISABLED,\n endConsult: DISABLED,\n recording: DISABLED,\n conference: DISABLED,\n wrapup: DISABLED,\n exitConference: DISABLED,\n transferConference: DISABLED,\n mergeToConference: DISABLED,\n switch: DISABLED,\n };\n}\n\nfunction createTaskUIControls(\n main: InteractionUIControls,\n consult: InteractionUIControls,\n activeLeg: TaskUILeg\n): TaskUIControls {\n return {\n main,\n consult,\n activeLeg,\n };\n}\n\nexport function getDefaultUIControls(): TaskUIControls {\n return createTaskUIControls(\n getDefaultInteractionUIControls(),\n getDefaultInteractionUIControls(),\n 'main'\n );\n}\n\nfunction computeVoiceInteractionUIControls(\n state: TaskState,\n context: TaskContext,\n config: UIControlConfig,\n fallbackTaskData?: TaskData,\n currentLeg: TaskUILeg = 'main'\n): InteractionUIControls {\n // Early exit for idle\n if (state === TaskState.IDLE) {\n return getDefaultInteractionUIControls();\n }\n\n // Essential data\n const taskData = context.taskData ?? fallbackTaskData ?? null;\n const interaction = taskData?.interaction;\n const mainCallId = interaction?.mainInteractionId || taskData?.interactionId;\n const isWebrtc = config.voiceVariant === VOICE_VARIANT.WEBRTC;\n const isOutdial = interaction?.outboundType === 'OUTDIAL';\n const serverHold = getServerHoldStateForControls(context, mainCallId, fallbackTaskData);\n\n // Backend-derived checks\n const customerInCall =\n interaction && mainCallId ? getIsCustomerInCall(interaction, mainCallId) : false;\n // EP-DN/secondary legs can have incomplete media participant lists; fall back to participants map.\n const customerPresent =\n customerInCall ||\n Boolean(\n interaction &&\n interaction.participants &&\n Object.values(interaction.participants).some(\n (p: any) => p?.pType === 'Customer' && !p?.hasLeft\n )\n );\n const participantCount =\n interaction && mainCallId ? getConferenceParticipantsCount(interaction, mainCallId) : 0;\n const maxParticipants = participantCount >= MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE;\n const selfAgentId = config.agentId ?? taskData?.agentId;\n const consultInProgress = getIsConsultInProgressForConferenceControls(\n interaction,\n mainCallId,\n selfAgentId\n );\n const conferenceFromBackend = taskData ? getIsConferenceInProgress(taskData) : false;\n // Note: ownership is used by some controls; keep computations local to those controls\n\n // Context flags (set by state machine actions)\n const {consultInitiator, consultDestinationAgentJoined, consultCallHeld, consultFromConference} =\n context;\n const {recordingControlsAvailable} = context;\n\n const stateImpliesHeld = state === TaskState.HELD || state === TaskState.RESUME_INITIATING;\n const stateImpliesConnected =\n state === TaskState.CONNECTED || state === TaskState.HOLD_INITIATING;\n const isHeld = stateImpliesHeld || serverHold === true;\n const isConnected = stateImpliesConnected || (!stateImpliesHeld && serverHold === false);\n\n // State categories for cleaner logic\n const isConsulting =\n state === TaskState.CONSULTING ||\n state === TaskState.CONSULT_INITIATING ||\n state === TaskState.CONF_INITIATING;\n const isConferencing = state === TaskState.CONFERENCING;\n const isWrappingUp = state === TaskState.WRAPPING_UP;\n const selfInMainCall =\n Boolean(selfAgentId) &&\n Boolean(mainCallId) &&\n Boolean(interaction?.media?.[mainCallId]?.participants?.includes(selfAgentId as string));\n const conferenceActive = isConferencing || conferenceFromBackend || consultFromConference;\n // Treat consult initiator as \"in conference\" even if mainCall participant list lags while consulting.\n const inConference = conferenceActive && (isConferencing || selfInMainCall || consultInitiator);\n\n // Check if this is a consulted agent (must be after isConsulting is computed).\n const isSoleAgentOnCall = participantCount <= 1 && !isConsulting && !inConference;\n const isConsulted =\n inConference || isSoleAgentOnCall\n ? false\n : getIsConsultedAgentForControls(taskData, context, isConsulting);\n\n // Active call = can perform call operations\n const isActive =\n state === TaskState.CONNECTED ||\n state === TaskState.HELD ||\n state === TaskState.HOLD_INITIATING ||\n state === TaskState.RESUME_INITIATING ||\n isConsulting ||\n isConferencing;\n\n // Consulted agents have limited controls until they're in conference or wrapup\n // Use inConference (not isConferencing) so controls remain enabled after state downgrade\n const hasFullControls = !isConsulted || consultInitiator || inConference || isWrappingUp;\n const consultOwnedBySelf =\n consultInitiator || (Boolean(selfAgentId) && taskData?.consultingAgentId === selfAgentId);\n const hasConsultMedia = Boolean(\n taskData?.consultMediaResourceId ||\n Object.values(interaction?.media ?? {}).some((media: any) => media?.mType === 'consult')\n );\n const hasParallelConsultLeg =\n consultOwnedBySelf &&\n !isConsulting &&\n !isConsulted &&\n (consultInProgress || consultCallHeld || hasConsultMedia);\n const consultLegOnHold = isConsulting && consultCallHeld;\n\n return {\n // Accept/Decline: Voice tasks in offered state\n // For outdial, accept is disabled (auto-answer handles it), decline remains enabled\n // For Extension mode (non-WebRTC), accept shows as disabled \"Ringing\" button\n accept:\n state === TaskState.OFFERED && !interaction?.isTerminated\n ? {isVisible: true, isEnabled: isWebrtc && !isOutdial}\n : DISABLED,\n decline:\n isWebrtc && state === TaskState.OFFERED && !interaction?.isTerminated\n ? VISIBLE_ENABLED\n : DISABLED,\n\n // Hold: visible in connected/held/conference, disabled in conference/consulting\n hold: (() => {\n if (!hasFullControls) return DISABLED;\n if (consultOwnedBySelf && (isConsulting || hasParallelConsultLeg || consultCallHeld)) {\n return DISABLED;\n }\n if (hasParallelConsultLeg) return DISABLED;\n if (state === TaskState.OFFERED) return DISABLED;\n if (isWrappingUp) return DISABLED;\n // Visibility: connected || held || inConference\n if (!(isConnected || isHeld || inConference)) return DISABLED;\n // Enabled: (connected || held) && !inConference && !isConsulting\n const canHold = (isConnected || isHeld) && !inConference && !isConsulting;\n\n return canHold ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n })(),\n\n // Mute: WebRTC only, active calls; hidden entirely during wrapup\n mute: (() => {\n if (!isWebrtc) return DISABLED;\n if (isWrappingUp) return DISABLED;\n if (isConsulting) return VISIBLE_ENABLED;\n\n if (isConnected || isHeld || isConferencing) {\n if (inConference) return VISIBLE_ENABLED;\n\n return isHeld ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n }\n\n return DISABLED;\n })(),\n\n // End: varies by state; during consulting only on main leg (consult held)\n end: (() => {\n if (!config.isEndTaskEnabled) return DISABLED;\n if (hasParallelConsultLeg) return VISIBLE_DISABLED;\n\n if (isConsulting) {\n if (currentLeg === 'consult' && consultCallHeld) return DISABLED;\n\n return consultInitiator && consultCallHeld ? VISIBLE_ENABLED : DISABLED;\n }\n\n if (inConference) {\n if (isConsulted) return DISABLED;\n\n if (consultInProgress) return VISIBLE_DISABLED;\n\n return isWrappingUp ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n }\n if (!hasFullControls) return DISABLED;\n if (isActive) return isHeld || isWrappingUp ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n\n return DISABLED;\n })(),\n\n // Transfer: connected/held, not in conference\n transfer: (() => {\n if (hasParallelConsultLeg) {\n if (state === TaskState.CONNECTED) return VISIBLE_ENABLED;\n if (state === TaskState.HELD) return VISIBLE_DISABLED;\n }\n if (isConsulting) {\n if (!consultInitiator) return DISABLED;\n if (consultLegOnHold) return VISIBLE_DISABLED;\n\n return consultDestinationAgentJoined ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n }\n if (!hasFullControls || inConference) return DISABLED;\n if (state === TaskState.CONNECTED || state === TaskState.HELD) return VISIBLE_ENABLED;\n\n return DISABLED;\n })(),\n\n // Consult: connected/held/conference when conditions met\n consult: (() => {\n const isConnectedOrHeld = state === TaskState.CONNECTED || state === TaskState.HELD;\n\n if (hasParallelConsultLeg) return DISABLED;\n if (!hasFullControls || !(isConnectedOrHeld || inConference)) {\n return DISABLED;\n }\n\n // Enabled conditions differ by state\n const canFromConnected =\n !maxParticipants && customerPresent && !consultInProgress && !isConsulted;\n const canFromConference =\n !maxParticipants && customerPresent && !consultInProgress && !isConsulting;\n\n const isEnabled = inConference ? canFromConference : canFromConnected;\n\n return {isVisible: true, isEnabled};\n })(),\n\n // ConsultTransfer: always hidden (use transfer button)\n consultTransfer: DISABLED,\n\n // EndConsult: during consulting\n endConsult: (() => {\n if (!isConsulting) return DISABLED;\n if (isConsulted && isConferencing) return DISABLED;\n if (!isConsulted && isConferencing && !(consultInitiator && conferenceFromBackend)) {\n return DISABLED;\n }\n\n return {isVisible: true, isEnabled: consultInitiator || config.isEndConsultEnabled};\n })(),\n\n // Recording: connected/held only, not in consult/conference\n recording: (() => {\n if (!recordingControlsAvailable || !config.isRecordingEnabled) return DISABLED;\n if (!hasFullControls || isConsulting || inConference) return DISABLED;\n if (state === TaskState.CONNECTED || state === TaskState.HELD) {\n return VISIBLE_ENABLED;\n }\n\n return DISABLED;\n })(),\n\n // Conference: during consulting, enabled on both legs when agent joined\n // Label changes based on leg: \"Conference\" on main leg, \"Merge\" on consult leg\n conference: (() => {\n if (hasParallelConsultLeg) {\n if (state === TaskState.CONNECTED) {\n return maxParticipants ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n }\n if (state === TaskState.HELD) return VISIBLE_DISABLED;\n\n return DISABLED;\n }\n if (!hasFullControls || !isConsulting) return DISABLED;\n if (!consultInitiator) return DISABLED;\n if (consultLegOnHold) return VISIBLE_DISABLED;\n\n return consultDestinationAgentJoined && !maxParticipants ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n })(),\n\n // Wrapup: wrapping up state\n wrapup: isWrappingUp ? VISIBLE_ENABLED : DISABLED,\n\n // ExitConference: in conference, not consulting from conference\n exitConference: (() => {\n if (isConsulted && !isConferencing) return DISABLED;\n if (!inConference) return DISABLED;\n const consultingFromConference = consultInitiator && isConsulting && conferenceFromBackend;\n\n return consultingFromConference ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n })(),\n\n // TransferConference: in conference with active consult, owner consulting from conference\n transferConference: (() => {\n if (hasParallelConsultLeg || consultLegOnHold) return DISABLED;\n if (!inConference || !isConsulting) return DISABLED;\n if (!consultInitiator || isConsulted) return DISABLED;\n\n return consultDestinationAgentJoined ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n })(),\n\n // MergeToConference: mirrors conference control, enabled on both legs\n mergeToConference: (() => {\n if (!isConsulting || !consultInitiator) return DISABLED;\n if (consultLegOnHold) return VISIBLE_DISABLED;\n\n return consultDestinationAgentJoined && !maxParticipants ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n })(),\n\n // Switch: visible only on the currently active leg\n switch: (() => {\n if (currentLeg === 'consult') {\n if (!isConsulting || !consultInitiator || consultCallHeld) return DISABLED;\n\n return consultDestinationAgentJoined ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n }\n\n if (hasParallelConsultLeg && state === TaskState.CONNECTED) {\n return consultDestinationAgentJoined ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n }\n\n return DISABLED;\n })(),\n };\n}\n\nfunction computeDigitalInteractionUIControls(\n state: TaskState,\n context: TaskContext,\n fallbackTaskData?: TaskData\n): InteractionUIControls {\n const taskData = context.taskData ?? fallbackTaskData ?? null;\n const isTerminated = taskData?.interaction?.isTerminated ?? false;\n\n const isConnected = state === TaskState.CONNECTED;\n const isWrappingUp = state === TaskState.WRAPPING_UP;\n\n return {\n accept: state === TaskState.OFFERED ? VISIBLE_ENABLED : DISABLED,\n decline: DISABLED,\n hold: DISABLED,\n mute: DISABLED,\n end: isConnected && !isWrappingUp ? VISIBLE_ENABLED : DISABLED,\n transfer: isConnected && !isWrappingUp ? VISIBLE_ENABLED : DISABLED,\n consult: DISABLED,\n consultTransfer: DISABLED,\n endConsult: DISABLED,\n recording: DISABLED,\n conference: DISABLED,\n wrapup: isTerminated || isWrappingUp ? VISIBLE_ENABLED : DISABLED,\n exitConference: DISABLED,\n transferConference: DISABLED,\n mergeToConference: DISABLED,\n switch: DISABLED,\n };\n}\n\nfunction getVoiceLegState(\n currentState: TaskState,\n context: TaskContext,\n config: UIControlConfig,\n fallbackTaskData?: TaskData\n): {hasConsultLeg: boolean; activeLeg: TaskUILeg; mainState: TaskState; consultState: TaskState} {\n if (currentState === TaskState.WRAPPING_UP) {\n return {\n hasConsultLeg: false,\n activeLeg: 'main',\n mainState: currentState,\n consultState: TaskState.CONSULTING,\n };\n }\n\n const taskData = context.taskData ?? fallbackTaskData ?? null;\n const interaction = taskData?.interaction;\n const mainCallId = interaction?.mainInteractionId || taskData?.interactionId;\n const selfAgentId = config.agentId ?? taskData?.agentId;\n const consultInProgress = getIsConsultInProgressForConferenceControls(\n interaction,\n mainCallId,\n selfAgentId\n );\n const isConsultingState =\n currentState === TaskState.CONSULTING ||\n currentState === TaskState.CONSULT_INITIATING ||\n currentState === TaskState.CONF_INITIATING;\n const consultOwnedBySelf =\n context.consultInitiator ||\n (Boolean(selfAgentId) && taskData?.consultingAgentId === selfAgentId);\n const hasConsultMedia = Boolean(\n taskData?.consultMediaResourceId ||\n Object.values(interaction?.media ?? {}).some((media: any) => media?.mType === 'consult')\n );\n const hasConsultLeg = Boolean(\n consultOwnedBySelf &&\n !taskData?.isConsulted &&\n !interaction?.isTerminated &&\n (consultInProgress || isConsultingState || context.consultCallHeld || hasConsultMedia)\n );\n\n if (!hasConsultLeg) {\n return {\n hasConsultLeg: false,\n activeLeg: 'main',\n mainState: currentState,\n consultState: TaskState.CONSULTING,\n };\n }\n\n return {\n hasConsultLeg: true,\n activeLeg: context.consultCallHeld ? 'main' : 'consult',\n mainState: context.consultCallHeld ? TaskState.CONNECTED : TaskState.HELD,\n consultState: isConsultingState ? currentState : TaskState.CONSULTING,\n };\n}\n\nexport function computeUIControls(\n currentState: TaskState,\n context: TaskContext,\n fallbackTaskData?: TaskData\n): TaskUIControls {\n if (currentState === TaskState.TERMINATED || currentState === TaskState.COMPLETED) {\n return getDefaultUIControls();\n }\n\n switch (context.uiControlConfig.channelType) {\n case TASK_CHANNEL_TYPE.VOICE: {\n const {hasConsultLeg, activeLeg, mainState, consultState} = getVoiceLegState(\n currentState,\n context,\n context.uiControlConfig,\n fallbackTaskData\n );\n\n const mainControls = computeVoiceInteractionUIControls(\n mainState,\n context,\n context.uiControlConfig,\n fallbackTaskData,\n 'main'\n );\n const consultControls = hasConsultLeg\n ? computeVoiceInteractionUIControls(\n consultState,\n context,\n context.uiControlConfig,\n fallbackTaskData,\n 'consult'\n )\n : getDefaultInteractionUIControls();\n\n return createTaskUIControls(mainControls, consultControls, activeLeg);\n }\n case TASK_CHANNEL_TYPE.DIGITAL:\n return createTaskUIControls(\n computeDigitalInteractionUIControls(currentState, context, fallbackTaskData),\n getDefaultInteractionUIControls(),\n 'main'\n );\n default:\n return getDefaultUIControls();\n }\n}\n\nfunction haveInteractionUIControlsChanged(\n previous: InteractionUIControls,\n next: InteractionUIControls\n): boolean {\n return (Object.keys(next) as (keyof InteractionUIControls)[]).some((key) => {\n const prev = previous[key];\n const curr = next[key];\n\n return prev.isVisible !== curr.isVisible || prev.isEnabled !== curr.isEnabled;\n });\n}\n\nexport function haveUIControlsChanged(\n previous: TaskUIControls | undefined,\n next: TaskUIControls\n): boolean {\n if (!previous) return true;\n\n return (\n previous.activeLeg !== next.activeLeg ||\n haveInteractionUIControlsChanged(previous.main, next.main) ||\n haveInteractionUIControlsChanged(previous.consult, next.consult)\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_types","require","_constants","_TaskUtils","DISABLED","isVisible","isEnabled","VISIBLE_ENABLED","VISIBLE_DISABLED","getDefaultInteractionUIControls","accept","decline","hold","mute","end","transfer","consult","consultTransfer","endConsult","recording","conference","wrapup","exitConference","transferConference","mergeToConference","switch","createTaskUIControls","main","activeLeg","getDefaultUIControls","computeVoiceInteractionUIControls","state","context","config","fallbackTaskData","currentLeg","TaskState","IDLE","taskData","interaction","mainCallId","mainInteractionId","interactionId","isWebrtc","voiceVariant","VOICE_VARIANT","WEBRTC","isOutdial","outboundType","serverHold","getServerHoldStateForControls","customerInCall","getIsCustomerInCall","customerPresent","Boolean","participants","Object","values","some","p","pType","hasLeft","participantCount","getConferenceParticipantsCount","maxParticipants","MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE","selfAgentId","agentId","consultInProgress","getIsConsultInProgressForConferenceControls","conferenceFromBackend","getIsConferenceInProgress","consultInitiator","consultDestinationAgentJoined","consultDestinationType","consultCallHeld","consultFromConference","recordingControlsAvailable","isEpDnConsult","isConsultDestinationReady","stateImpliesHeld","HELD","RESUME_INITIATING","stateImpliesConnected","CONNECTED","HOLD_INITIATING","isHeld","isConnected","isConsulting","CONSULTING","CONSULT_INITIATING","CONF_INITIATING","isConferencing","CONFERENCING","isWrappingUp","WRAPPING_UP","selfInMainCall","media","includes","conferenceActive","inConference","isSoleAgentOnCall","isConsulted","getIsConsultedAgentForControls","isActive","hasFullControls","consultOwnedBySelf","consultingAgentId","hasConsultMedia","consultMediaResourceId","mType","hasParallelConsultLeg","consultLegOnHold","OFFERED","isTerminated","canHold","isEndTaskEnabled","isConnectedOrHeld","canFromConnected","canFromConference","isEndConsultEnabled","isRecordingEnabled","consultingFromConference","computeDigitalInteractionUIControls","getVoiceLegState","currentState","hasConsultLeg","mainState","consultState","isConsultingState","computeUIControls","TERMINATED","COMPLETED","uiControlConfig","channelType","TASK_CHANNEL_TYPE","VOICE","mainControls","consultControls","DIGITAL","haveInteractionUIControlsChanged","previous","next","keys","key","prev","curr","haveUIControlsChanged"],"sources":["uiControlsComputer.ts"],"sourcesContent":["/**\n * UI Controls Computer - Centralized logic for computing UI control states\n */\n\nimport {\n InteractionUIControls,\n TASK_CHANNEL_TYPE,\n TaskData,\n TaskUILeg,\n TaskUIControls,\n VOICE_VARIANT,\n} from '../types';\nimport {TaskContext, UIControlConfig} from './types';\nimport {TaskState, MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE} from './constants';\nimport {\n getIsCustomerInCall,\n getConferenceParticipantsCount,\n getIsConferenceInProgress,\n getIsConsultInProgressForConferenceControls,\n getIsConsultedAgentForControls,\n getServerHoldStateForControls,\n} from '../TaskUtils';\n\nconst DISABLED = {isVisible: false, isEnabled: false} as const;\nconst VISIBLE_ENABLED = {isVisible: true, isEnabled: true} as const;\nconst VISIBLE_DISABLED = {isVisible: true, isEnabled: false} as const;\n\nfunction getDefaultInteractionUIControls(): InteractionUIControls {\n return {\n accept: DISABLED,\n decline: DISABLED,\n hold: DISABLED,\n mute: DISABLED,\n end: DISABLED,\n transfer: DISABLED,\n consult: DISABLED,\n consultTransfer: DISABLED,\n endConsult: DISABLED,\n recording: DISABLED,\n conference: DISABLED,\n wrapup: DISABLED,\n exitConference: DISABLED,\n transferConference: DISABLED,\n mergeToConference: DISABLED,\n switch: DISABLED,\n };\n}\n\nfunction createTaskUIControls(\n main: InteractionUIControls,\n consult: InteractionUIControls,\n activeLeg: TaskUILeg\n): TaskUIControls {\n return {\n main,\n consult,\n activeLeg,\n };\n}\n\nexport function getDefaultUIControls(): TaskUIControls {\n return createTaskUIControls(\n getDefaultInteractionUIControls(),\n getDefaultInteractionUIControls(),\n 'main'\n );\n}\n\nfunction computeVoiceInteractionUIControls(\n state: TaskState,\n context: TaskContext,\n config: UIControlConfig,\n fallbackTaskData?: TaskData,\n currentLeg: TaskUILeg = 'main'\n): InteractionUIControls {\n // Early exit for idle\n if (state === TaskState.IDLE) {\n return getDefaultInteractionUIControls();\n }\n\n // Essential data\n const taskData = context.taskData ?? fallbackTaskData ?? null;\n const interaction = taskData?.interaction;\n const mainCallId = interaction?.mainInteractionId || taskData?.interactionId;\n const isWebrtc = config.voiceVariant === VOICE_VARIANT.WEBRTC;\n const isOutdial = interaction?.outboundType === 'OUTDIAL';\n const serverHold = getServerHoldStateForControls(context, mainCallId, fallbackTaskData);\n\n // Backend-derived checks\n const customerInCall =\n interaction && mainCallId ? getIsCustomerInCall(interaction, mainCallId) : false;\n // EP-DN/secondary legs can have incomplete media participant lists; fall back to participants map.\n const customerPresent =\n customerInCall ||\n Boolean(\n interaction &&\n interaction.participants &&\n Object.values(interaction.participants).some(\n (p: any) => p?.pType === 'Customer' && !p?.hasLeft\n )\n );\n const participantCount =\n interaction && mainCallId ? getConferenceParticipantsCount(interaction, mainCallId) : 0;\n const maxParticipants = participantCount >= MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE;\n const selfAgentId = config.agentId ?? taskData?.agentId;\n const consultInProgress = getIsConsultInProgressForConferenceControls(\n interaction,\n mainCallId,\n selfAgentId\n );\n const conferenceFromBackend = taskData ? getIsConferenceInProgress(taskData) : false;\n // Note: ownership is used by some controls; keep computations local to those controls\n\n // Context flags (set by state machine actions)\n const {\n consultInitiator,\n consultDestinationAgentJoined,\n consultDestinationType,\n consultCallHeld,\n consultFromConference,\n } = context;\n const {recordingControlsAvailable} = context;\n\n // EP_DN consults are \"ready\" as soon as the consult is created (EP accepts routing immediately).\n // Backend sends destinationType as 'EP-DN'; SDK method uses 'entryPoint' — check both.\n const isEpDnConsult =\n consultDestinationType === 'entryPoint' || consultDestinationType === ('EP-DN' as any);\n const isConsultDestinationReady = consultDestinationAgentJoined || isEpDnConsult;\n\n const stateImpliesHeld = state === TaskState.HELD || state === TaskState.RESUME_INITIATING;\n const stateImpliesConnected =\n state === TaskState.CONNECTED || state === TaskState.HOLD_INITIATING;\n const isHeld = stateImpliesHeld || serverHold === true;\n const isConnected = stateImpliesConnected || (!stateImpliesHeld && serverHold === false);\n\n // State categories for cleaner logic\n const isConsulting =\n state === TaskState.CONSULTING ||\n state === TaskState.CONSULT_INITIATING ||\n state === TaskState.CONF_INITIATING;\n const isConferencing = state === TaskState.CONFERENCING;\n const isWrappingUp = state === TaskState.WRAPPING_UP;\n const selfInMainCall =\n Boolean(selfAgentId) &&\n Boolean(mainCallId) &&\n Boolean(interaction?.media?.[mainCallId]?.participants?.includes(selfAgentId as string));\n const conferenceActive = isConferencing || conferenceFromBackend || consultFromConference;\n // Treat consult initiator as \"in conference\" even if mainCall participant list lags while consulting.\n const inConference = conferenceActive && (isConferencing || selfInMainCall || consultInitiator);\n\n // Check if this is a consulted agent (must be after isConsulting is computed).\n const isSoleAgentOnCall = participantCount <= 1 && !isConsulting && !inConference;\n const isConsulted =\n inConference || isSoleAgentOnCall\n ? false\n : getIsConsultedAgentForControls(taskData, context, isConsulting);\n\n // Active call = can perform call operations\n const isActive =\n state === TaskState.CONNECTED ||\n state === TaskState.HELD ||\n state === TaskState.HOLD_INITIATING ||\n state === TaskState.RESUME_INITIATING ||\n isConsulting ||\n isConferencing;\n\n // Consulted agents have limited controls until they're in conference or wrapup\n // Use inConference (not isConferencing) so controls remain enabled after state downgrade\n const hasFullControls = !isConsulted || consultInitiator || inConference || isWrappingUp;\n const consultOwnedBySelf =\n consultInitiator || (Boolean(selfAgentId) && taskData?.consultingAgentId === selfAgentId);\n const hasConsultMedia = Boolean(\n taskData?.consultMediaResourceId ||\n Object.values(interaction?.media ?? {}).some((media: any) => media?.mType === 'consult')\n );\n const hasParallelConsultLeg =\n consultOwnedBySelf &&\n !isConsulting &&\n !isConsulted &&\n (consultInProgress || consultCallHeld || hasConsultMedia);\n const consultLegOnHold = isConsulting && consultCallHeld;\n\n return {\n // Accept/Decline: Voice tasks in offered state\n // For outdial, accept is disabled (auto-answer handles it), decline remains enabled\n // For Extension mode (non-WebRTC), accept shows as disabled \"Ringing\" button\n accept:\n state === TaskState.OFFERED && !interaction?.isTerminated\n ? {isVisible: true, isEnabled: isWebrtc && !isOutdial}\n : DISABLED,\n decline:\n isWebrtc && state === TaskState.OFFERED && !interaction?.isTerminated\n ? VISIBLE_ENABLED\n : DISABLED,\n\n // Hold: visible in connected/held/conference, disabled in conference/consulting\n hold: (() => {\n if (!hasFullControls) return DISABLED;\n if (consultOwnedBySelf && (isConsulting || hasParallelConsultLeg || consultCallHeld)) {\n return DISABLED;\n }\n if (hasParallelConsultLeg) return DISABLED;\n if (state === TaskState.OFFERED) return DISABLED;\n if (isWrappingUp) return DISABLED;\n // Visibility: connected || held || inConference\n if (!(isConnected || isHeld || inConference)) return DISABLED;\n // Enabled: (connected || held) && !inConference && !isConsulting\n const canHold = (isConnected || isHeld) && !inConference && !isConsulting;\n\n return canHold ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n })(),\n\n // Mute: WebRTC only, active calls; hidden entirely during wrapup\n mute: (() => {\n if (!isWebrtc) return DISABLED;\n if (isWrappingUp) return DISABLED;\n if (isConsulting) return VISIBLE_ENABLED;\n\n if (isConnected || isHeld || isConferencing) {\n if (inConference) return VISIBLE_ENABLED;\n\n return isHeld ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n }\n\n return DISABLED;\n })(),\n\n // End: varies by state; during consulting only on main leg (consult held)\n end: (() => {\n if (!config.isEndTaskEnabled) return DISABLED;\n if (hasParallelConsultLeg) {\n return isConnected && isEpDnConsult ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n }\n\n if (isConsulting) {\n if (currentLeg === 'consult' && consultCallHeld) return DISABLED;\n\n return consultInitiator && consultCallHeld ? VISIBLE_ENABLED : DISABLED;\n }\n\n if (inConference) {\n if (isConsulted) return DISABLED;\n\n if (consultInProgress) return VISIBLE_DISABLED;\n\n return isWrappingUp ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n }\n if (!hasFullControls) return DISABLED;\n if (isActive) return isHeld || isWrappingUp ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n\n return DISABLED;\n })(),\n\n // Transfer: connected/held, not in conference\n transfer: (() => {\n if (hasParallelConsultLeg) {\n if (state === TaskState.CONNECTED) return VISIBLE_ENABLED;\n if (state === TaskState.HELD) return VISIBLE_DISABLED;\n }\n if (isConsulting) {\n if (!consultInitiator) return DISABLED;\n if (consultLegOnHold) return VISIBLE_DISABLED;\n\n return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n }\n if (!hasFullControls || inConference) return DISABLED;\n if (state === TaskState.CONNECTED || state === TaskState.HELD) return VISIBLE_ENABLED;\n\n return DISABLED;\n })(),\n\n // Consult: connected/held/conference when conditions met\n consult: (() => {\n const isConnectedOrHeld = state === TaskState.CONNECTED || state === TaskState.HELD;\n\n if (hasParallelConsultLeg) return DISABLED;\n if (!hasFullControls || !(isConnectedOrHeld || inConference)) {\n return DISABLED;\n }\n\n // Enabled conditions differ by state\n const canFromConnected =\n !maxParticipants && customerPresent && !consultInProgress && !isConsulted;\n const canFromConference =\n !maxParticipants && customerPresent && !consultInProgress && !isConsulting;\n\n const isEnabled = inConference ? canFromConference : canFromConnected;\n\n return {isVisible: true, isEnabled};\n })(),\n\n // ConsultTransfer: always hidden (use transfer button)\n consultTransfer: DISABLED,\n\n // EndConsult: during consulting\n endConsult: (() => {\n if (!isConsulting) return DISABLED;\n if (isConsulted && isConferencing) return DISABLED;\n if (!isConsulted && isConferencing && !(consultInitiator && conferenceFromBackend)) {\n return DISABLED;\n }\n\n return {isVisible: true, isEnabled: consultInitiator || config.isEndConsultEnabled};\n })(),\n\n // Recording: connected/held only, not in consult/conference\n recording: (() => {\n if (!recordingControlsAvailable || !config.isRecordingEnabled) return DISABLED;\n if (!hasFullControls || isConsulting || inConference) return DISABLED;\n if (state === TaskState.CONNECTED || state === TaskState.HELD) {\n return VISIBLE_ENABLED;\n }\n\n return DISABLED;\n })(),\n\n // Conference: during consulting, enabled on both legs when agent joined\n // Label changes based on leg: \"Conference\" on main leg, \"Merge\" on consult leg\n conference: (() => {\n if (hasParallelConsultLeg) {\n if (state === TaskState.CONNECTED) {\n return maxParticipants ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n }\n if (state === TaskState.HELD) return VISIBLE_DISABLED;\n\n return DISABLED;\n }\n if (!hasFullControls || !isConsulting) return DISABLED;\n if (!consultInitiator) return DISABLED;\n if (consultLegOnHold) return VISIBLE_DISABLED;\n\n return isConsultDestinationReady && !maxParticipants ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n })(),\n\n // Wrapup: wrapping up state\n wrapup: isWrappingUp ? VISIBLE_ENABLED : DISABLED,\n\n // ExitConference: in conference, not consulting from conference\n exitConference: (() => {\n if (isConsulted && !isConferencing) return DISABLED;\n if (!inConference) return DISABLED;\n const consultingFromConference = consultInitiator && isConsulting && conferenceFromBackend;\n\n return consultingFromConference ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n })(),\n\n // TransferConference: in conference with active consult, owner consulting from conference\n transferConference: (() => {\n if (hasParallelConsultLeg || consultLegOnHold) return DISABLED;\n if (!inConference || !isConsulting) return DISABLED;\n if (!consultInitiator || isConsulted) return DISABLED;\n\n return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n })(),\n\n // MergeToConference: mirrors conference control, enabled on both legs\n mergeToConference: (() => {\n if (!isConsulting || !consultInitiator) return DISABLED;\n if (consultLegOnHold) return VISIBLE_DISABLED;\n\n return isConsultDestinationReady && !maxParticipants ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n })(),\n\n // Switch: visible only on the currently active leg\n switch: (() => {\n if (currentLeg === 'consult') {\n if (!isConsulting || !consultInitiator || consultCallHeld) return DISABLED;\n\n return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n }\n\n if (hasParallelConsultLeg && state === TaskState.CONNECTED) {\n return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n }\n\n return DISABLED;\n })(),\n };\n}\n\nfunction computeDigitalInteractionUIControls(\n state: TaskState,\n context: TaskContext,\n fallbackTaskData?: TaskData\n): InteractionUIControls {\n const taskData = context.taskData ?? fallbackTaskData ?? null;\n const isTerminated = taskData?.interaction?.isTerminated ?? false;\n\n const isConnected = state === TaskState.CONNECTED;\n const isWrappingUp = state === TaskState.WRAPPING_UP;\n\n return {\n accept: state === TaskState.OFFERED ? VISIBLE_ENABLED : DISABLED,\n decline: DISABLED,\n hold: DISABLED,\n mute: DISABLED,\n end: isConnected && !isWrappingUp ? VISIBLE_ENABLED : DISABLED,\n transfer: isConnected && !isWrappingUp ? VISIBLE_ENABLED : DISABLED,\n consult: DISABLED,\n consultTransfer: DISABLED,\n endConsult: DISABLED,\n recording: DISABLED,\n conference: DISABLED,\n wrapup: isTerminated || isWrappingUp ? VISIBLE_ENABLED : DISABLED,\n exitConference: DISABLED,\n transferConference: DISABLED,\n mergeToConference: DISABLED,\n switch: DISABLED,\n };\n}\n\nfunction getVoiceLegState(\n currentState: TaskState,\n context: TaskContext,\n config: UIControlConfig,\n fallbackTaskData?: TaskData\n): {hasConsultLeg: boolean; activeLeg: TaskUILeg; mainState: TaskState; consultState: TaskState} {\n if (currentState === TaskState.WRAPPING_UP) {\n return {\n hasConsultLeg: false,\n activeLeg: 'main',\n mainState: currentState,\n consultState: TaskState.CONSULTING,\n };\n }\n\n const taskData = context.taskData ?? fallbackTaskData ?? null;\n const interaction = taskData?.interaction;\n const mainCallId = interaction?.mainInteractionId || taskData?.interactionId;\n const selfAgentId = config.agentId ?? taskData?.agentId;\n const consultInProgress = getIsConsultInProgressForConferenceControls(\n interaction,\n mainCallId,\n selfAgentId\n );\n const isConsultingState =\n currentState === TaskState.CONSULTING ||\n currentState === TaskState.CONSULT_INITIATING ||\n currentState === TaskState.CONF_INITIATING;\n const consultOwnedBySelf =\n context.consultInitiator ||\n (Boolean(selfAgentId) && taskData?.consultingAgentId === selfAgentId);\n const hasConsultMedia = Boolean(\n taskData?.consultMediaResourceId ||\n Object.values(interaction?.media ?? {}).some((media: any) => media?.mType === 'consult')\n );\n const hasConsultLeg = Boolean(\n consultOwnedBySelf &&\n !taskData?.isConsulted &&\n !interaction?.isTerminated &&\n (consultInProgress || isConsultingState || context.consultCallHeld || hasConsultMedia)\n );\n\n if (!hasConsultLeg) {\n return {\n hasConsultLeg: false,\n activeLeg: 'main',\n mainState: currentState,\n consultState: TaskState.CONSULTING,\n };\n }\n\n return {\n hasConsultLeg: true,\n activeLeg: context.consultCallHeld ? 'main' : 'consult',\n mainState: context.consultCallHeld ? TaskState.CONNECTED : TaskState.HELD,\n consultState: isConsultingState ? currentState : TaskState.CONSULTING,\n };\n}\n\nexport function computeUIControls(\n currentState: TaskState,\n context: TaskContext,\n fallbackTaskData?: TaskData\n): TaskUIControls {\n if (currentState === TaskState.TERMINATED || currentState === TaskState.COMPLETED) {\n return getDefaultUIControls();\n }\n\n switch (context.uiControlConfig.channelType) {\n case TASK_CHANNEL_TYPE.VOICE: {\n const {hasConsultLeg, activeLeg, mainState, consultState} = getVoiceLegState(\n currentState,\n context,\n context.uiControlConfig,\n fallbackTaskData\n );\n\n const mainControls = computeVoiceInteractionUIControls(\n mainState,\n context,\n context.uiControlConfig,\n fallbackTaskData,\n 'main'\n );\n const consultControls = hasConsultLeg\n ? computeVoiceInteractionUIControls(\n consultState,\n context,\n context.uiControlConfig,\n fallbackTaskData,\n 'consult'\n )\n : getDefaultInteractionUIControls();\n\n return createTaskUIControls(mainControls, consultControls, activeLeg);\n }\n case TASK_CHANNEL_TYPE.DIGITAL:\n return createTaskUIControls(\n computeDigitalInteractionUIControls(currentState, context, fallbackTaskData),\n getDefaultInteractionUIControls(),\n 'main'\n );\n default:\n return getDefaultUIControls();\n }\n}\n\nfunction haveInteractionUIControlsChanged(\n previous: InteractionUIControls,\n next: InteractionUIControls\n): boolean {\n return (Object.keys(next) as (keyof InteractionUIControls)[]).some((key) => {\n const prev = previous[key];\n const curr = next[key];\n\n return prev.isVisible !== curr.isVisible || prev.isEnabled !== curr.isEnabled;\n });\n}\n\nexport function haveUIControlsChanged(\n previous: TaskUIControls | undefined,\n next: TaskUIControls\n): boolean {\n if (!previous) return true;\n\n return (\n previous.activeLeg !== next.activeLeg ||\n haveInteractionUIControlsChanged(previous.main, next.main) ||\n haveInteractionUIControlsChanged(previous.consult, next.consult)\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
package/dist/webex.js
CHANGED
package/package.json
CHANGED
|
@@ -691,8 +691,20 @@ export default class TaskManager extends EventEmitter {
|
|
|
691
691
|
this.wrapupData,
|
|
692
692
|
this.agentId
|
|
693
693
|
);
|
|
694
|
-
this.setupTaskListeners(task);
|
|
695
694
|
this.taskCollection[payload.interactionId] = task;
|
|
695
|
+
|
|
696
|
+
// Transition the new task out of IDLE immediately so UI controls are
|
|
697
|
+
// computed before TASK_MERGED is emitted. This handles the race where
|
|
698
|
+
// AgentContactAssigned arrives before ContactMerged and gets dropped.
|
|
699
|
+
// Send HYDRATE before setupTaskListeners so the emitTaskHydrate action
|
|
700
|
+
// doesn't bubble up to the Widget (avoids duplicate listener registration).
|
|
701
|
+
task.sendStateMachineEvent({
|
|
702
|
+
type: TaskEvent.HYDRATE,
|
|
703
|
+
taskData,
|
|
704
|
+
agentId: this.agentId,
|
|
705
|
+
} as TaskEventPayload);
|
|
706
|
+
|
|
707
|
+
this.setupTaskListeners(task);
|
|
696
708
|
}
|
|
697
709
|
|
|
698
710
|
if (task) {
|
|
@@ -109,7 +109,20 @@ const deriveTaskDataUpdates = (context: TaskContext, taskData: TaskData | undefi
|
|
|
109
109
|
(p: any) => p?.isConsulted === true && !p?.hasLeft
|
|
110
110
|
)
|
|
111
111
|
);
|
|
112
|
-
|
|
112
|
+
const cpd = taskData.interaction?.callProcessingDetails;
|
|
113
|
+
const backendSaysJoined = cpd?.consultDestinationAgentJoined === 'true';
|
|
114
|
+
if (hasJoinedConsultee || backendSaysJoined)
|
|
115
|
+
updates.consultDestinationAgentJoined = true;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (!context.consultDestinationType && !updates.consultDestinationType) {
|
|
119
|
+
const hasEpDnParticipant = Boolean(
|
|
120
|
+
taskData.interaction.participants &&
|
|
121
|
+
Object.values(taskData.interaction.participants).some(
|
|
122
|
+
(p: any) => p?.pType === 'EP-DN' && !p?.hasLeft
|
|
123
|
+
)
|
|
124
|
+
);
|
|
125
|
+
if (hasEpDnParticipant) updates.consultDestinationType = 'entryPoint' as any;
|
|
113
126
|
}
|
|
114
127
|
|
|
115
128
|
const effectiveConsultInitiator = updates.consultInitiator ?? context.consultInitiator;
|
|
@@ -100,7 +100,15 @@ export const guards = {
|
|
|
100
100
|
isInteractionConsulting: ({event}: GuardParams): boolean => {
|
|
101
101
|
const taskData = getTaskDataFromEvent(event);
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
if (taskData?.interaction?.state === 'consulting') return true;
|
|
104
|
+
|
|
105
|
+
// EP_DN consulted agent: backend reports state as 'connected' but CPD indicates consult
|
|
106
|
+
const cpd = taskData?.interaction?.callProcessingDetails;
|
|
107
|
+
if (cpd?.relationshipType === 'consult' && taskData?.interaction?.state === 'connected') {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return false;
|
|
104
112
|
},
|
|
105
113
|
|
|
106
114
|
isInteractionHeld: ({event}: GuardParams): boolean => {
|
|
@@ -112,10 +112,21 @@ function computeVoiceInteractionUIControls(
|
|
|
112
112
|
// Note: ownership is used by some controls; keep computations local to those controls
|
|
113
113
|
|
|
114
114
|
// Context flags (set by state machine actions)
|
|
115
|
-
const {
|
|
116
|
-
|
|
115
|
+
const {
|
|
116
|
+
consultInitiator,
|
|
117
|
+
consultDestinationAgentJoined,
|
|
118
|
+
consultDestinationType,
|
|
119
|
+
consultCallHeld,
|
|
120
|
+
consultFromConference,
|
|
121
|
+
} = context;
|
|
117
122
|
const {recordingControlsAvailable} = context;
|
|
118
123
|
|
|
124
|
+
// EP_DN consults are "ready" as soon as the consult is created (EP accepts routing immediately).
|
|
125
|
+
// Backend sends destinationType as 'EP-DN'; SDK method uses 'entryPoint' — check both.
|
|
126
|
+
const isEpDnConsult =
|
|
127
|
+
consultDestinationType === 'entryPoint' || consultDestinationType === ('EP-DN' as any);
|
|
128
|
+
const isConsultDestinationReady = consultDestinationAgentJoined || isEpDnConsult;
|
|
129
|
+
|
|
119
130
|
const stateImpliesHeld = state === TaskState.HELD || state === TaskState.RESUME_INITIATING;
|
|
120
131
|
const stateImpliesConnected =
|
|
121
132
|
state === TaskState.CONNECTED || state === TaskState.HOLD_INITIATING;
|
|
@@ -217,7 +228,9 @@ function computeVoiceInteractionUIControls(
|
|
|
217
228
|
// End: varies by state; during consulting only on main leg (consult held)
|
|
218
229
|
end: (() => {
|
|
219
230
|
if (!config.isEndTaskEnabled) return DISABLED;
|
|
220
|
-
if (hasParallelConsultLeg)
|
|
231
|
+
if (hasParallelConsultLeg) {
|
|
232
|
+
return isConnected && isEpDnConsult ? VISIBLE_ENABLED : VISIBLE_DISABLED;
|
|
233
|
+
}
|
|
221
234
|
|
|
222
235
|
if (isConsulting) {
|
|
223
236
|
if (currentLeg === 'consult' && consultCallHeld) return DISABLED;
|
|
@@ -248,7 +261,7 @@ function computeVoiceInteractionUIControls(
|
|
|
248
261
|
if (!consultInitiator) return DISABLED;
|
|
249
262
|
if (consultLegOnHold) return VISIBLE_DISABLED;
|
|
250
263
|
|
|
251
|
-
return
|
|
264
|
+
return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;
|
|
252
265
|
}
|
|
253
266
|
if (!hasFullControls || inConference) return DISABLED;
|
|
254
267
|
if (state === TaskState.CONNECTED || state === TaskState.HELD) return VISIBLE_ENABLED;
|
|
@@ -316,7 +329,7 @@ function computeVoiceInteractionUIControls(
|
|
|
316
329
|
if (!consultInitiator) return DISABLED;
|
|
317
330
|
if (consultLegOnHold) return VISIBLE_DISABLED;
|
|
318
331
|
|
|
319
|
-
return
|
|
332
|
+
return isConsultDestinationReady && !maxParticipants ? VISIBLE_ENABLED : VISIBLE_DISABLED;
|
|
320
333
|
})(),
|
|
321
334
|
|
|
322
335
|
// Wrapup: wrapping up state
|
|
@@ -337,7 +350,7 @@ function computeVoiceInteractionUIControls(
|
|
|
337
350
|
if (!inConference || !isConsulting) return DISABLED;
|
|
338
351
|
if (!consultInitiator || isConsulted) return DISABLED;
|
|
339
352
|
|
|
340
|
-
return
|
|
353
|
+
return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;
|
|
341
354
|
})(),
|
|
342
355
|
|
|
343
356
|
// MergeToConference: mirrors conference control, enabled on both legs
|
|
@@ -345,7 +358,7 @@ function computeVoiceInteractionUIControls(
|
|
|
345
358
|
if (!isConsulting || !consultInitiator) return DISABLED;
|
|
346
359
|
if (consultLegOnHold) return VISIBLE_DISABLED;
|
|
347
360
|
|
|
348
|
-
return
|
|
361
|
+
return isConsultDestinationReady && !maxParticipants ? VISIBLE_ENABLED : VISIBLE_DISABLED;
|
|
349
362
|
})(),
|
|
350
363
|
|
|
351
364
|
// Switch: visible only on the currently active leg
|
|
@@ -353,11 +366,11 @@ function computeVoiceInteractionUIControls(
|
|
|
353
366
|
if (currentLeg === 'consult') {
|
|
354
367
|
if (!isConsulting || !consultInitiator || consultCallHeld) return DISABLED;
|
|
355
368
|
|
|
356
|
-
return
|
|
369
|
+
return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;
|
|
357
370
|
}
|
|
358
371
|
|
|
359
372
|
if (hasParallelConsultLeg && state === TaskState.CONNECTED) {
|
|
360
|
-
return
|
|
373
|
+
return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;
|
|
361
374
|
}
|
|
362
375
|
|
|
363
376
|
return DISABLED;
|