Skip to content

Commit b372732

Browse files
committed
fix(mpc): fix CAD for MPC
1 parent a295d58 commit b372732

5 files changed

Lines changed: 177 additions & 56 deletions

File tree

packages/contact-center/cc-components/src/components/task/CallControl/CallControlCustom/call-control-custom.utils.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ export const createConsultButtons = (
2828
const consultCtrl = controls?.consult;
2929
const mainCtrl = controls?.main;
3030
const isConsultLegActive = controls?.activeLeg === 'consult';
31+
const consultTransferCtrl = consultCtrl?.transfer;
32+
const consultTransferConferenceCtrl = consultCtrl?.transferConference;
33+
const mainTransferConferenceCtrl = mainCtrl?.transferConference;
34+
const isTransferConferenceVisible =
35+
(consultTransferConferenceCtrl?.isVisible ?? false) || (mainTransferConferenceCtrl?.isVisible ?? false);
36+
const isTransferConferenceEnabled =
37+
(consultTransferConferenceCtrl?.isEnabled ?? false) || (mainTransferConferenceCtrl?.isEnabled ?? false);
3138
return [
3239
{
3340
key: 'mute',
@@ -51,11 +58,11 @@ export const createConsultButtons = (
5158
{
5259
key: 'transfer',
5360
icon: 'next-bold',
54-
tooltip: 'Transfer',
61+
tooltip: isTransferConferenceVisible ? 'Transfer Conference' : 'Transfer',
5562
onClick: consultTransfer,
5663
className: 'call-control-button',
57-
disabled: !(consultCtrl?.transfer?.isEnabled ?? false),
58-
isVisible: consultCtrl?.transfer?.isVisible ?? false,
64+
disabled: !((consultTransferCtrl?.isEnabled ?? false) || isTransferConferenceEnabled),
65+
isVisible: (consultTransferCtrl?.isVisible ?? false) || isTransferConferenceVisible,
5966
},
6067
{
6168
key: 'conference',

packages/contact-center/cc-components/src/components/task/CallControlCAD/call-control-cad.tsx

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ const CallControlCADComponent: React.FC<CallControlComponentProps> = (props) =>
7575
const dn = currentTask?.data?.interaction?.callAssociatedDetails?.dn;
7676

7777
// eslint-disable-next-line @typescript-eslint/no-explicit-any
78-
const callAssociatedData = (currentTask?.data?.interaction as any)?.callAssociatedData as CallAssociatedDataMap | undefined;
78+
const callAssociatedData = (currentTask?.data?.interaction as any)?.callAssociatedData as
79+
| CallAssociatedDataMap
80+
| undefined;
7981
const globalVariables = getAgentViewableGlobalVariables(callAssociatedData);
8082

8183
// Create unique IDs for tooltips
@@ -284,24 +286,25 @@ const CallControlCADComponent: React.FC<CallControlComponentProps> = (props) =>
284286
</div>
285287
)}
286288
</div>
287-
{(controls?.consult?.endConsult?.isVisible || controls?.main?.endConsult?.isVisible) && !controls?.main?.wrapup?.isVisible && (
288-
<div className={`call-control-consult-container ${callControlConsultClassName || ''}`}>
289-
<CallControlConsultComponent
290-
agentName={consultAgentName}
291-
consultTimerLabel={consultTimerLabel}
292-
consultTimerTimestamp={consultTimerTimestamp}
293-
endConsultCall={endConsultCall}
294-
consultTransfer={consultTransfer}
295-
consultConference={consultConference}
296-
switchToMainCall={switchToMainCall}
297-
logger={logger}
298-
isMuted={isMuted}
299-
controls={controls}
300-
toggleConsultMute={toggleMute}
301-
conferenceEnabled={conferenceEnabled}
302-
/>
303-
</div>
304-
)}
289+
{(controls?.consult?.endConsult?.isVisible || controls?.main?.endConsult?.isVisible) &&
290+
!controls?.main?.wrapup?.isVisible && (
291+
<div className={`call-control-consult-container ${callControlConsultClassName || ''}`}>
292+
<CallControlConsultComponent
293+
agentName={consultAgentName}
294+
consultTimerLabel={consultTimerLabel}
295+
consultTimerTimestamp={consultTimerTimestamp}
296+
endConsultCall={endConsultCall}
297+
consultTransfer={consultTransfer}
298+
consultConference={consultConference}
299+
switchToMainCall={switchToMainCall}
300+
logger={logger}
301+
isMuted={isMuted}
302+
controls={controls}
303+
toggleConsultMute={toggleMute}
304+
conferenceEnabled={conferenceEnabled}
305+
/>
306+
</div>
307+
)}
305308
</>
306309
);
307310
};

packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/call-control-custom.util.tsx

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -46,33 +46,19 @@ describe('Call Control Custom Utils', () => {
4646
});
4747

4848
const mockControlVisibility = {
49-
accept: {isVisible: true, isEnabled: true},
50-
decline: {isVisible: true, isEnabled: true},
51-
end: {isVisible: true, isEnabled: true},
52-
muteUnmute: {isVisible: true, isEnabled: true},
53-
muteUnmuteConsult: {isVisible: true, isEnabled: true},
54-
holdResume: {isVisible: true, isEnabled: true},
55-
consult: {isVisible: true, isEnabled: true},
56-
transfer: {isVisible: true, isEnabled: true},
57-
conference: {isVisible: true, isEnabled: true},
58-
wrapup: {isVisible: false, isEnabled: false},
59-
pauseResumeRecording: {isVisible: true, isEnabled: true},
60-
endConsult: {isVisible: true, isEnabled: true},
61-
recordingIndicator: {isVisible: true, isEnabled: true},
62-
exitConference: {isVisible: false, isEnabled: false},
63-
mergeConference: {isVisible: false, isEnabled: false},
64-
mergeConferenceConsult: {isVisible: false, isEnabled: false},
65-
consultTransfer: {isVisible: false, isEnabled: false},
66-
consultTransferConsult: {isVisible: false, isEnabled: false},
67-
switchToMainCall: {isVisible: false, isEnabled: false},
68-
switchToConsult: {isVisible: false, isEnabled: false},
69-
isConferenceInProgress: false,
70-
isConsultInitiated: false,
71-
isConsultInitiatedAndAccepted: false,
72-
isConsultInitiatedOrAccepted: false,
73-
isConsultReceived: false,
74-
isHeld: false,
75-
consultCallHeld: false,
49+
activeLeg: 'consult',
50+
main: {
51+
endConsult: {isVisible: false, isEnabled: false},
52+
transferConference: {isVisible: false, isEnabled: false},
53+
},
54+
consult: {
55+
mute: {isVisible: true, isEnabled: true},
56+
switch: {isVisible: true, isEnabled: true},
57+
transfer: {isVisible: true, isEnabled: true},
58+
transferConference: {isVisible: false, isEnabled: false},
59+
mergeToConference: {isVisible: true, isEnabled: true},
60+
endConsult: {isVisible: true, isEnabled: true},
61+
},
7662
};
7763

7864
describe('createConsultButtons', () => {
@@ -139,7 +125,10 @@ describe('Call Control Custom Utils', () => {
139125
});
140126

141127
it('should disable transfer button when consult not completed', () => {
142-
const customVisibility = {...mockControlVisibility, consultTransferConsult: {isVisible: true, isEnabled: false}};
128+
const customVisibility = {
129+
...mockControlVisibility,
130+
consult: {...mockControlVisibility.consult, transfer: {isVisible: true, isEnabled: false}},
131+
};
143132
const buttons = createConsultButtons(
144133
false, // isMuted
145134
customVisibility,
@@ -156,7 +145,10 @@ describe('Call Control Custom Utils', () => {
156145
});
157146

158147
it('should hide transfer button when not agent being consulted or no onTransfer', () => {
159-
const customVisibility = {...mockControlVisibility, consultTransferConsult: {isVisible: false, isEnabled: false}};
148+
const customVisibility = {
149+
...mockControlVisibility,
150+
consult: {...mockControlVisibility.consult, transfer: {isVisible: false, isEnabled: false}},
151+
};
160152
const buttons = createConsultButtons(
161153
false, // isMuted
162154
customVisibility,
@@ -172,8 +164,11 @@ describe('Call Control Custom Utils', () => {
172164
expect(transferButton?.isVisible).toBe(false);
173165
});
174166

175-
it('should hide mute button when muteUnmuteConsult is false', () => {
176-
const customVisibility = {...mockControlVisibility, muteUnmuteConsult: {isVisible: false, isEnabled: false}};
167+
it('should hide mute button when consult mute is false', () => {
168+
const customVisibility = {
169+
...mockControlVisibility,
170+
consult: {...mockControlVisibility.consult, mute: {isVisible: false, isEnabled: false}},
171+
};
177172
const buttons = createConsultButtons(
178173
false, // isMuted
179174
customVisibility,
@@ -189,6 +184,34 @@ describe('Call Control Custom Utils', () => {
189184
expect(muteButton?.isVisible).toBe(false);
190185
});
191186

187+
it('should show Transfer Conference button from transferConference controls', () => {
188+
const conferenceTransferControls = {
189+
...mockControlVisibility,
190+
consult: {
191+
...mockControlVisibility.consult,
192+
transfer: {isVisible: false, isEnabled: false},
193+
transferConference: {isVisible: true, isEnabled: true},
194+
},
195+
};
196+
197+
const buttons = createConsultButtons(
198+
false,
199+
conferenceTransferControls as never,
200+
jest.fn(),
201+
jest.fn(),
202+
jest.fn(),
203+
jest.fn(),
204+
jest.fn(),
205+
loggerMock
206+
);
207+
208+
const transferButton = buttons.find((b) => b.key === 'transfer');
209+
expect(transferButton?.isVisible).toBe(true);
210+
expect(transferButton?.disabled).toBe(false);
211+
expect(transferButton?.tooltip).toBe('Transfer Conference');
212+
expect(transferButton?.icon).toBe('next-bold');
213+
});
214+
192215
it('should disable consult mute when active leg is main', () => {
193216
const nestedControls = {
194217
activeLeg: 'main',

packages/contact-center/task/src/helper.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -986,10 +986,12 @@ export const useCallControl = (props: useCallControlProps) => {
986986
}
987987

988988
try {
989-
const currentState = currentTask.state?.value;
990-
const isCurrentlyConsulting = currentState === 'CONSULTING';
989+
const shouldUseTransferConference =
990+
currentTask.data.isConferenceInProgress ||
991+
controls?.consult?.transferConference?.isVisible ||
992+
controls?.main?.transferConference?.isVisible;
991993

992-
if (!isCurrentlyConsulting && currentTask.data.isConferenceInProgress) {
994+
if (shouldUseTransferConference) {
993995
logger.info('Conference in progress, using transferConference', {
994996
module: 'useCallControl',
995997
method: 'consultTransfer',

packages/contact-center/task/tests/helper.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3337,6 +3337,92 @@ describe('useCallControl', () => {
33373337
}
33383338
);
33393339
});
3340+
3341+
it('should call transferConference when transferConference control is visible', async () => {
3342+
const taskWithTransferConferenceControl = {
3343+
...mockCurrentTask,
3344+
data: {
3345+
...mockCurrentTask.data,
3346+
isConferenceInProgress: false,
3347+
},
3348+
uiControls: {
3349+
...mockCurrentTask.uiControls,
3350+
activeLeg: 'consult',
3351+
consult: {
3352+
...mockCurrentTask.uiControls.consult,
3353+
transferConference: {isVisible: true, isEnabled: true},
3354+
},
3355+
},
3356+
transferConference: jest.fn().mockResolvedValue(undefined),
3357+
};
3358+
3359+
const {result} = renderHook(() =>
3360+
useCallControl({
3361+
currentTask: taskWithTransferConferenceControl,
3362+
onHoldResume: mockOnHoldResume,
3363+
onEnd: mockOnEnd,
3364+
onWrapUp: mockOnWrapUp,
3365+
logger: mockLogger,
3366+
featureFlags: store.featureFlags,
3367+
deviceType: store.deviceType,
3368+
isMuted: false,
3369+
conferenceEnabled: true,
3370+
agentId: 'test-agent-id',
3371+
})
3372+
);
3373+
3374+
await act(async () => {
3375+
await result.current.consultTransfer();
3376+
});
3377+
3378+
expect(taskWithTransferConferenceControl.transferConference).toHaveBeenCalled();
3379+
});
3380+
3381+
it('should call transferConference even when state is CONSULTING and transferConference is visible', async () => {
3382+
const taskWithConsultAndConference = {
3383+
...mockCurrentTask,
3384+
state: {
3385+
...mockCurrentTask.state,
3386+
value: 'CONSULTING',
3387+
},
3388+
data: {
3389+
...mockCurrentTask.data,
3390+
isConferenceInProgress: false,
3391+
},
3392+
uiControls: {
3393+
...mockCurrentTask.uiControls,
3394+
activeLeg: 'consult',
3395+
consult: {
3396+
...mockCurrentTask.uiControls.consult,
3397+
transferConference: {isVisible: true, isEnabled: true},
3398+
},
3399+
},
3400+
transferConference: jest.fn().mockResolvedValue(undefined),
3401+
transfer: jest.fn().mockResolvedValue(undefined),
3402+
};
3403+
3404+
const {result} = renderHook(() =>
3405+
useCallControl({
3406+
currentTask: taskWithConsultAndConference,
3407+
onHoldResume: mockOnHoldResume,
3408+
onEnd: mockOnEnd,
3409+
onWrapUp: mockOnWrapUp,
3410+
logger: mockLogger,
3411+
featureFlags: store.featureFlags,
3412+
deviceType: store.deviceType,
3413+
isMuted: false,
3414+
conferenceEnabled: true,
3415+
agentId: 'test-agent-id',
3416+
})
3417+
);
3418+
3419+
await act(async () => {
3420+
await result.current.consultTransfer();
3421+
});
3422+
3423+
expect(taskWithConsultAndConference.transferConference).toHaveBeenCalled();
3424+
expect(taskWithConsultAndConference.transfer).not.toHaveBeenCalled();
3425+
});
33403426
});
33413427

33423428
describe('consult button disabled via controlVisibility with conference participants', () => {

0 commit comments

Comments
 (0)