fix(task-refactor)migrate widgets to SDK state-machine-driven uiControls#668
fix(task-refactor)migrate widgets to SDK state-machine-driven uiControls#668akulakum wants to merge 4 commits intowebex:task-refactorfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2227d693dc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (lastWrapupAuxCodeIdRef.current) { | ||
| const wrapUpReason = store.wrapupCodes.find((code) => code.id === lastWrapupAuxCodeIdRef.current)?.name; | ||
| if (onWrapUp) { |
There was a problem hiding this comment.
Restore onWrapUp callback for SDK-driven wrapups
wrapupCallCallback now emits onWrapUp only when lastWrapupAuxCodeIdRef.current is present, but that ref is only set in wrapupCall(). As a result, wrapups triggered outside this path (for example auto-wrapup or other SDK-driven/task-synced wrapup events) will fire TASK_WRAPPEDUP but never notify consumers via onWrapUp, which breaks callback-based integrations such as analytics or workflow hooks.
Useful? React with 👍 / 👎.
| </div> | ||
| </> | ||
| )} | ||
| {!controls?.wrapup?.isVisible && isInteractionOnHold(currentTask) && ( |
There was a problem hiding this comment.
Keep consult-state gating for the CAD hold indicator
The hold badge now depends only on isInteractionOnHold(currentTask), which becomes true when either the main leg or consult leg is held. During consult/conference flows one leg is often intentionally held while the agent is active on the other, so this change can incorrectly show an ON HOLD status. The previous logic gated this by consult-state flags, and removing that gating regresses status accuracy.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c63805a45b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| store.lastConsultDestination ?? { | ||
| to: currentTask.data.destAgentId, | ||
| destinationType: 'agent' as DestinationType, | ||
| } |
There was a problem hiding this comment.
Preserve consult destination for consult transfer
consultTransfer() now falls back to currentTask.transfer({ to: currentTask.data.destAgentId, destinationType: 'agent' }) when store.lastConsultDestination is missing. That store field is only set in consultCall(), so hydrated/multi-session consults (or any flow where the consult was not initiated in this hook) can lose the original destination type. In those cases, queue/EP consult transfers can be sent as agent transfers with an incorrect or empty destination, causing transfer failure or routing to the wrong target.
Useful? React with 👍 / 👎.
| // Derive consultCallHeld from controls: switchToConsult.isVisible means consult call is held | ||
| const consultCallHeld = controls.switchToConsult?.isVisible ?? false; |
There was a problem hiding this comment.
Derive consult hold timer from actual hold state
This computes consultCallHeld from controls.switchToConsult.isVisible, which is a UI visibility signal rather than the consult leg's hold state. If the button is hidden for reasons other than hold status, the timer logic will mislabel a held consult as active consulting and use the wrong timestamp. The timer should be driven by task/media hold state, not button visibility.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 24267feeb5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| this.setState({reset: true}); | ||
| // Ensure agent state is set to Available (auxCodeId '0') when no tasks remain | ||
| // The backend should send AGENT_STATE_CHANGE, but in test environments it may not | ||
| this.setCurrentState('0'); |
There was a problem hiding this comment.
Remove forced Available state on empty task list
Setting currentState to '0' inside refreshTaskList() introduces a side effect beyond UI cleanup: when UserState is mounted, its useEffect reacts to currentState changes and calls cc.setAgentState(...), so ending the last task can unexpectedly push the agent to Available even if the backend intended a different post-call state. This regression was introduced by the new unconditional this.setCurrentState('0') and can cause incorrect agent-state transitions in production flows.
Useful? React with 👍 / 👎.
| isTelephony, | ||
| logger | ||
| ); | ||
| const isConsulting = (controls?.consult?.endConsult?.isVisible || controls?.main?.endConsult?.isVisible) ?? false; |
There was a problem hiding this comment.
Derive consult mode without relying on end-consult visibility
Using endConsult.isVisible as the consult-state detector is not reliable: consult can be active while end-consult is hidden (for example when end-consult is disabled by configuration), so this check can treat an active consult as non-consulting. In that case consult-specific filtering is skipped here, and the same predicate also hides the CAD consult panel, leaving incorrect controls during an ongoing consult session.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 40a5f9f957
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return buttons; | ||
| } | ||
|
|
||
| return buttons.filter((button) => !['hold', 'consult', 'transfer', 'record'].includes(button.id)); |
There was a problem hiding this comment.
Stop filtering recording control during consult
filterButtonsForConsultation now always removes the record button whenever a consult is active, which bypasses the SDK-provided controls.main.recording visibility/enablement and prevents agents from pausing/resuming recording during consult flows where recording is still allowed. This is a regression from the prior behavior (which only filtered hold/consult) and can break recording-control workflows in consult scenarios.
Useful? React with 👍 / 👎.
| disabled: !(mainCtrl?.transfer?.isEnabled ?? false), | ||
| isVisible: | ||
| (mainCtrl?.transfer?.isVisible ?? false) && | ||
| ((controls?.consult?.endConsult?.isVisible || controls?.main?.endConsult?.isVisible) ?? false) && |
There was a problem hiding this comment.
Use conference transfer control when invoking transferConference
The transferConsult button is gated only by mainCtrl.transfer (isEnabled/isVisible), but the action handler can switch to currentTask.transferConference() in conference flows. When SDK state exposes conference-transfer availability separately from regular transfer, this mapping can hide or disable the button even though conference transfer is the intended action, leaving no way to trigger that path from the UI.
Useful? React with 👍 / 👎.
COMPLETES #https://jira-eng-sjc12.cisco.com/jira/browse/CAI-7779
This pull request addresses
The CC Widgets currently compute button visibility and enablement on the widget side using a complex combination of deviceType, featureFlags, conferenceEnabled, task state flags, and ~22 visibility functions in getControlsVisibility(). This approach duplicates logic that the SDK now handles internally through its state-machine-driven task.uiControls — a property on the ITask object where each of the 17 controls has { isVisible: boolean, isEnabled: boolean } computed from TaskState and TaskContext. This PR migrates all task widgets to consume task.uiControls as the single source of truth, eliminating widget-side control computation and aligning with the SDK's new architecture.
by making the following changes
Core migration — SDK uiControls as single source of truth:
Props removed (SDK handles internally):
Props restored (application-level overrides, not feature flags):
Hold state handling:
Transfer button mapping fix:
Type and Web Component updates:
Migration documentation:
Change Type
The following scenarios were tested
< ENUMERATE TESTS PERFORMED, WHETHER MANUAL OR AUTOMATED >
The GAI Coding Policy And Copyright Annotation Best Practices
Checklist before merging
Make sure to have followed the contributing guidelines before submitting.