Skip to content

Commit 4fdf2a3

Browse files
authored
feat(plugin-cc): refactored-voice-class (#4335)
1 parent f0af195 commit 4fdf2a3

File tree

13 files changed

+1118
-242
lines changed

13 files changed

+1118
-242
lines changed

docs/samples/contact-center/app.js

Lines changed: 121 additions & 110 deletions
Large diffs are not rendered by default.

packages/@webex/plugin-cc/src/cc.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,6 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter
221221
const resp = await this.connectWebsocket();
222222
// Ensure 'dn' is always populated from 'defaultDn'
223223
resp.dn = resp.defaultDn;
224-
const configFlags: ConfigFlags = {
225-
isEndCallEnabled: this.agentConfig.isEndCallEnabled,
226-
isEndConsultEnabled: this.agentConfig.isEndConsultEnabled,
227-
webRtcEnabled: this.agentConfig.webRtcEnabled,
228-
autoWrapup: this.agentConfig.wrapUpData?.wrapUpProps?.autoWrapup ?? false,
229-
};
230-
this.taskManager.setConfigFlags(configFlags);
231224
this.metricsManager.trackEvent(
232225
METRIC_EVENT_NAMES.WEBSOCKET_REGISTER_SUCCESS,
233226
{
@@ -424,6 +417,13 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter
424417
const agentId = data.agentId;
425418
const orgId = this.$webex.credentials.getOrgId();
426419
this.agentConfig = await this.services.config.getAgentConfig(orgId, agentId);
420+
const configFlags: ConfigFlags = {
421+
isEndCallEnabled: this.agentConfig.isEndCallEnabled,
422+
isEndConsultEnabled: this.agentConfig.isEndConsultEnabled,
423+
webRtcEnabled: this.agentConfig.webRtcEnabled,
424+
autoWrapup: this.agentConfig.wrapUpData?.wrapUpProps?.autoWrapup ?? false,
425+
};
426+
this.taskManager.setConfigFlags(configFlags);
427427
LoggerProxy.log(`Agent config is fetched successfully`, {
428428
module: CC_FILE,
429429
method: METHODS.CONNECT_WEBSOCKET,

packages/@webex/plugin-cc/src/constants.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,9 @@ export const METHODS = {
4848
HANDLE_INCOMING_TASK: 'handleIncomingTask',
4949
HANDLE_TASK_HYDRATE: 'handleTaskHydrate',
5050
INCOMING_TASK_LISTENER: 'incomingTaskListener',
51+
HOLD_RESUME: 'holdResume',
52+
ACCEPT: 'accept',
53+
REJECT: 'reject',
54+
TRANSFER_CALL: 'transferCall',
55+
COMPLETE_TRANSFER: 'completeTransfer',
5156
};

packages/@webex/plugin-cc/src/services/task/Task.ts

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ export default abstract class Task extends EventEmitter implements ITask {
4848

4949
private initialiseUIControls() {
5050
this.taskUiControls = {
51-
accept: new TaskButtonControl(true, true),
52-
decline: new TaskButtonControl(true, true),
51+
accept: new TaskButtonControl(false, false),
52+
decline: new TaskButtonControl(false, false),
5353
hold: new TaskButtonControl(false, false),
5454
mute: new TaskButtonControl(false, false),
55-
end: new TaskButtonControl(true, true),
56-
transfer: new TaskButtonControl(true, true),
55+
end: new TaskButtonControl(false, false),
56+
transfer: new TaskButtonControl(false, false),
5757
consult: new TaskButtonControl(false, false),
5858
consultTransfer: new TaskButtonControl(false, false),
5959
endConsult: new TaskButtonControl(false, false),
@@ -68,6 +68,35 @@ export default abstract class Task extends EventEmitter implements ITask {
6868
*/
6969
protected setUIControls() {}
7070

71+
/**
72+
*
73+
* @param methodName - The name of the method that is unsupported
74+
* @throws Error
75+
*/
76+
protected unsupportedMethodError(methodName: string) {
77+
LoggerProxy.error(`Unsupported operation`, {
78+
module: 'TASK',
79+
method: methodName,
80+
});
81+
throw new Error(`Unsupported operation: ${methodName}`);
82+
}
83+
84+
/**
85+
* Apply visibility & enabled flags in one go.
86+
* Usage: updateTaskUiControls({ hold: [true,true], end: [false,true] })
87+
*/
88+
protected updateTaskUiControls(
89+
config: Partial<Record<keyof typeof this.taskUiControls, [boolean, boolean]>>
90+
): void {
91+
Object.entries(config).forEach(([k, [vis, en]]) => {
92+
const ctl = this.taskUiControls[k as keyof typeof this.taskUiControls];
93+
if (ctl) {
94+
ctl.setVisiblity(vis);
95+
ctl.setEnabled(en);
96+
}
97+
});
98+
}
99+
71100
/**
72101
* This method is used to update the task data.
73102
* @param updatedData - TaskData

packages/@webex/plugin-cc/src/services/task/TaskManager.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,18 @@ export default class TaskManager extends EventEmitter {
9595
});
9696
switch (payload.data.type) {
9797
case CC_EVENTS.AGENT_CONTACT:
98-
this.taskCollection[payload.data.interactionId] = task;
98+
if (!task) {
99+
// Re-create task if it does not exist
100+
// This can happen when the task is created after the event is received (multi session)
101+
task = TaskFactory.createTask(
102+
this.contact,
103+
this.webCallingService,
104+
{...payload.data, isConsulted: false},
105+
this.configFlags
106+
);
107+
this.taskCollection[payload.data.interactionId] = task;
108+
}
109+
this.updateTaskData(task, payload.data);
99110
this.emit(TASK_EVENTS.TASK_HYDRATE, task);
100111
break;
101112

@@ -238,7 +249,11 @@ export default class TaskManager extends EventEmitter {
238249
task.emit(TASK_EVENTS.TASK_CONSULT_QUEUE_CANCELLED, task);
239250
break;
240251
case CC_EVENTS.AGENT_WRAPUP:
241-
this.updateTaskData(task, payload.data);
252+
this.updateTaskData(task, {
253+
...payload.data,
254+
wrapUpRequired: true,
255+
});
256+
task.emit(TASK_EVENTS.TASK_END, task);
242257
break;
243258
case CC_EVENTS.AGENT_WRAPPEDUP:
244259
this.removeTaskFromCollection(task);

packages/@webex/plugin-cc/src/services/task/types.ts

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,23 +1163,15 @@ export interface ITask extends EventEmitter {
11631163
*/
11641164
export interface IVoice extends ITask {
11651165
/**
1166-
* This is used to hold the task.
1166+
* This is used to hold or resume the task.
11671167
* @returns Promise<TaskResponse>
11681168
* @example
11691169
* ```
1170-
* task.hold();
1170+
* task.holdResume();
11711171
* ```
11721172
*/
1173-
hold(): Promise<TaskResponse>;
1174-
/**
1175-
* This is used to resume the task.
1176-
* @returns Promise<TaskResponse>
1177-
* @example
1178-
* ```
1179-
* task.resume();
1180-
* ```
1181-
*/
1182-
resume(): Promise<TaskResponse>;
1173+
holdResume(): Promise<TaskResponse>;
1174+
11831175
/**
11841176
* This is used to consult the task.
11851177
* @param consultPayload
@@ -1244,31 +1236,25 @@ export class TaskButtonControl {
12441236
}
12451237

12461238
/**
1247-
* Shows the button control.
1248-
*/
1249-
show() {
1250-
this.visible = true;
1251-
}
1252-
1253-
/**
1254-
* Hides the button control.
1255-
*/
1256-
hide() {
1257-
this.visible = false;
1258-
}
1259-
1260-
/**
1261-
* Enables the button control.
1239+
*
1240+
* @param visible - Indicates whether the button control is visible or not.
1241+
*
1242+
* This method sets the visibility.
1243+
* If `visible` is true, the button will be shown;
12621244
*/
1263-
enable() {
1264-
this.enabled = true;
1245+
setVisiblity(visible: boolean) {
1246+
this.visible = visible;
12651247
}
12661248

12671249
/**
1268-
* Disables the button control.
1250+
*
1251+
* @param enabled - Indicates whether the button control is enabled or not.
1252+
*
1253+
* This method sets the enabled state of the button control.
1254+
* If `enabled` is true, the button will be enabled; otherwise, it will be disabled.
12691255
*/
1270-
disable() {
1271-
this.enabled = false;
1256+
setEnabled(enabled: boolean) {
1257+
this.enabled = enabled;
12721258
}
12731259
}
12741260

0 commit comments

Comments
 (0)