@microsoft/omnichannel-chat-widget 1.8.2-main.5199342 → 1.8.2-main.b882454
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -1
- package/lib/cjs/common/Constants.js +17 -3
- package/lib/cjs/common/telemetry/TelemetryConstants.js +2 -0
- package/lib/cjs/common/utils.js +27 -2
- package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +4 -4
- package/lib/cjs/components/draggable/DraggableChatWidget.js +16 -1
- package/lib/cjs/components/livechatwidget/common/createInternetConnectionChangeHandler.js +22 -9
- package/lib/cjs/components/livechatwidget/common/createMarkdown.js +54 -1
- package/lib/cjs/components/livechatwidget/common/customEventHandler.js +53 -0
- package/lib/cjs/components/livechatwidget/common/endChat.js +19 -7
- package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +33 -1
- package/lib/cjs/components/livechatwidget/common/liveChatConfigUtils.js +18 -1
- package/lib/cjs/components/livechatwidget/common/renderSurveyHelpers.js +54 -7
- package/lib/cjs/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +15 -2
- package/lib/cjs/components/livechatwidget/common/startChat.js +6 -4
- package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +27 -12
- package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +18 -14
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.js +42 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.js +4 -3
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware.js +12 -6
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +41 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +45 -0
- package/lib/cjs/contexts/common/CustomEventType.js +1 -0
- package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +3 -1
- package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +3 -1
- package/lib/cjs/contexts/createReducer.js +30 -0
- package/lib/cjs/controller/componentController.js +2 -2
- package/lib/cjs/firstresponselatency/FirstMessageTrackerFromBot.js +101 -36
- package/lib/cjs/firstresponselatency/FirstResponseLatencyTracker.js +39 -21
- package/lib/cjs/firstresponselatency/util.js +60 -31
- package/lib/cjs/plugins/newMessageEventHandler.js +12 -6
- package/lib/esm/common/Constants.js +15 -2
- package/lib/esm/common/telemetry/TelemetryConstants.js +2 -0
- package/lib/esm/common/utils.js +21 -0
- package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +4 -4
- package/lib/esm/components/draggable/DraggableChatWidget.js +16 -1
- package/lib/esm/components/livechatwidget/common/createInternetConnectionChangeHandler.js +22 -9
- package/lib/esm/components/livechatwidget/common/createMarkdown.js +54 -1
- package/lib/esm/components/livechatwidget/common/customEventHandler.js +45 -0
- package/lib/esm/components/livechatwidget/common/endChat.js +19 -7
- package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +33 -1
- package/lib/esm/components/livechatwidget/common/liveChatConfigUtils.js +16 -0
- package/lib/esm/components/livechatwidget/common/renderSurveyHelpers.js +56 -9
- package/lib/esm/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +16 -3
- package/lib/esm/components/livechatwidget/common/startChat.js +6 -4
- package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +27 -12
- package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +18 -14
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.js +36 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.js +4 -4
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware.js +12 -6
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +33 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +38 -0
- package/lib/esm/contexts/common/CustomEventType.js +1 -0
- package/lib/esm/contexts/common/LiveChatWidgetActionType.js +3 -1
- package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +3 -1
- package/lib/esm/contexts/createReducer.js +30 -0
- package/lib/esm/controller/componentController.js +2 -2
- package/lib/esm/firstresponselatency/FirstMessageTrackerFromBot.js +101 -36
- package/lib/esm/firstresponselatency/FirstResponseLatencyTracker.js +39 -21
- package/lib/esm/firstresponselatency/util.js +57 -29
- package/lib/esm/plugins/newMessageEventHandler.js +12 -6
- package/lib/types/common/Constants.d.ts +14 -2
- package/lib/types/common/telemetry/TelemetryConstants.d.ts +2 -0
- package/lib/types/common/utils.d.ts +8 -0
- package/lib/types/components/livechatwidget/common/customEventHandler.d.ts +4 -0
- package/lib/types/components/livechatwidget/common/liveChatConfigUtils.d.ts +1 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.d.ts +8 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.d.ts +1 -1
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware.d.ts +1 -1
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.d.ts +22 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.d.ts +5 -0
- package/lib/types/contexts/common/CustomEventType.d.ts +6 -0
- package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +2 -0
- package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +3 -1
- package/lib/types/firstresponselatency/FirstResponseLatencyTracker.d.ts +2 -2
- package/lib/types/firstresponselatency/util.d.ts +17 -0
- package/lib/types/plugins/newMessageEventHandler.d.ts +1 -1
- package/package.json +5 -5
|
@@ -12,13 +12,13 @@ var _Constants2 = require("../common/Constants");
|
|
|
12
12
|
var _FirstResponseLatencyTracker = require("../firstresponselatency/FirstResponseLatencyTracker");
|
|
13
13
|
var _TelemetryHelper = require("../common/telemetry/TelemetryHelper");
|
|
14
14
|
var _TelemetryManager = require("../common/telemetry/TelemetryManager");
|
|
15
|
-
const createOnNewAdapterActivityHandler = (chatId, userId) => {
|
|
15
|
+
const createOnNewAdapterActivityHandler = (chatId, userId, startTime) => {
|
|
16
16
|
// Hooking the message tracker in the listener, a bit invasive but easier to control.
|
|
17
17
|
const firstResponseLatencyTracker = new _FirstResponseLatencyTracker.FirstResponseLatencyTracker();
|
|
18
18
|
// epoch time in utc for when start to listen.
|
|
19
19
|
// We dont longer have a mechanism to know if a message is history or new, so any message older than the time we start listening will be considered a history message.
|
|
20
20
|
// this is a workaround for the fact that we dont have a way to identify if a message is history or new, and it will provide consistency across different scenarios
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
let isHistoryMessageReceivedEventRaised = false;
|
|
23
23
|
const onNewAdapterActivityHandler = activity => {
|
|
24
24
|
raiseMessageEvent(activity);
|
|
@@ -41,6 +41,7 @@ const createOnNewAdapterActivityHandler = (chatId, userId) => {
|
|
|
41
41
|
});
|
|
42
42
|
};
|
|
43
43
|
const systemMessageStrategy = activity => {
|
|
44
|
+
var _TelemetryManager$Int3;
|
|
44
45
|
const payload = (0, _util.buildMessagePayload)(activity, userId);
|
|
45
46
|
payload.messageType = _Constants2.Constants.systemMessageTag;
|
|
46
47
|
if ((0, _util.isHistoryMessage)(activity, startTime)) {
|
|
@@ -48,6 +49,11 @@ const createOnNewAdapterActivityHandler = (chatId, userId) => {
|
|
|
48
49
|
historyMessageStrategy((0, _util.polyfillMessagePayloadForEvent)(activity, payload, (_TelemetryManager$Int2 = _TelemetryManager.TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int2 === void 0 ? void 0 : _TelemetryManager$Int2.conversationId));
|
|
49
50
|
return;
|
|
50
51
|
}
|
|
52
|
+
const newMessageReceivedEvent = {
|
|
53
|
+
eventName: _TelemetryConstants.BroadcastEvent.NewMessageReceived,
|
|
54
|
+
payload: (0, _util.polyfillMessagePayloadForEvent)(activity, payload, (_TelemetryManager$Int3 = _TelemetryManager.TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int3 === void 0 ? void 0 : _TelemetryManager$Int3.conversationId)
|
|
55
|
+
};
|
|
56
|
+
_omnichannelChatComponents.BroadcastService.postMessage(newMessageReceivedEvent);
|
|
51
57
|
_TelemetryHelper.TelemetryHelper.logActionEventToAllTelemetry(_TelemetryConstants.LogLevel.INFO, {
|
|
52
58
|
Event: _TelemetryConstants.TelemetryEvent.SystemMessageReceived,
|
|
53
59
|
Description: "System message received"
|
|
@@ -83,20 +89,20 @@ const createOnNewAdapterActivityHandler = (chatId, userId) => {
|
|
|
83
89
|
return true;
|
|
84
90
|
};
|
|
85
91
|
const receivedMessageStrategy = activity => {
|
|
86
|
-
var _TelemetryManager$
|
|
92
|
+
var _TelemetryManager$Int5;
|
|
87
93
|
if (!isValidMessage(activity)) return;
|
|
88
94
|
const isHistoryMessageReceived = (0, _util.isHistoryMessage)(activity, startTime);
|
|
89
95
|
const payload = (0, _util.buildMessagePayload)(activity, userId);
|
|
90
96
|
payload.messageType = _Constants2.Constants.userMessageTag;
|
|
91
97
|
if (isHistoryMessageReceived) {
|
|
92
|
-
var _TelemetryManager$
|
|
93
|
-
historyMessageStrategy((0, _util.polyfillMessagePayloadForEvent)(activity, payload, (_TelemetryManager$
|
|
98
|
+
var _TelemetryManager$Int4;
|
|
99
|
+
historyMessageStrategy((0, _util.polyfillMessagePayloadForEvent)(activity, payload, (_TelemetryManager$Int4 = _TelemetryManager.TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int4 === void 0 ? void 0 : _TelemetryManager$Int4.conversationId));
|
|
94
100
|
return;
|
|
95
101
|
}
|
|
96
102
|
firstResponseLatencyTracker.stopClock(payload);
|
|
97
103
|
const newMessageReceivedEvent = {
|
|
98
104
|
eventName: _TelemetryConstants.BroadcastEvent.NewMessageReceived,
|
|
99
|
-
payload: (0, _util.polyfillMessagePayloadForEvent)(activity, payload, (_TelemetryManager$
|
|
105
|
+
payload: (0, _util.polyfillMessagePayloadForEvent)(activity, payload, (_TelemetryManager$Int5 = _TelemetryManager.TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int5 === void 0 ? void 0 : _TelemetryManager$Int5.conversationId)
|
|
100
106
|
};
|
|
101
107
|
_omnichannelChatComponents.BroadcastService.postMessage(newMessageReceivedEvent);
|
|
102
108
|
_TelemetryHelper.TelemetryHelper.logActionEventToAllTelemetry(_TelemetryConstants.LogLevel.INFO, {
|
|
@@ -16,12 +16,16 @@ _defineProperty(Constants, "channelMessageTag", "channel");
|
|
|
16
16
|
_defineProperty(Constants, "historyMessageTag", "history");
|
|
17
17
|
_defineProperty(Constants, "agentEndConversationMessageTag", "agentendconversation");
|
|
18
18
|
_defineProperty(Constants, "supervisorForceCloseMessageTag", "supervisorforceclosedconversation");
|
|
19
|
+
_defineProperty(Constants, "endConversationalSurveyMessageTag", "endconversationalsurvey");
|
|
20
|
+
_defineProperty(Constants, "startConversationalSurveyMessageTag", "startconversationalsurvey");
|
|
21
|
+
_defineProperty(Constants, "c2ConversationalSurveyMessageTag", "c2conversationalsurvey");
|
|
19
22
|
_defineProperty(Constants, "receivedMessageClassName", "ms_lcw_webchat_received_message");
|
|
20
23
|
_defineProperty(Constants, "sentMessageClassName", "ms_lcw_webchat_sent_message");
|
|
21
24
|
_defineProperty(Constants, "webchatChannelId", "webchat");
|
|
22
25
|
_defineProperty(Constants, "markdown", "markdown");
|
|
23
26
|
_defineProperty(Constants, "actionType", "actionType");
|
|
24
27
|
_defineProperty(Constants, "markDownSystemMessageClass", "webchat__basic-transcript__activity-markdown-body");
|
|
28
|
+
_defineProperty(Constants, "MARKDOWN_LIST_INDENTATION", " ");
|
|
25
29
|
_defineProperty(Constants, "String", "string");
|
|
26
30
|
_defineProperty(Constants, "ChatMessagesJson", "chatMessagesJson");
|
|
27
31
|
_defineProperty(Constants, "truePascal", "True");
|
|
@@ -105,8 +109,7 @@ _defineProperty(Constants, "TargetRelationshipAttributes", "noopener noreferrer"
|
|
|
105
109
|
// Markdown icons
|
|
106
110
|
_defineProperty(Constants, "OpenLinkIconCssClass", "webchat__render-markdown__external-link-icon");
|
|
107
111
|
// internet connection test
|
|
108
|
-
_defineProperty(Constants, "
|
|
109
|
-
_defineProperty(Constants, "internetConnectionTestUrlText", "Omnichannel Connect Test");
|
|
112
|
+
_defineProperty(Constants, "internetConnectionTestPath", "/livechatwidget/version.txt");
|
|
110
113
|
_defineProperty(Constants, "ChatWidgetStateChangedPrefix", "ChatWidgetStateChanged");
|
|
111
114
|
_defineProperty(Constants, "PostChatLoadingDurationInMs", 2000);
|
|
112
115
|
_defineProperty(Constants, "BrowserUnloadConfirmationMessage", "Do you want to leave chat?");
|
|
@@ -122,6 +125,12 @@ _defineProperty(Constants, "InitContextParamsResponse", "initContextParamsRespon
|
|
|
122
125
|
_defineProperty(Constants, "OCOriginalMessageId", "OriginalMessageId");
|
|
123
126
|
_defineProperty(Constants, "WebchatSequenceIdAttribute", "webchat:sequence-id");
|
|
124
127
|
_defineProperty(Constants, "MessageSequenceIdOverride", "MessageSequenceIdOverride");
|
|
128
|
+
_defineProperty(Constants, "sendCustomEvent", "sendCustomEvent");
|
|
129
|
+
_defineProperty(Constants, "onCustomEvent", "onCustomEvent");
|
|
130
|
+
_defineProperty(Constants, "customEventName", "customEventName");
|
|
131
|
+
_defineProperty(Constants, "customEventValue", "customEventValue");
|
|
132
|
+
_defineProperty(Constants, "Hidden", "Hidden");
|
|
133
|
+
_defineProperty(Constants, "EndConversationDueToOverflow", "endconversationduetooverflow");
|
|
125
134
|
export const Regex = (_class = /*#__PURE__*/_createClass(function Regex() {
|
|
126
135
|
_classCallCheck(this, Regex);
|
|
127
136
|
}), _defineProperty(_class, "EmailRegex", "^(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\")@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?)*|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\])$"), _class);
|
|
@@ -220,6 +229,10 @@ export let ConversationMode;
|
|
|
220
229
|
ConversationMode["Regular"] = "192350000";
|
|
221
230
|
ConversationMode["Persistent"] = "192350001";
|
|
222
231
|
})(ConversationMode || (ConversationMode = {}));
|
|
232
|
+
export let SurveyProvider;
|
|
233
|
+
(function (SurveyProvider) {
|
|
234
|
+
SurveyProvider["MicrosoftCopilotStudio"] = "600990001";
|
|
235
|
+
})(SurveyProvider || (SurveyProvider = {}));
|
|
223
236
|
export let LiveWorkItemState;
|
|
224
237
|
(function (LiveWorkItemState) {
|
|
225
238
|
LiveWorkItemState["Active"] = "Active";
|
|
@@ -184,6 +184,7 @@ export let TelemetryEvent;
|
|
|
184
184
|
TelemetryEvent["BotAuthActivityUndefinedSignInId"] = "BotAuthActivityUndefinedSignInId";
|
|
185
185
|
TelemetryEvent["ThirdPartyCookiesBlocked"] = "ThirdPartyCookiesBlocked";
|
|
186
186
|
TelemetryEvent["ParticipantsRemovedEvent"] = "ParticipantsRemovedEvent";
|
|
187
|
+
TelemetryEvent["QueueOverflowEvent"] = "QueueOverflowEvent";
|
|
187
188
|
TelemetryEvent["ProcessingHTMLTextMiddlewareFailed"] = "ProcessingHTMLTextMiddlewareFailed";
|
|
188
189
|
TelemetryEvent["ProcessingSanitizationMiddlewareFailed"] = "ProcessingSanitizationMiddlewareFailed";
|
|
189
190
|
TelemetryEvent["FormatTagsMiddlewareJSONStringifyFailed"] = "FormatTagsMiddlewareJSONStringifyFailed";
|
|
@@ -222,6 +223,7 @@ export let TelemetryEvent;
|
|
|
222
223
|
TelemetryEvent["SystemMessageReceived"] = "SystemMessageReceived";
|
|
223
224
|
TelemetryEvent["RehydrateMessageReceived"] = "RehydrateMessageReceived";
|
|
224
225
|
TelemetryEvent["CustomContextReceived"] = "CustomContextReceived";
|
|
226
|
+
TelemetryEvent["CustomEventAction"] = "CustomEventAction";
|
|
225
227
|
TelemetryEvent["NetworkDisconnected"] = "NetworkDisconnected";
|
|
226
228
|
TelemetryEvent["NetworkReconnected"] = "NetworkReconnected";
|
|
227
229
|
TelemetryEvent["LinkModePostChatWorkflowStarted"] = "LinkModePostChatWorkflowStarted";
|
package/lib/esm/common/utils.js
CHANGED
|
@@ -453,4 +453,25 @@ export function getDeviceType() {
|
|
|
453
453
|
} else {
|
|
454
454
|
return "standard";
|
|
455
455
|
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
//Bots expect a payload containing:
|
|
459
|
+
//1. customEventName: this should be string describe the event name
|
|
460
|
+
//2. customEventValue: given the value is from customer with unknown type, it is required to stringify the payload later
|
|
461
|
+
export const isValidCustomEvent = payload => {
|
|
462
|
+
if (Constants.customEventName in payload && payload.customEventName && typeof payload.customEventName === Constants.String && Constants.customEventValue in payload && payload.customEventValue) return true;
|
|
463
|
+
return false;
|
|
464
|
+
};
|
|
465
|
+
export const getCustomEventValue = customEventPayload => {
|
|
466
|
+
let returnVal = "";
|
|
467
|
+
try {
|
|
468
|
+
returnVal = typeof customEventPayload.customEventValue === Constants.String ? customEventPayload.customEventValue : JSON.stringify(customEventPayload.customEventValue);
|
|
469
|
+
} catch (error) {
|
|
470
|
+
console.error(error);
|
|
471
|
+
}
|
|
472
|
+
return returnVal;
|
|
473
|
+
};
|
|
474
|
+
export function isEndConversationDueToOverflowActivity(activity) {
|
|
475
|
+
var _activity$channelData, _activity$channelData2;
|
|
476
|
+
return (activity === null || activity === void 0 ? void 0 : (_activity$channelData = activity.channelData) === null || _activity$channelData === void 0 ? void 0 : _activity$channelData.tags) && Array.isArray(activity === null || activity === void 0 ? void 0 : (_activity$channelData2 = activity.channelData) === null || _activity$channelData2 === void 0 ? void 0 : _activity$channelData2.tags) && activity.channelData.tags.includes(Constants.EndConversationDueToOverflow);
|
|
456
477
|
}
|
|
@@ -65,7 +65,6 @@ export const ChatButtonStateful = props => {
|
|
|
65
65
|
};
|
|
66
66
|
const outOfOfficeStyleProps = Object.assign({}, defaultOutOfOfficeChatButtonStyleProps, outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.styleProps);
|
|
67
67
|
const controlProps = {
|
|
68
|
-
...(buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.controlProps),
|
|
69
68
|
id: "oc-lcw-chat-button",
|
|
70
69
|
dir: state.domainStates.globalDir,
|
|
71
70
|
titleText: "Let's Chat!",
|
|
@@ -74,7 +73,8 @@ export const ChatButtonStateful = props => {
|
|
|
74
73
|
unreadMessageCount: state.appStates.unreadMessageCount ? state.appStates.unreadMessageCount > Constants.maximumUnreadMessageCount ? (_props$buttonProps = props.buttonProps) === null || _props$buttonProps === void 0 ? void 0 : (_props$buttonProps$co = _props$buttonProps.controlProps) === null || _props$buttonProps$co === void 0 ? void 0 : _props$buttonProps$co.largeUnreadMessageString : state.appStates.unreadMessageCount.toString() : "0",
|
|
75
74
|
unreadMessageString: (_props$buttonProps2 = props.buttonProps) === null || _props$buttonProps2 === void 0 ? void 0 : (_props$buttonProps2$c = _props$buttonProps2.controlProps) === null || _props$buttonProps2$c === void 0 ? void 0 : _props$buttonProps2$c.unreadMessageString,
|
|
76
75
|
// Regular chat button onClick - this will always take precedence
|
|
77
|
-
onClick: () => ref.current()
|
|
76
|
+
onClick: () => ref.current(),
|
|
77
|
+
...(buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.controlProps)
|
|
78
78
|
};
|
|
79
79
|
const outOfOfficeControlProps = {
|
|
80
80
|
// Only take specific properties from outOfOfficeButtonProps, never onClick
|
|
@@ -83,7 +83,6 @@ export const ChatButtonStateful = props => {
|
|
|
83
83
|
titleText: (outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : (_outOfOfficeButtonPro = outOfOfficeButtonProps.controlProps) === null || _outOfOfficeButtonPro === void 0 ? void 0 : _outOfOfficeButtonPro.titleText) || "We're Offline",
|
|
84
84
|
subtitleText: (outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : (_outOfOfficeButtonPro2 = outOfOfficeButtonProps.controlProps) === null || _outOfOfficeButtonPro2 === void 0 ? void 0 : _outOfOfficeButtonPro2.subtitleText) || "No agents available",
|
|
85
85
|
unreadMessageString: (_props$buttonProps3 = props.buttonProps) === null || _props$buttonProps3 === void 0 ? void 0 : (_props$buttonProps3$c = _props$buttonProps3.controlProps) === null || _props$buttonProps3$c === void 0 ? void 0 : _props$buttonProps3$c.unreadMessageString,
|
|
86
|
-
...(outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.controlProps),
|
|
87
86
|
// Out-of-office specific onClick - this will ALWAYS take precedence
|
|
88
87
|
onClick: () => {
|
|
89
88
|
if (state.appStates.isMinimized) {
|
|
@@ -96,7 +95,8 @@ export const ChatButtonStateful = props => {
|
|
|
96
95
|
type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
|
|
97
96
|
payload: ConversationState.OutOfOffice
|
|
98
97
|
});
|
|
99
|
-
}
|
|
98
|
+
},
|
|
99
|
+
...(outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.controlProps)
|
|
100
100
|
};
|
|
101
101
|
useEffect(() => {
|
|
102
102
|
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
@@ -25,8 +25,11 @@ const DraggableChatWidget = props => {
|
|
|
25
25
|
};
|
|
26
26
|
const calculateOffsetsWithinViewport = useCallback((id, offset, delta) => {
|
|
27
27
|
const draggableElement = document.getElementById(id);
|
|
28
|
+
if (isNullOrUndefined(draggableElement)) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
28
31
|
const positionRelativeToViewport = draggableElement.getBoundingClientRect();
|
|
29
|
-
if (isNullOrUndefined(
|
|
32
|
+
if (isNullOrUndefined(positionRelativeToViewport) || isNullOrUndefined(offset.offsetLeft) || isNullOrUndefined(offset.offsetTop)) {
|
|
30
33
|
return;
|
|
31
34
|
}
|
|
32
35
|
let offsetLeft = offset.offsetLeft;
|
|
@@ -68,6 +71,9 @@ const DraggableChatWidget = props => {
|
|
|
68
71
|
}
|
|
69
72
|
const cacheInitialPosition = () => {
|
|
70
73
|
const draggableElement = document.getElementById(props.elementId);
|
|
74
|
+
if (isNullOrUndefined(draggableElement)) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
71
77
|
const offsetLeft = draggableElement.offsetLeft;
|
|
72
78
|
const offsetTop = draggableElement.offsetTop;
|
|
73
79
|
setInitialPosition({
|
|
@@ -77,6 +83,9 @@ const DraggableChatWidget = props => {
|
|
|
77
83
|
};
|
|
78
84
|
const calculateOffsets = () => {
|
|
79
85
|
const draggableElement = document.getElementById(props.elementId);
|
|
86
|
+
if (isNullOrUndefined(draggableElement)) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
80
89
|
const offsetLeft = draggableElement.offsetLeft;
|
|
81
90
|
const offsetTop = draggableElement.offsetTop;
|
|
82
91
|
|
|
@@ -111,6 +120,9 @@ const DraggableChatWidget = props => {
|
|
|
111
120
|
resetPosition(initialPosition);
|
|
112
121
|
} else if (state.appStates.isMinimized) {
|
|
113
122
|
const draggableElement = document.getElementById(props.elementId);
|
|
123
|
+
if (isNullOrUndefined(draggableElement)) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
114
126
|
const offsetLeft = draggableElement.offsetLeft;
|
|
115
127
|
const offsetTop = draggableElement.offsetTop;
|
|
116
128
|
if (!cachedPosition) {
|
|
@@ -135,6 +147,9 @@ const DraggableChatWidget = props => {
|
|
|
135
147
|
|
|
136
148
|
// Update position via DOM manipulation to prevent <Stack/> continuously rendering on style change causing high CPU spike
|
|
137
149
|
const draggableElement = document.getElementById(props.elementId);
|
|
150
|
+
if (isNullOrUndefined(draggableElement)) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
138
153
|
repositionElement(draggableElement, offsetLeft, offsetTop);
|
|
139
154
|
setPosition({
|
|
140
155
|
offsetLeft,
|
|
@@ -7,34 +7,47 @@ import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
|
|
|
7
7
|
import { defaultMiddlewareLocalizedTexts } from "../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts";
|
|
8
8
|
import { executeReducer } from "../../../contexts/createReducer";
|
|
9
9
|
import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
|
|
10
|
-
const
|
|
10
|
+
const getRegionBasedInternetTestUrl = widgetSnippet => {
|
|
11
|
+
var _widgetSnippet$match;
|
|
12
|
+
if (!widgetSnippet) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const widgetSnippetSourceRegex = new RegExp("src=\"(https:\\/\\/[\\w-.]+)[\\w-.\\/]+\"");
|
|
16
|
+
const baseCdnUrl = (_widgetSnippet$match = widgetSnippet.match(widgetSnippetSourceRegex)) === null || _widgetSnippet$match === void 0 ? void 0 : _widgetSnippet$match[1];
|
|
17
|
+
return baseCdnUrl ? `${baseCdnUrl}${Constants.internetConnectionTestPath}` : null;
|
|
18
|
+
};
|
|
19
|
+
const isInternetConnected = async testUrl => {
|
|
11
20
|
try {
|
|
12
|
-
const response = await fetch(
|
|
13
|
-
|
|
14
|
-
|
|
21
|
+
const response = await fetch(testUrl, {
|
|
22
|
+
method: "GET",
|
|
23
|
+
cache: "no-cache"
|
|
24
|
+
});
|
|
25
|
+
return response.ok;
|
|
15
26
|
} catch {
|
|
16
27
|
return false;
|
|
17
28
|
}
|
|
18
29
|
};
|
|
19
30
|
export const createInternetConnectionChangeHandler = async state => {
|
|
20
31
|
const handler = async () => {
|
|
21
|
-
|
|
32
|
+
var _inMemoryState$domain, _inMemoryState$domain2;
|
|
22
33
|
const inMemoryState = executeReducer(state, {
|
|
23
34
|
type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
|
|
24
35
|
payload: null
|
|
25
36
|
});
|
|
37
|
+
const testUrl = getRegionBasedInternetTestUrl((_inMemoryState$domain = inMemoryState.domainStates.liveChatConfig) === null || _inMemoryState$domain === void 0 ? void 0 : (_inMemoryState$domain2 = _inMemoryState$domain.LiveWSAndLiveChatEngJoin) === null || _inMemoryState$domain2 === void 0 ? void 0 : _inMemoryState$domain2.msdyn_widgetsnippet);
|
|
38
|
+
const connected = testUrl ? await isInternetConnected(testUrl) : false;
|
|
26
39
|
if (!connected) {
|
|
27
|
-
var _inMemoryState$
|
|
40
|
+
var _inMemoryState$domain3, _inMemoryState$domain4;
|
|
28
41
|
TelemetryHelper.logActionEvent(LogLevel.WARN, {
|
|
29
42
|
Event: TelemetryEvent.NetworkDisconnected
|
|
30
43
|
});
|
|
31
|
-
NotificationHandler.notifyError(NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$
|
|
44
|
+
NotificationHandler.notifyError(NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain3 = inMemoryState.domainStates) === null || _inMemoryState$domain3 === void 0 ? void 0 : (_inMemoryState$domain4 = _inMemoryState$domain3.middlewareLocalizedTexts) === null || _inMemoryState$domain4 === void 0 ? void 0 : _inMemoryState$domain4.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION);
|
|
32
45
|
} else {
|
|
33
|
-
var _inMemoryState$
|
|
46
|
+
var _inMemoryState$domain5, _inMemoryState$domain6;
|
|
34
47
|
TelemetryHelper.logActionEvent(LogLevel.WARN, {
|
|
35
48
|
Event: TelemetryEvent.NetworkReconnected
|
|
36
49
|
});
|
|
37
|
-
NotificationHandler.notifySuccess(NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$
|
|
50
|
+
NotificationHandler.notifySuccess(NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain5 = inMemoryState.domainStates) === null || _inMemoryState$domain5 === void 0 ? void 0 : (_inMemoryState$domain6 = _inMemoryState$domain5.middlewareLocalizedTexts) === null || _inMemoryState$domain6 === void 0 ? void 0 : _inMemoryState$domain6.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE);
|
|
38
51
|
BroadcastService.postMessage({
|
|
39
52
|
eventName: BroadcastEvent.NetworkReconnected
|
|
40
53
|
});
|
|
@@ -28,12 +28,65 @@ export const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineM
|
|
|
28
28
|
// Rule to process html blocks and paragraphs
|
|
29
29
|
"html_inline",
|
|
30
30
|
// Rule to process html tags
|
|
31
|
-
"newline"
|
|
31
|
+
"newline",
|
|
32
|
+
// Rule to proceess '\n'
|
|
33
|
+
"list" // Enable list parsing rule
|
|
32
34
|
]);
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
markdown.disable(["strikethrough"]);
|
|
36
38
|
|
|
39
|
+
// Custom plugin to fix numbered list continuity
|
|
40
|
+
markdown.use(function (md) {
|
|
41
|
+
const originalRender = md.render.bind(md);
|
|
42
|
+
const originalRenderInline = md.renderInline.bind(md);
|
|
43
|
+
function preprocessText(text) {
|
|
44
|
+
// Handle numbered lists that come with double line breaks (knowledge article format)
|
|
45
|
+
// This ensures proper continuous numbering instead of separate lists
|
|
46
|
+
|
|
47
|
+
let result = text;
|
|
48
|
+
|
|
49
|
+
// Only process if the text contains the double line break pattern
|
|
50
|
+
// But exclude simple numbered lists (where content after \n\n starts with another number)
|
|
51
|
+
if (!/\d+\.\s+.*?\n\n(?!\d+\.\s)[\s\S]*?(?:\n\n\d+\.|\s*$)/.test(text)) {
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Convert "1. Item\n\nContent\n\n2. Item" to proper markdown list format
|
|
56
|
+
// Use improved pattern with negative lookahead to exclude cases where content starts with numbered list
|
|
57
|
+
const listPattern = /(\d+\.\s+[^\n]+)(\n\n(?!\d+\.\s)[\s\S]*?)(?=\n\n\d+\.|\s*$)/g;
|
|
58
|
+
if (listPattern.test(result)) {
|
|
59
|
+
// Reset regex state for actual replacement
|
|
60
|
+
listPattern.lastIndex = 0;
|
|
61
|
+
result = result.replace(listPattern, (match, listItem, content) => {
|
|
62
|
+
if (!content) {
|
|
63
|
+
return match;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Format content with proper indentation
|
|
67
|
+
const cleanContent = content.substring(2); // Remove leading \n\n
|
|
68
|
+
const lines = cleanContent.split("\n");
|
|
69
|
+
const indentedContent = lines.map(line => line.trim() ? `${Constants.MARKDOWN_LIST_INDENTATION}${line}` : "").join("\n");
|
|
70
|
+
const lineBreak = disableNewLineMarkdownSupport ? "\n" : "\n\n";
|
|
71
|
+
return `${listItem}${lineBreak}${indentedContent}`;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
78
|
+
md.render = function (text, env) {
|
|
79
|
+
const processedText = preprocessText(text);
|
|
80
|
+
return originalRender(processedText, env);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
84
|
+
md.renderInline = function (text, env) {
|
|
85
|
+
const processedText = preprocessText(text);
|
|
86
|
+
return originalRenderInline(processedText, env);
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
|
|
37
90
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
91
|
markdown.use(MarkdownItForInline, "url_new_win", "link_open", function (tokens, idx, env) {
|
|
39
92
|
const targetAttrIndex = tokens[idx].attrIndex(Constants.Target);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Constants } from "../../../common/Constants";
|
|
2
|
+
import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
|
|
3
|
+
import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
|
|
4
|
+
import { getCustomEventValue, isValidCustomEvent } from "../../../common/utils";
|
|
5
|
+
export const customEventCallback = facadeChatSDK => event => {
|
|
6
|
+
if (!(Constants.payload in event)) return;
|
|
7
|
+
if (isValidCustomEvent(event.payload)) {
|
|
8
|
+
const customEventPayload = event.payload;
|
|
9
|
+
try {
|
|
10
|
+
const customEventValueStr = getCustomEventValue(customEventPayload);
|
|
11
|
+
const customEventName = customEventPayload.customEventName;
|
|
12
|
+
const messageMeta = {
|
|
13
|
+
customEvent: Constants.true,
|
|
14
|
+
customEventName: customEventName,
|
|
15
|
+
customEventValue: customEventValueStr
|
|
16
|
+
};
|
|
17
|
+
const messagePayload = {
|
|
18
|
+
content: "",
|
|
19
|
+
tags: [Constants.Hidden],
|
|
20
|
+
metadata: messageMeta,
|
|
21
|
+
timestamp: new Date()
|
|
22
|
+
};
|
|
23
|
+
facadeChatSDK.sendMessage(messagePayload);
|
|
24
|
+
TelemetryHelper.logActionEventToAllTelemetry(LogLevel.DEBUG, {
|
|
25
|
+
Event: TelemetryEvent.CustomEventAction,
|
|
26
|
+
Description: "Sent customEvent.",
|
|
27
|
+
CustomProperties: {
|
|
28
|
+
customEventName,
|
|
29
|
+
lengthCustomEventValue: customEventValueStr.length
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
} catch (error) {
|
|
33
|
+
TelemetryHelper.logActionEventToAllTelemetry(LogLevel.ERROR, {
|
|
34
|
+
Event: TelemetryEvent.CustomEventAction,
|
|
35
|
+
Description: "Failed to process CustomEvent.",
|
|
36
|
+
ExceptionDetails: {
|
|
37
|
+
error
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
export const subscribeToSendCustomEvent = (broadcastService, facadeChatSDK, customEventCallback) => {
|
|
44
|
+
broadcastService.getMessageByEventName(Constants.sendCustomEvent).subscribe(customEventCallback(facadeChatSDK));
|
|
45
|
+
};
|
|
@@ -16,7 +16,7 @@ import { uuidv4 } from "@microsoft/omnichannel-chat-sdk";
|
|
|
16
16
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
17
|
const prepareEndChat = async (props, facadeChatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter) => {
|
|
18
18
|
try {
|
|
19
|
-
var _conversationDetails$, _state$domainStates, _state$
|
|
19
|
+
var _conversationDetails$, _state$domainStates, _state$appStates5;
|
|
20
20
|
const {
|
|
21
21
|
chatConfig
|
|
22
22
|
} = props;
|
|
@@ -27,7 +27,7 @@ const prepareEndChat = async (props, facadeChatSDK, state, dispatch, setAdapter,
|
|
|
27
27
|
|
|
28
28
|
// Use Case: When post chat is not configured
|
|
29
29
|
if ((conversationDetails === null || conversationDetails === void 0 ? void 0 : (_conversationDetails$ = conversationDetails.canRenderPostChat) === null || _conversationDetails$ === void 0 ? void 0 : _conversationDetails$.toLowerCase()) === Constants.false) {
|
|
30
|
-
var _state$appStates;
|
|
30
|
+
var _state$appStates, _state$appStates2, _state$appStates3;
|
|
31
31
|
// If ended by customer, just close chat
|
|
32
32
|
if ((state === null || state === void 0 ? void 0 : (_state$appStates = state.appStates) === null || _state$appStates === void 0 ? void 0 : _state$appStates.conversationEndedBy) === ConversationEndEntity.Customer) {
|
|
33
33
|
TelemetryHelper.logSDKEvent(LogLevel.INFO, {
|
|
@@ -35,9 +35,17 @@ const prepareEndChat = async (props, facadeChatSDK, state, dispatch, setAdapter,
|
|
|
35
35
|
Description: PrepareEndChatDescriptionConstants.ConversationEndedByCustomerWithoutPostChat
|
|
36
36
|
});
|
|
37
37
|
await endChat(props, facadeChatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, false, true);
|
|
38
|
+
return;
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
// Use Case: If ended by Agent, stay chat in InActive state
|
|
42
|
+
let isConversationalSurveyEnabled = state.appStates.isConversationalSurveyEnabled;
|
|
43
|
+
if (isConversationalSurveyEnabled && ((state === null || state === void 0 ? void 0 : (_state$appStates2 = state.appStates) === null || _state$appStates2 === void 0 ? void 0 : _state$appStates2.conversationEndedBy) === ConversationEndEntity.Agent || (state === null || state === void 0 ? void 0 : (_state$appStates3 = state.appStates) === null || _state$appStates3 === void 0 ? void 0 : _state$appStates3.conversationEndedBy) === ConversationEndEntity.Bot)) {
|
|
44
|
+
dispatch({
|
|
45
|
+
type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
|
|
46
|
+
payload: ConversationState.InActive
|
|
47
|
+
});
|
|
48
|
+
}
|
|
41
49
|
return;
|
|
42
50
|
}
|
|
43
51
|
|
|
@@ -53,7 +61,7 @@ const prepareEndChat = async (props, facadeChatSDK, state, dispatch, setAdapter,
|
|
|
53
61
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
54
62
|
const postchatContext = (await getPostChatContext(facadeChatSDK, state, dispatch)) ?? (state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : _state$domainStates.postChatContext);
|
|
55
63
|
if (postchatContext === undefined) {
|
|
56
|
-
var _state$
|
|
64
|
+
var _state$appStates4;
|
|
57
65
|
BroadcastService.postMessage({
|
|
58
66
|
eventName: BroadcastEvent.OnWidgetError,
|
|
59
67
|
payload: {
|
|
@@ -62,7 +70,7 @@ const prepareEndChat = async (props, facadeChatSDK, state, dispatch, setAdapter,
|
|
|
62
70
|
});
|
|
63
71
|
|
|
64
72
|
// For Customer intiated conversations, just close chat widget
|
|
65
|
-
if ((state === null || state === void 0 ? void 0 : (_state$
|
|
73
|
+
if ((state === null || state === void 0 ? void 0 : (_state$appStates4 = state.appStates) === null || _state$appStates4 === void 0 ? void 0 : _state$appStates4.conversationEndedBy) === ConversationEndEntity.Customer) {
|
|
66
74
|
TelemetryHelper.logSDKEvent(LogLevel.INFO, {
|
|
67
75
|
Event: TelemetryEvent.PrepareEndChat,
|
|
68
76
|
Description: PrepareEndChatDescriptionConstants.ConversationEndedByCustomerWithInvalidPostChat
|
|
@@ -80,11 +88,11 @@ const prepareEndChat = async (props, facadeChatSDK, state, dispatch, setAdapter,
|
|
|
80
88
|
}
|
|
81
89
|
|
|
82
90
|
// Log PrepareEndChat if conversation ended by customer (bot and agent cases are handled in LiveChatWidgetStateful.tsx)
|
|
83
|
-
if (state !== null && state !== void 0 && (_state$
|
|
84
|
-
var _state$
|
|
91
|
+
if (state !== null && state !== void 0 && (_state$appStates5 = state.appStates) !== null && _state$appStates5 !== void 0 && _state$appStates5.conversationEndedBy) {
|
|
92
|
+
var _state$appStates6;
|
|
85
93
|
TelemetryHelper.logSDKEvent(LogLevel.INFO, {
|
|
86
94
|
Event: TelemetryEvent.PrepareEndChat,
|
|
87
|
-
Description: `${PrepareEndChatDescriptionConstants.ConversationEndedByCustomerWithInvalidPostChat} ${state === null || state === void 0 ? void 0 : (_state$
|
|
95
|
+
Description: `${PrepareEndChatDescriptionConstants.ConversationEndedByCustomerWithInvalidPostChat} ${state === null || state === void 0 ? void 0 : (_state$appStates6 = state.appStates) === null || _state$appStates6 === void 0 ? void 0 : _state$appStates6.conversationEndedBy}.`
|
|
88
96
|
});
|
|
89
97
|
}
|
|
90
98
|
const persistentEnabled = isPersistentEnabled(chatConfig);
|
|
@@ -256,6 +264,10 @@ export const closeChatStateCleanUp = dispatch => {
|
|
|
256
264
|
payload: undefined
|
|
257
265
|
});
|
|
258
266
|
// dispatch({ type: LiveChatWidgetActionType.SET_CONVERSATION_STATE, payload: ConversationState.Closed });
|
|
267
|
+
dispatch({
|
|
268
|
+
type: LiveChatWidgetActionType.SET_CONVERSATIONAL_SURVEY_DISPLAY,
|
|
269
|
+
payload: false
|
|
270
|
+
});
|
|
259
271
|
dispatch({
|
|
260
272
|
type: LiveChatWidgetActionType.SET_RECONNECT_ID,
|
|
261
273
|
payload: undefined
|
|
@@ -32,6 +32,12 @@ import htmlTextMiddleware from "../../webchatcontainerstateful/webchatcontroller
|
|
|
32
32
|
import preProcessingMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware";
|
|
33
33
|
import sanitizationMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware";
|
|
34
34
|
import { Constants } from "../../../common/Constants";
|
|
35
|
+
import createCallActionMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware";
|
|
36
|
+
import createCustomEventMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware";
|
|
37
|
+
import { ConversationState } from "../../../contexts/common/ConversationState";
|
|
38
|
+
import { executeReducer } from "../../../contexts/createReducer";
|
|
39
|
+
import { createQueueOverflowMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware";
|
|
40
|
+
import { BroadcastService } from "@microsoft/omnichannel-chat-components";
|
|
35
41
|
|
|
36
42
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
43
|
export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endChat) => {
|
|
@@ -53,6 +59,20 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
|
|
|
53
59
|
let webChatStore = WebChatStoreLoader.store;
|
|
54
60
|
if (!webChatStore) {
|
|
55
61
|
var _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _props$webChatContain7;
|
|
62
|
+
const addConversationalSurveyTagsCallback = action => {
|
|
63
|
+
var _inMemoryState$appSta;
|
|
64
|
+
const inMemoryState = executeReducer(state, {
|
|
65
|
+
type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
|
|
66
|
+
payload: null
|
|
67
|
+
});
|
|
68
|
+
const isConversationalSurvey = (_inMemoryState$appSta = inMemoryState.appStates) === null || _inMemoryState$appSta === void 0 ? void 0 : _inMemoryState$appSta.isConversationalSurvey;
|
|
69
|
+
if (isConversationalSurvey) {
|
|
70
|
+
if (!action.payload.activity.channelData.tags.includes(Constants.c2ConversationalSurveyMessageTag)) {
|
|
71
|
+
action.payload.activity.channelData.tags.push(Constants.c2ConversationalSurveyMessageTag);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return action;
|
|
75
|
+
};
|
|
56
76
|
const conversationEndCallback = async () => {
|
|
57
77
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
58
78
|
const conversationDetails = await getConversationDetailsCall(facadeChatSDK);
|
|
@@ -82,9 +102,21 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
|
|
|
82
102
|
});
|
|
83
103
|
}
|
|
84
104
|
};
|
|
105
|
+
const startConversationalSurveyCallback = async () => {
|
|
106
|
+
dispatch({
|
|
107
|
+
type: LiveChatWidgetActionType.SET_CONVERSATIONAL_SURVEY_DISPLAY,
|
|
108
|
+
payload: true
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
const endConversationalSurveyCallback = async () => {
|
|
112
|
+
dispatch({
|
|
113
|
+
type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
|
|
114
|
+
payload: ConversationState.InActive
|
|
115
|
+
});
|
|
116
|
+
};
|
|
85
117
|
webChatStore = createStore({},
|
|
86
118
|
//initial state
|
|
87
|
-
preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), channelDataMiddleware, createConversationEndMiddleware(conversationEndCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, createMessageSequenceIdOverrideMiddleware, gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware(honorsTargetInHTMLLinks), createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware,
|
|
119
|
+
preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), createCustomEventMiddleware(BroadcastService), createQueueOverflowMiddleware(state, dispatch), channelDataMiddleware(addConversationalSurveyTagsCallback), createConversationEndMiddleware(conversationEndCallback, startConversationalSurveyCallback, endConversationalSurveyCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, createMessageSequenceIdOverrideMiddleware, gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware(honorsTargetInHTMLLinks), createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware, createCallActionMiddleware(),
|
|
88
120
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
89
121
|
...(((_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.storeMiddlewares) ?? []));
|
|
90
122
|
WebChatStoreLoader.store = webChatStore;
|
|
@@ -6,6 +6,22 @@ export const isPostChatSurveyEnabled = async facadeChatSDK => {
|
|
|
6
6
|
const postChatEnabled = (_chatConfig$LiveWSAnd = chatConfig.LiveWSAndLiveChatEngJoin) === null || _chatConfig$LiveWSAnd === void 0 ? void 0 : _chatConfig$LiveWSAnd.msdyn_postconversationsurveyenable.toString().toLowerCase();
|
|
7
7
|
return postChatEnabled === "true";
|
|
8
8
|
};
|
|
9
|
+
export const getPostChatSurveyConfig = async facadeChatSDK => {
|
|
10
|
+
var _chatConfig$LiveWSAnd2, _chatConfig$LiveWSAnd3, _chatConfig$LiveWSAnd4, _chatConfig$LiveWSAnd5, _chatConfig$LiveWSAnd6, _chatConfig$LiveWSAnd7, _chatConfig$LiveWSAnd8, _chatConfig$LiveWSAnd9, _chatConfig$LiveWSAnd10;
|
|
11
|
+
const chatConfig = await facadeChatSDK.getLiveChatConfig();
|
|
12
|
+
const postChatEnabled = (_chatConfig$LiveWSAnd2 = chatConfig.LiveWSAndLiveChatEngJoin) === null || _chatConfig$LiveWSAnd2 === void 0 ? void 0 : _chatConfig$LiveWSAnd2.msdyn_postconversationsurveyenable.toString().toLowerCase();
|
|
13
|
+
const agentSurveyMode = (_chatConfig$LiveWSAnd3 = chatConfig.LiveWSAndLiveChatEngJoin) === null || _chatConfig$LiveWSAnd3 === void 0 ? void 0 : (_chatConfig$LiveWSAnd4 = _chatConfig$LiveWSAnd3.msdyn_postconversationsurveymode) === null || _chatConfig$LiveWSAnd4 === void 0 ? void 0 : _chatConfig$LiveWSAnd4.toString();
|
|
14
|
+
const botSurveyMode = (_chatConfig$LiveWSAnd5 = chatConfig.LiveWSAndLiveChatEngJoin) === null || _chatConfig$LiveWSAnd5 === void 0 ? void 0 : (_chatConfig$LiveWSAnd6 = _chatConfig$LiveWSAnd5.msdyn_postconversationsurveybotsurveymode) === null || _chatConfig$LiveWSAnd6 === void 0 ? void 0 : _chatConfig$LiveWSAnd6.toString();
|
|
15
|
+
const surveyProvider = (_chatConfig$LiveWSAnd7 = chatConfig.LiveWSAndLiveChatEngJoin) === null || _chatConfig$LiveWSAnd7 === void 0 ? void 0 : (_chatConfig$LiveWSAnd8 = _chatConfig$LiveWSAnd7.msdyn_surveyprovider) === null || _chatConfig$LiveWSAnd8 === void 0 ? void 0 : _chatConfig$LiveWSAnd8.toString();
|
|
16
|
+
const isConversationalSurveyEnabled = (_chatConfig$LiveWSAnd9 = chatConfig.LiveWSAndLiveChatEngJoin) === null || _chatConfig$LiveWSAnd9 === void 0 ? void 0 : (_chatConfig$LiveWSAnd10 = _chatConfig$LiveWSAnd9.msdyn_isConversationalPostChatSurveyEnabled) === null || _chatConfig$LiveWSAnd10 === void 0 ? void 0 : _chatConfig$LiveWSAnd10.toString().toLowerCase();
|
|
17
|
+
return {
|
|
18
|
+
postChatEnabled: postChatEnabled === "true",
|
|
19
|
+
agentSurveyMode: agentSurveyMode,
|
|
20
|
+
botSurveyMode: botSurveyMode,
|
|
21
|
+
surveyProvider: surveyProvider,
|
|
22
|
+
isConversationalSurveyEnabled: isConversationalSurveyEnabled === "true"
|
|
23
|
+
};
|
|
24
|
+
};
|
|
9
25
|
export const isPersistentChatEnabled = conversationMode => {
|
|
10
26
|
if (isNullOrUndefined(conversationMode)) {
|
|
11
27
|
return false;
|