Skip to content

Commit ab5fd64

Browse files
rsarikaakulakum
andauthored
fix(cc-task): visibility toggle for conference feature (#553)
Co-authored-by: “Akula <akulakum@cisco.com>
1 parent 2ff45cd commit ab5fd64

File tree

12 files changed

+206
-197
lines changed

12 files changed

+206
-197
lines changed

packages/contact-center/cc-components/src/components/task/task.types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,9 +386,9 @@ export interface ControlProps {
386386
allowConsultToQueue: boolean;
387387

388388
/**
389-
* Flag to enable or disable multi-party conference feature
389+
* Flag to enable or disable conference feature
390390
*/
391-
multiPartyConferenceEnabled: boolean;
391+
conferenceEnabled: boolean;
392392

393393
/**
394394
* Function to set the last target type

packages/contact-center/task/src/CallControl/index.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,7 @@ import {CallControlProps} from '../task.types';
88
import {CallControlComponent} from '@webex/cc-components';
99

1010
const CallControlInternal: React.FunctionComponent<CallControlProps> = observer(
11-
({
12-
onHoldResume,
13-
onEnd,
14-
onWrapUp,
15-
onRecordingToggle,
16-
onToggleMute,
17-
consultTransferOptions,
18-
multiPartyConferenceEnabled,
19-
}) => {
11+
({onHoldResume, onEnd, onWrapUp, onRecordingToggle, onToggleMute, consultTransferOptions, conferenceEnabled}) => {
2012
const {
2113
logger,
2214
currentTask,
@@ -42,7 +34,7 @@ const CallControlInternal: React.FunctionComponent<CallControlProps> = observer(
4234
deviceType,
4335
featureFlags,
4436
isMuted,
45-
multiPartyConferenceEnabled,
37+
conferenceEnabled,
4638
agentId,
4739
}),
4840
wrapupCodes,
@@ -65,7 +57,7 @@ const CallControl: React.FunctionComponent<CallControlProps> = (props) => {
6557
if (store.onErrorCallback) store.onErrorCallback('CallControl', error);
6658
}}
6759
>
68-
<CallControlInternal {...props} multiPartyConferenceEnabled={props.multiPartyConferenceEnabled ?? true} />
60+
<CallControlInternal {...props} conferenceEnabled={props.conferenceEnabled ?? true} />
6961
</ErrorBoundary>
7062
);
7163
};

packages/contact-center/task/src/CallControlCAD/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const CallControlCADInternal: React.FunctionComponent<CallControlProps> = observ
1616
onToggleMute,
1717
callControlClassName,
1818
callControlConsultClassName,
19-
multiPartyConferenceEnabled,
19+
conferenceEnabled,
2020
consultTransferOptions,
2121
}) => {
2222
const {
@@ -43,7 +43,7 @@ const CallControlCADInternal: React.FunctionComponent<CallControlProps> = observ
4343
deviceType,
4444
featureFlags,
4545
isMuted,
46-
multiPartyConferenceEnabled,
46+
conferenceEnabled,
4747
agentId,
4848
}),
4949
wrapupCodes,
@@ -68,7 +68,7 @@ const CallControlCAD: React.FunctionComponent<CallControlProps> = (props) => {
6868
if (store.onErrorCallback) store.onErrorCallback('CallControlCAD', error);
6969
}}
7070
>
71-
<CallControlCADInternal {...props} multiPartyConferenceEnabled={props.multiPartyConferenceEnabled ?? true} />
71+
<CallControlCADInternal {...props} conferenceEnabled={props.conferenceEnabled ?? true} />
7272
</ErrorBoundary>
7373
);
7474
};

packages/contact-center/task/src/Utils/constants.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,3 @@ export const MEDIA_TYPE_TELEPHONY = 'telephony';
33
export const MEDIA_TYPE_CHAT = 'chat';
44
export const MEDIA_TYPE_EMAIL = 'email';
55
export const MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE = 7;
6-
export const MAX_PARTICIPANTS_IN_THREE_PARTY_CONFERENCE = 2;

packages/contact-center/task/src/Utils/task-util.ts

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {
1717
MEDIA_TYPE_CHAT,
1818
MEDIA_TYPE_EMAIL,
1919
MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE,
20-
MAX_PARTICIPANTS_IN_THREE_PARTY_CONFERENCE,
2120
} from './constants';
2221
import {DeviceTypeFlags} from '../task.types';
2322

@@ -177,20 +176,14 @@ export function getConferenceButtonVisibility(
177176
webRtcEnabled: boolean,
178177
isCall: boolean,
179178
isChat: boolean,
180-
isBeingConsulted: boolean
179+
isBeingConsulted: boolean,
180+
conferenceEnabled: boolean
181181
): Visibility {
182-
const isVisible = ((isBrowser && isCall && webRtcEnabled) || isChat) && !isBeingConsulted;
182+
const isVisible = ((isBrowser && isCall && webRtcEnabled) || isChat) && !isBeingConsulted && conferenceEnabled;
183183

184184
return {isVisible, isEnabled: true};
185185
}
186186

187-
/**
188-
* Get visibility for Conference In Progress indicator
189-
*/
190-
export function getConferenceInProgressVisibility(task: ITask): boolean {
191-
return task?.data?.isConferenceInProgress ?? false;
192-
}
193-
194187
/**
195188
* Get visibility for Exit Conference button
196189
*/
@@ -199,9 +192,10 @@ export function getExitConferenceButtonVisibility(
199192
isConsultInitiatedOrAccepted: boolean,
200193
consultCallHeld: boolean,
201194
isHeld: boolean,
202-
isConsultCompleted: boolean
195+
isConsultCompleted: boolean,
196+
conferenceEnabled: boolean
203197
): Visibility {
204-
const isVisible = isConferenceInProgress && !isConsultInitiatedOrAccepted;
198+
const isVisible = isConferenceInProgress && !isConsultInitiatedOrAccepted && conferenceEnabled;
205199
const isConferenceWithConsultNotHeld = isConferenceInProgress && isConsultInitiatedOrAccepted && !consultCallHeld;
206200
// Disable if: conference with consult not held OR (held AND in conference AND consult completed)
207201
const isEnabled = !isConferenceWithConsultNotHeld && !(isHeld && isConferenceInProgress && isConsultCompleted);
@@ -217,9 +211,10 @@ export function getMergeConferenceButtonVisibility(
217211
isConsultAccepted: boolean,
218212
consultCallHeld: boolean,
219213
isConferenceInProgress: boolean,
220-
isCustomerInCall: boolean
214+
isCustomerInCall: boolean,
215+
conferenceEnabled: boolean
221216
): Visibility {
222-
const isVisible = isConsultInitiatedOrAccepted && isCustomerInCall;
217+
const isVisible = isConsultInitiatedOrAccepted && isCustomerInCall && conferenceEnabled;
223218
const isConferenceWithConsultNotHeld = isConferenceInProgress && isConsultInitiatedOrAccepted && !consultCallHeld;
224219
const isEnabled = isConsultAccepted && consultCallHeld && !isConferenceWithConsultNotHeld;
225220

@@ -291,9 +286,10 @@ export function getMergeConferenceConsultButtonVisibility(
291286
isConsultAccepted: boolean,
292287
isConsultInitiated: boolean,
293288
consultCallHeld: boolean,
294-
isCustomerInCall: boolean
289+
isCustomerInCall: boolean,
290+
conferenceEnabled: boolean
295291
): Visibility {
296-
const isVisible = isConsultAccepted || isConsultInitiated;
292+
const isVisible = (isConsultAccepted || isConsultInitiated) && conferenceEnabled;
297293
const isEnabled = !consultCallHeld && isConsultAccepted && isCustomerInCall;
298294

299295
return {isVisible, isEnabled};
@@ -377,7 +373,7 @@ export function getWrapupButtonVisibility(task: ITask): Visibility {
377373
* @param featureFlags Feature flags configuration object
378374
* @param task The task object
379375
* @param agentId The agent ID
380-
* @param multiPartyConferenceEnabled Whether multiparty conference is enabled
376+
* @param conferenceEnabled Whether conference is enabled
381377
* @param logger Optional logger instance
382378
* @returns An object containing the visibility and state of various controls
383379
*/
@@ -386,7 +382,7 @@ export function getControlsVisibility(
386382
featureFlags: {[key: string]: boolean},
387383
task: ITask,
388384
agentId: string,
389-
multiPartyConferenceEnabled: boolean,
385+
conferenceEnabled: boolean,
390386
logger?: ILogger
391387
) {
392388
try {
@@ -409,7 +405,7 @@ export function getControlsVisibility(
409405

410406
// Calculate task state flags
411407
const isTransferVisibility = isBrowser ? webRtcEnabled : true;
412-
const isConferenceInProgress = task?.data?.isConferenceInProgress ?? false;
408+
const isConferenceInProgress = (task?.data?.isConferenceInProgress && conferenceEnabled) ?? false;
413409
const isConsultInProgress = getIsConsultInProgress(task);
414410
const isHeld = findHoldStatus(task, 'mainCall', agentId);
415411
const isCustomerInCall = getIsCustomerInCall(task);
@@ -419,9 +415,6 @@ export function getControlsVisibility(
419415

420416
// Calculate conference participants count
421417
const conferenceParticipantsCount = getConferenceParticipantsCount(task);
422-
const maxParticipantsInConference = multiPartyConferenceEnabled
423-
? MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE
424-
: MAX_PARTICIPANTS_IN_THREE_PARTY_CONFERENCE;
425418

426419
// Calculate consult status flags (REUSED CONDITIONS)
427420
const isConsultInitiated = taskConsultStatus === ConsultStatus.CONSULT_INITIATED;
@@ -472,20 +465,29 @@ export function getControlsVisibility(
472465

473466
// Transfer and conference controls
474467
transfer: getTransferButtonVisibility(isTransferVisibility, isConferenceInProgress, isConsultInitiatedOrAccepted),
475-
conference: getConferenceButtonVisibility(isBrowser, webRtcEnabled, isCall, isChat, isBeingConsulted),
468+
conference: getConferenceButtonVisibility(
469+
isBrowser,
470+
webRtcEnabled,
471+
isCall,
472+
isChat,
473+
isBeingConsulted,
474+
conferenceEnabled
475+
),
476476
exitConference: getExitConferenceButtonVisibility(
477477
isConferenceInProgress,
478478
isConsultInitiatedOrAccepted,
479479
consultCallHeld,
480480
isHeld,
481-
isConsultCompleted
481+
isConsultCompleted,
482+
conferenceEnabled
482483
),
483484
mergeConference: getMergeConferenceButtonVisibility(
484485
isConsultInitiatedOrAcceptedOnly,
485486
isConsultAccepted,
486487
consultCallHeld,
487488
isConferenceInProgress,
488-
isCustomerInCall
489+
isCustomerInCall,
490+
conferenceEnabled
489491
),
490492

491493
// Consult controls
@@ -495,7 +497,7 @@ export function getControlsVisibility(
495497
isConsultInProgress,
496498
isCustomerInCall,
497499
conferenceParticipantsCount,
498-
maxParticipantsInConference,
500+
MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE,
499501
isBeingConsulted,
500502
isHeld,
501503
isConsultCompleted,
@@ -524,7 +526,8 @@ export function getControlsVisibility(
524526
isConsultAccepted,
525527
isConsultInitiated,
526528
consultCallHeld,
527-
isCustomerInCall
529+
isCustomerInCall,
530+
conferenceEnabled
528531
),
529532
muteUnmuteConsult: getMuteUnmuteConsultButtonVisibility(
530533
isBrowser,
@@ -549,7 +552,7 @@ export function getControlsVisibility(
549552
wrapup: getWrapupButtonVisibility(task),
550553

551554
// State flags
552-
isConferenceInProgress: getConferenceInProgressVisibility(task),
555+
isConferenceInProgress,
553556
isConsultInitiated,
554557
isConsultInitiatedAndAccepted: isConsultAccepted,
555558
isConsultReceived: isBeingConsulted,

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ export const useCallControl = (props: useCallControlProps) => {
280280
deviceType,
281281
featureFlags,
282282
isMuted,
283-
multiPartyConferenceEnabled,
283+
conferenceEnabled,
284284
agentId,
285285
} = props;
286286
const [isRecording, setIsRecording] = useState(true);
@@ -868,8 +868,8 @@ export const useCallControl = (props: useCallControlProps) => {
868868
};
869869

870870
const controlVisibility = useMemo(
871-
() => getControlsVisibility(deviceType, featureFlags, currentTask, agentId, multiPartyConferenceEnabled, logger),
872-
[deviceType, featureFlags, currentTask, agentId, multiPartyConferenceEnabled, logger]
871+
() => getControlsVisibility(deviceType, featureFlags, currentTask, agentId, conferenceEnabled, logger),
872+
[deviceType, featureFlags, currentTask, agentId, conferenceEnabled, logger]
873873
);
874874

875875
// Add useEffect for auto wrap-up timer

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ export type CallControlProps = Partial<
2020
| 'callControlClassName'
2121
| 'callControlConsultClassName'
2222
| 'onToggleMute'
23-
| 'multiPartyConferenceEnabled'
23+
| 'conferenceEnabled'
2424
| 'consultTransferOptions'
2525
>
2626
>;
2727

2828
export type useCallControlProps = Pick<
2929
ControlProps,
30-
'currentTask' | 'logger' | 'deviceType' | 'featureFlags' | 'isMuted' | 'multiPartyConferenceEnabled' | 'agentId'
30+
'currentTask' | 'logger' | 'deviceType' | 'featureFlags' | 'isMuted' | 'conferenceEnabled' | 'agentId'
3131
> &
3232
Partial<Pick<ControlProps, 'onHoldResume' | 'onEnd' | 'onWrapUp' | 'onRecordingToggle' | 'onToggleMute'>>;
3333

packages/contact-center/task/tests/CallControl/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ describe('CallControl Component', () => {
104104
expect(useCallControlSpy).toHaveBeenCalledWith({
105105
currentTask: null,
106106
onHoldResume: onHoldResumeCb,
107-
multiPartyConferenceEnabled: true,
107+
conferenceEnabled: true,
108108
onEnd: onEndCb,
109109
onWrapUp: onWrapUpCb,
110110
onRecordingToggle: onRecordingToggleCb,

packages/contact-center/task/tests/CallControlCAD/index.tsx

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,12 @@ describe('CallControlCAD Component', () => {
111111
featureFlags: store.featureFlags,
112112
deviceType: '',
113113
isMuted: false,
114-
multiPartyConferenceEnabled: true,
114+
conferenceEnabled: true,
115115
agentId: store.agentId,
116116
});
117117
});
118118

119-
it('should use default multiPartyConferenceEnabled value when not provided', () => {
119+
it('should use default conferenceEnabled value when not provided', () => {
120120
const useCallControlSpy = jest.spyOn(helper, 'useCallControl').mockReturnValue({
121121
currentTask: mockTask,
122122
endCall: jest.fn(),
@@ -185,12 +185,12 @@ describe('CallControlCAD Component', () => {
185185
// Should default to true when not provided
186186
expect(useCallControlSpy).toHaveBeenCalledWith(
187187
expect.objectContaining({
188-
multiPartyConferenceEnabled: true,
188+
conferenceEnabled: true,
189189
})
190190
);
191191
});
192192

193-
it('should use provided multiPartyConferenceEnabled value', () => {
193+
it('should use provided conferenceEnabled value', () => {
194194
const useCallControlSpy = jest.spyOn(helper, 'useCallControl').mockReturnValue({
195195
currentTask: mockTask,
196196
endCall: jest.fn(),
@@ -255,18 +255,13 @@ describe('CallControlCAD Component', () => {
255255
});
256256

257257
render(
258-
<CallControlCAD
259-
onHoldResume={onHoldResumeCb}
260-
onEnd={onEndCb}
261-
onWrapUp={onWrapUpCb}
262-
multiPartyConferenceEnabled={false}
263-
/>
258+
<CallControlCAD onHoldResume={onHoldResumeCb} onEnd={onEndCb} onWrapUp={onWrapUpCb} conferenceEnabled={false} />
264259
);
265260

266261
// Should use the provided value
267262
expect(useCallControlSpy).toHaveBeenCalledWith(
268263
expect.objectContaining({
269-
multiPartyConferenceEnabled: false,
264+
conferenceEnabled: false,
270265
})
271266
);
272267
});

0 commit comments

Comments
 (0)