Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -386,9 +386,9 @@ export interface ControlProps {
allowConsultToQueue: boolean;

/**
* Flag to enable or disable multi-party conference feature
* Flag to enable or disable conference feature
*/
multiPartyConferenceEnabled: boolean;
conferenceEnabled: boolean;

/**
* Function to set the last target type
Expand Down
14 changes: 3 additions & 11 deletions packages/contact-center/task/src/CallControl/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,7 @@ import {CallControlProps} from '../task.types';
import {CallControlComponent} from '@webex/cc-components';

const CallControlInternal: React.FunctionComponent<CallControlProps> = observer(
({
onHoldResume,
onEnd,
onWrapUp,
onRecordingToggle,
onToggleMute,
consultTransferOptions,
multiPartyConferenceEnabled,
}) => {
({onHoldResume, onEnd, onWrapUp, onRecordingToggle, onToggleMute, consultTransferOptions, conferenceEnabled}) => {
const {
logger,
currentTask,
Expand All @@ -42,7 +34,7 @@ const CallControlInternal: React.FunctionComponent<CallControlProps> = observer(
deviceType,
featureFlags,
isMuted,
multiPartyConferenceEnabled,
conferenceEnabled,
agentId,
}),
wrapupCodes,
Expand All @@ -65,7 +57,7 @@ const CallControl: React.FunctionComponent<CallControlProps> = (props) => {
if (store.onErrorCallback) store.onErrorCallback('CallControl', error);
}}
>
<CallControlInternal {...props} multiPartyConferenceEnabled={props.multiPartyConferenceEnabled ?? true} />
<CallControlInternal {...props} conferenceEnabled={props.conferenceEnabled ?? true} />

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this extra step? Why can't props itself handle it? I see we anyway read from props for props.conferenceEnabled

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if nothing passed we need to make sure by default enable it. If We can do it better way we can handle it in next PR.

</ErrorBoundary>
);
};
Expand Down
6 changes: 3 additions & 3 deletions packages/contact-center/task/src/CallControlCAD/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const CallControlCADInternal: React.FunctionComponent<CallControlProps> = observ
onToggleMute,
callControlClassName,
callControlConsultClassName,
multiPartyConferenceEnabled,
conferenceEnabled,
consultTransferOptions,
}) => {
const {
Expand All @@ -43,7 +43,7 @@ const CallControlCADInternal: React.FunctionComponent<CallControlProps> = observ
deviceType,
featureFlags,
isMuted,
multiPartyConferenceEnabled,
conferenceEnabled,
agentId,
}),
wrapupCodes,
Expand All @@ -68,7 +68,7 @@ const CallControlCAD: React.FunctionComponent<CallControlProps> = (props) => {
if (store.onErrorCallback) store.onErrorCallback('CallControlCAD', error);
}}
>
<CallControlCADInternal {...props} multiPartyConferenceEnabled={props.multiPartyConferenceEnabled ?? true} />
<CallControlCADInternal {...props} conferenceEnabled={props.conferenceEnabled ?? true} />

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question as above

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if nothing passed we need to make sure by default enable it. If We can do it better way we can handle it in next PR.

</ErrorBoundary>
);
};
Expand Down
1 change: 0 additions & 1 deletion packages/contact-center/task/src/Utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@ export const MEDIA_TYPE_TELEPHONY = 'telephony';
export const MEDIA_TYPE_CHAT = 'chat';
export const MEDIA_TYPE_EMAIL = 'email';
export const MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE = 7;
export const MAX_PARTICIPANTS_IN_THREE_PARTY_CONFERENCE = 2;
59 changes: 31 additions & 28 deletions packages/contact-center/task/src/Utils/task-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
MEDIA_TYPE_CHAT,
MEDIA_TYPE_EMAIL,
MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE,
MAX_PARTICIPANTS_IN_THREE_PARTY_CONFERENCE,
} from './constants';
import {DeviceTypeFlags} from '../task.types';

Expand Down Expand Up @@ -177,20 +176,14 @@ export function getConferenceButtonVisibility(
webRtcEnabled: boolean,
isCall: boolean,
isChat: boolean,
isBeingConsulted: boolean
isBeingConsulted: boolean,
conferenceEnabled: boolean
): Visibility {
const isVisible = ((isBrowser && isCall && webRtcEnabled) || isChat) && !isBeingConsulted;
const isVisible = ((isBrowser && isCall && webRtcEnabled) || isChat) && !isBeingConsulted && conferenceEnabled;

return {isVisible, isEnabled: true};
}

/**
* Get visibility for Conference In Progress indicator
*/
export function getConferenceInProgressVisibility(task: ITask): boolean {
return task?.data?.isConferenceInProgress ?? false;
}

/**
* Get visibility for Exit Conference button
*/
Expand All @@ -199,9 +192,10 @@ export function getExitConferenceButtonVisibility(
isConsultInitiatedOrAccepted: boolean,
consultCallHeld: boolean,
isHeld: boolean,
isConsultCompleted: boolean
isConsultCompleted: boolean,
conferenceEnabled: boolean
): Visibility {
const isVisible = isConferenceInProgress && !isConsultInitiatedOrAccepted;
const isVisible = isConferenceInProgress && !isConsultInitiatedOrAccepted && conferenceEnabled;
const isConferenceWithConsultNotHeld = isConferenceInProgress && isConsultInitiatedOrAccepted && !consultCallHeld;
// Disable if: conference with consult not held OR (held AND in conference AND consult completed)
const isEnabled = !isConferenceWithConsultNotHeld && !(isHeld && isConferenceInProgress && isConsultCompleted);
Expand All @@ -217,9 +211,10 @@ export function getMergeConferenceButtonVisibility(
isConsultAccepted: boolean,
consultCallHeld: boolean,
isConferenceInProgress: boolean,
isCustomerInCall: boolean
isCustomerInCall: boolean,
conferenceEnabled: boolean
): Visibility {
const isVisible = isConsultInitiatedOrAccepted && isCustomerInCall;
const isVisible = isConsultInitiatedOrAccepted && isCustomerInCall && conferenceEnabled;
const isConferenceWithConsultNotHeld = isConferenceInProgress && isConsultInitiatedOrAccepted && !consultCallHeld;
const isEnabled = isConsultAccepted && consultCallHeld && !isConferenceWithConsultNotHeld;

Expand Down Expand Up @@ -291,9 +286,10 @@ export function getMergeConferenceConsultButtonVisibility(
isConsultAccepted: boolean,
isConsultInitiated: boolean,
consultCallHeld: boolean,
isCustomerInCall: boolean
isCustomerInCall: boolean,
conferenceEnabled: boolean
): Visibility {
const isVisible = isConsultAccepted || isConsultInitiated;
const isVisible = (isConsultAccepted || isConsultInitiated) && conferenceEnabled;
const isEnabled = !consultCallHeld && isConsultAccepted && isCustomerInCall;

return {isVisible, isEnabled};
Expand Down Expand Up @@ -377,7 +373,7 @@ export function getWrapupButtonVisibility(task: ITask): Visibility {
* @param featureFlags Feature flags configuration object
* @param task The task object
* @param agentId The agent ID
* @param multiPartyConferenceEnabled Whether multiparty conference is enabled
* @param conferenceEnabled Whether conference is enabled
* @param logger Optional logger instance
* @returns An object containing the visibility and state of various controls
*/
Expand All @@ -386,7 +382,7 @@ export function getControlsVisibility(
featureFlags: {[key: string]: boolean},
task: ITask,
agentId: string,
multiPartyConferenceEnabled: boolean,
conferenceEnabled: boolean,
logger?: ILogger
) {
try {
Expand All @@ -409,7 +405,7 @@ export function getControlsVisibility(

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

// Calculate conference participants count
const conferenceParticipantsCount = getConferenceParticipantsCount(task);
const maxParticipantsInConference = multiPartyConferenceEnabled
? MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE
: MAX_PARTICIPANTS_IN_THREE_PARTY_CONFERENCE;

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

// Transfer and conference controls
transfer: getTransferButtonVisibility(isTransferVisibility, isConferenceInProgress, isConsultInitiatedOrAccepted),
conference: getConferenceButtonVisibility(isBrowser, webRtcEnabled, isCall, isChat, isBeingConsulted),
conference: getConferenceButtonVisibility(
isBrowser,
webRtcEnabled,
isCall,
isChat,
isBeingConsulted,
conferenceEnabled
),
exitConference: getExitConferenceButtonVisibility(
isConferenceInProgress,
isConsultInitiatedOrAccepted,
consultCallHeld,
isHeld,
isConsultCompleted
isConsultCompleted,
conferenceEnabled
),
mergeConference: getMergeConferenceButtonVisibility(
isConsultInitiatedOrAcceptedOnly,
isConsultAccepted,
consultCallHeld,
isConferenceInProgress,
isCustomerInCall
isCustomerInCall,
conferenceEnabled
),

// Consult controls
Expand All @@ -495,7 +497,7 @@ export function getControlsVisibility(
isConsultInProgress,
isCustomerInCall,
conferenceParticipantsCount,
maxParticipantsInConference,
MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE,
Comment thread
mkesavan13 marked this conversation as resolved.
isBeingConsulted,
isHeld,
isConsultCompleted,
Expand Down Expand Up @@ -524,7 +526,8 @@ export function getControlsVisibility(
isConsultAccepted,
isConsultInitiated,
consultCallHeld,
isCustomerInCall
isCustomerInCall,
conferenceEnabled
),
muteUnmuteConsult: getMuteUnmuteConsultButtonVisibility(
isBrowser,
Expand All @@ -549,7 +552,7 @@ export function getControlsVisibility(
wrapup: getWrapupButtonVisibility(task),

// State flags
isConferenceInProgress: getConferenceInProgressVisibility(task),
isConferenceInProgress,
isConsultInitiated,
isConsultInitiatedAndAccepted: isConsultAccepted,
isConsultReceived: isBeingConsulted,
Expand Down
6 changes: 3 additions & 3 deletions packages/contact-center/task/src/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ export const useCallControl = (props: useCallControlProps) => {
deviceType,
featureFlags,
isMuted,
multiPartyConferenceEnabled,
conferenceEnabled,
agentId,
} = props;
const [isRecording, setIsRecording] = useState(true);
Expand Down Expand Up @@ -868,8 +868,8 @@ export const useCallControl = (props: useCallControlProps) => {
};

const controlVisibility = useMemo(
() => getControlsVisibility(deviceType, featureFlags, currentTask, agentId, multiPartyConferenceEnabled, logger),
[deviceType, featureFlags, currentTask, agentId, multiPartyConferenceEnabled, logger]
() => getControlsVisibility(deviceType, featureFlags, currentTask, agentId, conferenceEnabled, logger),
[deviceType, featureFlags, currentTask, agentId, conferenceEnabled, logger]
);

// Add useEffect for auto wrap-up timer
Expand Down
4 changes: 2 additions & 2 deletions packages/contact-center/task/src/task.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ export type CallControlProps = Partial<
| 'callControlClassName'
| 'callControlConsultClassName'
| 'onToggleMute'
| 'multiPartyConferenceEnabled'
| 'conferenceEnabled'
| 'consultTransferOptions'
>
>;

export type useCallControlProps = Pick<
ControlProps,
'currentTask' | 'logger' | 'deviceType' | 'featureFlags' | 'isMuted' | 'multiPartyConferenceEnabled' | 'agentId'
'currentTask' | 'logger' | 'deviceType' | 'featureFlags' | 'isMuted' | 'conferenceEnabled' | 'agentId'
> &
Partial<Pick<ControlProps, 'onHoldResume' | 'onEnd' | 'onWrapUp' | 'onRecordingToggle' | 'onToggleMute'>>;

Expand Down
2 changes: 1 addition & 1 deletion packages/contact-center/task/tests/CallControl/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ describe('CallControl Component', () => {
expect(useCallControlSpy).toHaveBeenCalledWith({
currentTask: null,
onHoldResume: onHoldResumeCb,
multiPartyConferenceEnabled: true,
conferenceEnabled: true,
onEnd: onEndCb,
onWrapUp: onWrapUpCb,
onRecordingToggle: onRecordingToggleCb,
Expand Down
17 changes: 6 additions & 11 deletions packages/contact-center/task/tests/CallControlCAD/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,12 @@ describe('CallControlCAD Component', () => {
featureFlags: store.featureFlags,
deviceType: '',
isMuted: false,
multiPartyConferenceEnabled: true,
conferenceEnabled: true,
agentId: store.agentId,
});
});

it('should use default multiPartyConferenceEnabled value when not provided', () => {
it('should use default conferenceEnabled value when not provided', () => {
const useCallControlSpy = jest.spyOn(helper, 'useCallControl').mockReturnValue({
currentTask: mockTask,
endCall: jest.fn(),
Expand Down Expand Up @@ -185,12 +185,12 @@ describe('CallControlCAD Component', () => {
// Should default to true when not provided
expect(useCallControlSpy).toHaveBeenCalledWith(
expect.objectContaining({
multiPartyConferenceEnabled: true,
conferenceEnabled: true,
})
);
});

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

render(
<CallControlCAD
onHoldResume={onHoldResumeCb}
onEnd={onEndCb}
onWrapUp={onWrapUpCb}
multiPartyConferenceEnabled={false}
/>
<CallControlCAD onHoldResume={onHoldResumeCb} onEnd={onEndCb} onWrapUp={onWrapUpCb} conferenceEnabled={false} />
);

// Should use the provided value
expect(useCallControlSpy).toHaveBeenCalledWith(
expect.objectContaining({
multiPartyConferenceEnabled: false,
conferenceEnabled: false,
})
);
});
Expand Down
Loading
Loading