@microsoft/omnichannel-chat-widget 1.4.0 → 1.4.1-main.2575376

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.
Files changed (30) hide show
  1. package/README.md +1 -1
  2. package/lib/cjs/common/utils.js +19 -2
  3. package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +8 -11
  4. package/lib/cjs/components/emailtranscriptpanestateful/EmailTranscriptPaneStateful.js +4 -1
  5. package/lib/cjs/components/livechatwidget/common/endChat.js +18 -15
  6. package/lib/cjs/components/livechatwidget/common/reconnectChatHelper.js +1 -1
  7. package/lib/cjs/components/livechatwidget/common/renderSurveyHelpers.js +11 -9
  8. package/lib/cjs/components/livechatwidget/common/startChat.js +29 -15
  9. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +46 -32
  10. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +22 -9
  11. package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +3 -1
  12. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios.js +1 -0
  13. package/lib/esm/common/utils.js +16 -0
  14. package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +8 -11
  15. package/lib/esm/components/emailtranscriptpanestateful/EmailTranscriptPaneStateful.js +5 -2
  16. package/lib/esm/components/livechatwidget/common/endChat.js +18 -18
  17. package/lib/esm/components/livechatwidget/common/reconnectChatHelper.js +1 -1
  18. package/lib/esm/components/livechatwidget/common/renderSurveyHelpers.js +11 -9
  19. package/lib/esm/components/livechatwidget/common/startChat.js +29 -15
  20. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +49 -35
  21. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +22 -9
  22. package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +3 -1
  23. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios.js +1 -0
  24. package/lib/types/common/utils.d.ts +9 -0
  25. package/lib/types/components/livechatwidget/common/endChat.d.ts +5 -2
  26. package/lib/types/components/livechatwidget/common/renderSurveyHelpers.d.ts +1 -1
  27. package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetControlProps.d.ts +1 -0
  28. package/lib/types/components/webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios.d.ts +1 -0
  29. package/lib/types/contexts/common/ILiveChatWidgetLocalizedTexts.d.ts +9 -0
  30. package/package.json +3 -3
@@ -55,13 +55,11 @@ const createMagicCodeSuccessResponse = signin => {
55
55
  };
56
56
  };
57
57
  const WebChatContainerStateful = props => {
58
- var _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _props$webChatContain3, _props$webChatContain4, _defaultWebChatContai, _props$webChatContain5, _props$webChatContain6, _defaultWebChatContai2, _webChatContainerProp7, _webChatContainerProp8, _webChatContainerProp9, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _webChatContainerProp13, _webChatContainerProp14;
58
+ var _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _props$webChatContain5, _props$webChatContain6, _defaultWebChatContai, _props$webChatContain7, _props$webChatContain8, _defaultWebChatContai2, _webChatContainerProp7, _webChatContainerProp8, _webChatContainerProp9, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _webChatContainerProp13, _webChatContainerProp14;
59
59
  const {
60
60
  BasicWebChat
61
61
  } = _botframeworkWebchat.Components;
62
62
  const [state, dispatch] = (0, _.useChatContextStore)();
63
- const magicCodeBroadcastChannel = new window.BroadcastChannel(_Constants.Constants.magicCodeBroadcastChannel); // eslint-disable-line @typescript-eslint/no-explicit-any
64
- const magicCodeResponseBroadcastChannel = new window.BroadcastChannel(_Constants.Constants.magicCodeResponseBroadcastChannel); // eslint-disable-line @typescript-eslint/no-explicit-any
65
63
  const {
66
64
  webChatContainerProps,
67
65
  contextDataStore
@@ -69,7 +67,7 @@ const WebChatContainerStateful = props => {
69
67
  const containerStyles = {
70
68
  root: Object.assign({}, _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.containerStyles, webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.containerStyles, {
71
69
  display: state.appStates.isMinimized ? "none" : ""
72
- }) // Use this instead of removing WebChat from the picture so that the activity observer inside the adapter is not invoked
70
+ }) // Use this instead of removing WebChat from the picture so that the activity observer inside the adapter is not invoked
73
71
  };
74
72
 
75
73
  const localizedTexts = {
@@ -103,6 +101,21 @@ const WebChatContainerStateful = props => {
103
101
  }
104
102
  }, []);
105
103
  (0, _react2.useEffect)(() => {
104
+ var _props$webChatContain3, _props$webChatContain4;
105
+ if (!((_props$webChatContain3 = props.webChatContainerProps) !== null && _props$webChatContain3 !== void 0 && (_props$webChatContain4 = _props$webChatContain3.botMagicCode) !== null && _props$webChatContain4 !== void 0 && _props$webChatContain4.disabled)) {
106
+ return;
107
+ }
108
+ if (!window.BroadcastChannel) {
109
+ // eslint-disable-line @typescript-eslint/no-explicit-any
110
+ _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
111
+ Event: _TelemetryConstants.TelemetryEvent.SuppressBotMagicCodeFailed,
112
+ Description: "BroadcastChannel not supported by default on current browser"
113
+ });
114
+ return;
115
+ }
116
+ const magicCodeBroadcastChannel = new window.BroadcastChannel(_Constants.Constants.magicCodeBroadcastChannel); // eslint-disable-line @typescript-eslint/no-explicit-any
117
+ const magicCodeResponseBroadcastChannel = new window.BroadcastChannel(_Constants.Constants.magicCodeResponseBroadcastChannel); // eslint-disable-line @typescript-eslint/no-explicit-any
118
+
106
119
  const eventListener = event => {
107
120
  // eslint-disable-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-empty-function
108
121
  const {
@@ -156,8 +169,8 @@ const WebChatContainerStateful = props => {
156
169
  div[class="ac-input-container"] * {white-space:${(webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : (_webChatContainerProp6 = webChatContainerProps.adaptiveCardStyles) === null || _webChatContainerProp6 === void 0 ? void 0 : _webChatContainerProp6.textWhiteSpace) ?? _defaultAdaptiveCardStyles.defaultAdaptiveCardStyles.textWhiteSpace}}
157
170
 
158
171
  .ms_lcw_webchat_received_message>div.webchat__stacked-layout>div.webchat__stacked-layout__main>div.webchat__stacked-layout__content>div.webchat__stacked-layout__message-row>[class^=webchat]:not(.webchat__bubble--from-user)>.webchat__bubble__content {
159
- background-color: ${((_props$webChatContain3 = props.webChatContainerProps) === null || _props$webChatContain3 === void 0 ? void 0 : (_props$webChatContain4 = _props$webChatContain3.webChatStyles) === null || _props$webChatContain4 === void 0 ? void 0 : _props$webChatContain4.bubbleBackground) ?? ((_defaultWebChatContai = _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.webChatStyles) === null || _defaultWebChatContai === void 0 ? void 0 : _defaultWebChatContai.bubbleBackground)};
160
- color:${((_props$webChatContain5 = props.webChatContainerProps) === null || _props$webChatContain5 === void 0 ? void 0 : (_props$webChatContain6 = _props$webChatContain5.webChatStyles) === null || _props$webChatContain6 === void 0 ? void 0 : _props$webChatContain6.bubbleTextColor) ?? ((_defaultWebChatContai2 = _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.webChatStyles) === null || _defaultWebChatContai2 === void 0 ? void 0 : _defaultWebChatContai2.bubbleTextColor)};
172
+ background-color: ${((_props$webChatContain5 = props.webChatContainerProps) === null || _props$webChatContain5 === void 0 ? void 0 : (_props$webChatContain6 = _props$webChatContain5.webChatStyles) === null || _props$webChatContain6 === void 0 ? void 0 : _props$webChatContain6.bubbleBackground) ?? ((_defaultWebChatContai = _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.webChatStyles) === null || _defaultWebChatContai === void 0 ? void 0 : _defaultWebChatContai.bubbleBackground)};
173
+ color:${((_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : (_props$webChatContain8 = _props$webChatContain7.webChatStyles) === null || _props$webChatContain8 === void 0 ? void 0 : _props$webChatContain8.bubbleTextColor) ?? ((_defaultWebChatContai2 = _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.webChatStyles) === null || _defaultWebChatContai2 === void 0 ? void 0 : _defaultWebChatContai2.bubbleTextColor)};
161
174
  }
162
175
 
163
176
  div[class="ac-textBlock"] a:link,
@@ -165,11 +178,11 @@ const WebChatContainerStateful = props => {
165
178
  div[class="ac-textBlock"] a:hover,
166
179
  div[class="ac-textBlock"] a:active {
167
180
  color: ${(webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : (_webChatContainerProp7 = webChatContainerProps.adaptiveCardStyles) === null || _webChatContainerProp7 === void 0 ? void 0 : _webChatContainerProp7.anchorColor) ?? _defaultAdaptiveCardStyles.defaultAdaptiveCardStyles.anchorColor};
168
- }
181
+ }
169
182
 
170
183
  .webchat__stacked-layout__content .ac-actionSet > .ac-pushButton > div {white-space: ${(webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : (_webChatContainerProp8 = webChatContainerProps.adaptiveCardStyles) === null || _webChatContainerProp8 === void 0 ? void 0 : _webChatContainerProp8.buttonWhiteSpace) ?? _defaultAdaptiveCardStyles.defaultAdaptiveCardStyles.buttonWhiteSpace} !important;}
171
184
 
172
- .ms_lcw_webchat_received_message img.webchat__markdown__external-link-icon {
185
+ .ms_lcw_webchat_received_message img.webchat__markdown__external-link-icon {
173
186
  background-image : url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIzIDMgMTggMTgiICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik03LjI1MDEgNC41MDAxN0gxMC43NDk1QzExLjE2MzcgNC41MDAxNyAxMS40OTk1IDQuODM1OTYgMTEuNDk5NSA1LjI1MDE3QzExLjQ5OTUgNS42Mjk4NiAxMS4yMTczIDUuOTQzNjYgMTAuODUxMyA1Ljk5MzMyTDEwLjc0OTUgNi4wMDAxN0g3LjI0OTc0QzYuMDcwNzkgNS45OTk2MSA1LjEwMzQ5IDYuOTA2NTYgNS4wMDc4NiA4LjA2MTEyTDUuMDAwMjggOC4yMjAwM0w1LjAwMzEyIDE2Ljc1MDdDNS4wMDM0MyAxNy45NDE1IDUuOTI4ODUgMTguOTE2MSA3LjA5OTY2IDE4Ljk5NDlMNy4yNTM3MSAxOS4wMDAxTDE1Ljc1MTggMTguOTg4NEMxNi45NDE1IDE4Ljk4NjggMTcuOTE0NSAxOC4wNjIgMTcuOTkzNSAxNi44OTIzTDE3Ljk5ODcgMTYuNzM4NFYxMy4yMzIxQzE3Ljk5ODcgMTIuODE3OSAxOC4zMzQ1IDEyLjQ4MjEgMTguNzQ4NyAxMi40ODIxQzE5LjEyODQgMTIuNDgyMSAxOS40NDIyIDEyLjc2NDMgMTkuNDkxOCAxMy4xMzAzTDE5LjQ5ODcgMTMuMjMyMVYxNi43Mzg0QzE5LjQ5ODcgMTguNzQwNyAxNy45MjkzIDIwLjM3NjkgMTUuOTUyOCAyMC40ODI5TDE1Ljc1MzggMjAuNDg4NEw3LjI1ODI3IDIwLjUwMDFMNy4wNTQ5NSAyMC40OTQ5QzUuMTQyMzkgMjAuMzk1NCAzLjYwODk1IDE4Ljg2MjcgMy41MDgzNyAxNi45NTAyTDMuNTAzMTIgMTYuNzUxMUwzLjUwMDg5IDguMjUyN0wzLjUwNTI5IDguMDUwMkMzLjYwNTM5IDYuMTM3NDkgNS4xMzg2NyA0LjYwNDQ5IDcuMDUwOTYgNC41MDUyN0w3LjI1MDEgNC41MDAxN0gxMC43NDk1SDcuMjUwMVpNMTMuNzQ4MSAzLjAwMTQ2TDIwLjMwMTggMy4wMDE5N0wyMC40MDE0IDMuMDE1NzVMMjAuNTAyMiAzLjA0MzkzTDIwLjU1OSAzLjA2ODAzQzIwLjYxMjIgMy4wOTEyMiAyMC42NjM0IDMuMTIxNjMgMjAuNzExMSAzLjE1ODg1TDIwLjc4MDQgMy4yMjE1NkwyMC44NjQxIDMuMzIwMTRMMjAuOTE4MyAzLjQxMDI1TDIwLjk1NyAzLjUwMDU3TDIwLjk3NjIgMy41NjQ3NkwyMC45ODk4IDMuNjI4NjJMMjAuOTk5MiAzLjcyMjgyTDIwLjk5OTcgMTAuMjU1NEMyMC45OTk3IDEwLjY2OTYgMjAuNjYzOSAxMS4wMDU0IDIwLjI0OTcgMTEuMDA1NEMxOS44NyAxMS4wMDU0IDE5LjU1NjIgMTAuNzIzMiAxOS41MDY1IDEwLjM1NzFMMTkuNDk5NyAxMC4yNTU0TDE5LjQ5ODkgNS41NjE0N0wxMi4yNzk3IDEyLjc4NDdDMTIuMDEzNCAxMy4wNTEgMTEuNTk2OCAxMy4wNzUzIDExLjMwMzEgMTIuODU3NUwxMS4yMTkgMTIuNzg0OUMxMC45NTI3IDEyLjUxODcgMTAuOTI4NCAxMi4xMDIxIDExLjE0NjIgMTEuODA4NEwxMS4yMTg4IDExLjcyNDNMMTguNDM2OSA0LjUwMTQ2SDEzLjc0ODFDMTMuMzY4NCA0LjUwMTQ2IDEzLjA1NDYgNC4yMTkzMSAxMy4wMDUgMy44NTMyNEwxMi45OTgxIDMuNzUxNDZDMTIuOTk4MSAzLjM3MTc3IDEzLjI4MDMgMy4wNTc5NyAxMy42NDY0IDMuMDA4MzFMMTMuNzQ4MSAzLjAwMTQ2WiIgZmlsbD0iI0ZGRkZGRiIgLz48L3N2Zz4) !important;
174
187
  height: '.75em';
175
188
  marginLeft: '.25em';
@@ -187,7 +200,7 @@ const WebChatContainerStateful = props => {
187
200
  .ms_lcw_webchat_received_message a:hover,
188
201
  .ms_lcw_webchat_received_message a:active {
189
202
  color: ${(webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : (_webChatContainerProp11 = webChatContainerProps.renderingMiddlewareProps) === null || _webChatContainerProp11 === void 0 ? void 0 : (_webChatContainerProp12 = _webChatContainerProp11.receivedMessageAnchorStyles) === null || _webChatContainerProp12 === void 0 ? void 0 : _webChatContainerProp12.color) ?? (_defaultReceivedMessageAnchorStyles.defaultReceivedMessageAnchorStyles === null || _defaultReceivedMessageAnchorStyles.defaultReceivedMessageAnchorStyles === void 0 ? void 0 : _defaultReceivedMessageAnchorStyles.defaultReceivedMessageAnchorStyles.color)};
190
- }
203
+ }
191
204
  .ms_lcw_webchat_sent_message a:link,
192
205
  .ms_lcw_webchat_sent_message a:visited,
193
206
  .ms_lcw_webchat_sent_message a:hover,
@@ -32,6 +32,8 @@ const defaultMiddlewareLocalizedTexts = {
32
32
  MIDDLEWARE_MESSAGE_RETRY: "Retry",
33
33
  MIDDLEWARE_BANNER_CHAT_DISCONNECT: "Your conversation has been disconnected. For additional assistance, please start a new chat.",
34
34
  THIRD_PARTY_COOKIES_BLOCKED_ALERT_MESSAGE: "Third party cookies are blocked. Reloading this page will start a new conversation.",
35
- MIDDLEWARE_BANNER_FILE_IS_MALICIOUS: "{0} has been blocked because the file may contain a malware."
35
+ MIDDLEWARE_BANNER_FILE_IS_MALICIOUS: "{0} has been blocked because the file may contain a malware.",
36
+ MIDDLEWARE_BANNER_FILE_EMAIL_ADDRESS_RECORDED_SUCCESS: "Email will be sent after chat ends!",
37
+ MIDDLEWARE_BANNER_FILE_EMAIL_ADDRESS_RECORDED_ERROR: "Email {0} could not be saved, try again later."
36
38
  };
37
39
  exports.defaultMiddlewareLocalizedTexts = defaultMiddlewareLocalizedTexts;
@@ -10,6 +10,7 @@ exports.NotificationScenarios = NotificationScenarios;
10
10
  NotificationScenarios["Connection"] = "connection";
11
11
  NotificationScenarios["DownloadTranscriptError"] = "download transcript";
12
12
  NotificationScenarios["EmailTranscriptError"] = "email transcript";
13
+ NotificationScenarios["EmailAddressSaved"] = "email address saved";
13
14
  NotificationScenarios["AttachmentError"] = "attachment";
14
15
  NotificationScenarios["InternetConnection"] = "internet connection";
15
16
  NotificationScenarios["MaxSizeError"] = "max size";
@@ -396,4 +396,20 @@ export const createFileAndDownload = (fileName, blobData, mimeType) => {
396
396
  document.body.appendChild(aElement);
397
397
  aElement.click();
398
398
  document.body.removeChild(aElement);
399
+ };
400
+
401
+ /**
402
+ *
403
+ * Replace placeholders with format {0}..{n} , in a string with values
404
+ *
405
+ * @param template String with placeholders to be replaced
406
+ * @param values array of values to replace the placeholders
407
+ * @returns formatted string with replaced values
408
+ */
409
+ // use of any for values as array of any type is passed
410
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
411
+ export const formatTemplateString = (templateMessage, values) => {
412
+ return templateMessage.replace(/{(\d+)}/g, (match, index) => {
413
+ return typeof values[index] !== "undefined" ? values[index] : match;
414
+ });
399
415
  };
@@ -56,17 +56,14 @@ export const ChatButtonStateful = props => {
56
56
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
57
57
  Event: TelemetryEvent.LCWChatButtonClicked
58
58
  });
59
- if (state.appStates.isMinimized) {
60
- dispatch({
61
- type: LiveChatWidgetActionType.SET_MINIMIZED,
62
- payload: false
63
- });
64
- } else {
65
- dispatch({
66
- type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
67
- payload: ConversationState.OutOfOffice
68
- });
69
- }
59
+ state.appStates.isMinimized && dispatch({
60
+ type: LiveChatWidgetActionType.SET_MINIMIZED,
61
+ payload: false
62
+ });
63
+ dispatch({
64
+ type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
65
+ payload: ConversationState.OutOfOffice
66
+ });
70
67
  },
71
68
  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,
72
69
  ...(outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.controlProps)
@@ -1,6 +1,6 @@
1
1
  import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
2
2
  import React, { useEffect, useState } from "react";
3
- import { findAllFocusableElement, findParentFocusableElementsWithoutChildContainer, preventFocusToMoveOutOfElement, setFocusOnElement, setFocusOnSendBox, setTabIndices } from "../../common/utils";
3
+ import { findAllFocusableElement, findParentFocusableElementsWithoutChildContainer, formatTemplateString, preventFocusToMoveOutOfElement, setFocusOnElement, setFocusOnSendBox, setTabIndices } from "../../common/utils";
4
4
  import { DimLayer } from "../dimlayer/DimLayer";
5
5
  import { InputValidationPane } from "@microsoft/omnichannel-chat-components";
6
6
  import { LiveChatWidgetActionType } from "../../contexts/common/LiveChatWidgetActionType";
@@ -10,6 +10,7 @@ import { Regex } from "../../common/Constants";
10
10
  import { TelemetryHelper } from "../../common/telemetry/TelemetryHelper";
11
11
  import useChatContextStore from "../../hooks/useChatContextStore";
12
12
  import useChatSDKStore from "../../hooks/useChatSDKStore";
13
+ import { defaultMiddlewareLocalizedTexts } from "../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts";
13
14
  export const EmailTranscriptPaneStateful = props => {
14
15
  var _props$controlProps;
15
16
  const initialTabIndexMap = new Map();
@@ -46,6 +47,7 @@ export const EmailTranscriptPaneStateful = props => {
46
47
  };
47
48
  try {
48
49
  await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.emailLiveChatTranscript(chatTranscriptBody));
50
+ NotificationHandler.notifySuccess(NotificationScenarios.EmailAddressSaved, defaultMiddlewareLocalizedTexts === null || defaultMiddlewareLocalizedTexts === void 0 ? void 0 : defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_FILE_EMAIL_ADDRESS_RECORDED_SUCCESS);
49
51
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
50
52
  Event: TelemetryEvent.EmailTranscriptSent,
51
53
  Description: "Transcript sent to email successfully."
@@ -57,7 +59,8 @@ export const EmailTranscriptPaneStateful = props => {
57
59
  exception: ex
58
60
  }
59
61
  });
60
- NotificationHandler.notifyError(NotificationScenarios.EmailTranscriptError, (props === null || props === void 0 ? void 0 : props.bannerMessageOnError) ?? "Email transcript to " + email + " failed.");
62
+ const message = formatTemplateString(defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_FILE_EMAIL_ADDRESS_RECORDED_ERROR, [email]);
63
+ NotificationHandler.notifyError(NotificationScenarios.EmailTranscriptError, (props === null || props === void 0 ? void 0 : props.bannerMessageOnError) ?? message);
61
64
  }
62
65
  },
63
66
  onCancel: () => {
@@ -1,7 +1,7 @@
1
1
  import { ConfirmationState, Constants, ConversationEndEntity, ParticipantType } from "../../../common/Constants";
2
2
  import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
3
3
  import { getAuthClientFunction, handleAuthentication } from "./authHelper";
4
- import { getConversationDetailsCall, getWidgetEndChatEventName, isNullOrEmptyString } from "../../../common/utils";
4
+ import { getConversationDetailsCall, getWidgetEndChatEventName } from "../../../common/utils";
5
5
  import { getPostChatContext, initiatePostChat } from "./renderSurveyHelpers";
6
6
  import { BroadcastService } from "@microsoft/omnichannel-chat-components";
7
7
  import { ConversationState } from "../../../contexts/common/ConversationState";
@@ -9,11 +9,12 @@ import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidge
9
9
  import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
10
10
  import { WebChatStoreLoader } from "../../webchatcontainerstateful/webchatcontroller/WebChatStoreLoader";
11
11
  import { defaultWebChatContainerStatefulProps } from "../../webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps";
12
+ import { TelemetryManager } from "../../../common/telemetry/TelemetryManager";
12
13
 
13
14
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
- const prepareEndChat = async (props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, uwid) => {
15
+ const prepareEndChat = async (props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter) => {
15
16
  try {
16
- var _conversationDetails$, _state$domainStates, _state$domainStates2;
17
+ var _conversationDetails$, _state$domainStates;
17
18
  // Use Case: If call is ongoing, end the call by simulating end call button click
18
19
  endVoiceVideoCallIfOngoing(chatSDK, dispatch);
19
20
  const conversationDetails = await getConversationDetailsCall(chatSDK);
@@ -23,7 +24,7 @@ const prepareEndChat = async (props, chatSDK, state, dispatch, setAdapter, setWe
23
24
  var _state$appStates;
24
25
  // If ended by customer, just close chat
25
26
  if ((state === null || state === void 0 ? void 0 : (_state$appStates = state.appStates) === null || _state$appStates === void 0 ? void 0 : _state$appStates.conversationEndedBy) === ConversationEndEntity.Customer) {
26
- await endChat(props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, false, true, uwid);
27
+ await endChat(props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, false, true);
27
28
  }
28
29
  // Use Case: If ended by Agent, stay chat in InActive state
29
30
  return;
@@ -38,15 +39,13 @@ const prepareEndChat = async (props, chatSDK, state, dispatch, setAdapter, setWe
38
39
  }
39
40
 
40
41
  // Use Case: Can render post chat scenarios
41
- await getPostChatContext(chatSDK, state, dispatch);
42
-
43
42
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
44
- const postchatContext = state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : _state$domainStates.postChatContext;
43
+ const postchatContext = (await getPostChatContext(chatSDK, state, dispatch)) ?? (state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : _state$domainStates.postChatContext);
45
44
  if (postchatContext === undefined) {
46
45
  var _state$appStates2;
47
46
  // For Customer intiated conversations, just close chat widget
48
47
  if ((state === null || state === void 0 ? void 0 : (_state$appStates2 = state.appStates) === null || _state$appStates2 === void 0 ? void 0 : _state$appStates2.conversationEndedBy) === ConversationEndEntity.Customer) {
49
- await endChat(props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, false, true, uwid);
48
+ await endChat(props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, false, true);
50
49
  return;
51
50
  }
52
51
 
@@ -57,10 +56,10 @@ const prepareEndChat = async (props, chatSDK, state, dispatch, setAdapter, setWe
57
56
  });
58
57
  return;
59
58
  }
60
- endChat(props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, true, true, uwid);
59
+ endChat(props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, true, true);
61
60
 
62
61
  // Initiate post chat render
63
- if (state !== null && state !== void 0 && (_state$domainStates2 = state.domainStates) !== null && _state$domainStates2 !== void 0 && _state$domainStates2.postChatContext) {
62
+ if (postchatContext) {
64
63
  await initiatePostChat(props, conversationDetails, state, dispatch, postchatContext);
65
64
  return;
66
65
  }
@@ -75,7 +74,7 @@ const prepareEndChat = async (props, chatSDK, state, dispatch, setAdapter, setWe
75
74
 
76
75
  //Close chat widget for any failure in embedded to allow to show start chat button
77
76
  if (((_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.hideStartChatButton) === false) {
78
- await endChat(props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, false, true, uwid);
77
+ await endChat(props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, false, true);
79
78
  }
80
79
  } finally {
81
80
  //Chat token clean up
@@ -84,8 +83,7 @@ const prepareEndChat = async (props, chatSDK, state, dispatch, setAdapter, setWe
84
83
  };
85
84
 
86
85
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
87
- const endChat = async function (props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, skipEndChatSDK, skipCloseChat, postMessageToOtherTab) {
88
- let uwid = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : "";
86
+ const endChat = async (props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, skipEndChatSDK, skipCloseChat, postMessageToOtherTab) => {
89
87
  if (!skipEndChatSDK && chatSDK.conversation) {
90
88
  try {
91
89
  TelemetryHelper.logSDKEvent(LogLevel.INFO, {
@@ -137,15 +135,17 @@ const endChat = async function (props, chatSDK, state, dispatch, setAdapter, set
137
135
  closeChatWidget(dispatch, props, state);
138
136
  }
139
137
  }
140
- if (postMessageToOtherTab && !isNullOrEmptyString(uwid)) {
138
+ if (postMessageToOtherTab) {
141
139
  const endChatEventName = await getEndChatEventName(chatSDK, props);
142
140
  BroadcastService.postMessage({
143
141
  eventName: endChatEventName,
144
- payload: uwid
142
+ payload: {
143
+ runtimeId: TelemetryManager.InternalTelemetryData.lcwRuntimeId
144
+ }
145
145
  });
146
146
  }
147
147
  };
148
- const callingStateCleanUp = async dispatch => {
148
+ export const callingStateCleanUp = async dispatch => {
149
149
  dispatch({
150
150
  type: LiveChatWidgetActionType.SHOW_CALLING_CONTAINER,
151
151
  payload: false
@@ -167,7 +167,7 @@ const callingStateCleanUp = async dispatch => {
167
167
  payload: true
168
168
  });
169
169
  };
170
- const endChatStateCleanUp = async dispatch => {
170
+ export const endChatStateCleanUp = async dispatch => {
171
171
  // Need to clear these states immediately when chat ended from OC.
172
172
  dispatch({
173
173
  type: LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
@@ -182,7 +182,7 @@ const endChatStateCleanUp = async dispatch => {
182
182
  payload: false
183
183
  });
184
184
  };
185
- const closeChatStateCleanUp = async dispatch => {
185
+ export const closeChatStateCleanUp = async dispatch => {
186
186
  dispatch({
187
187
  type: LiveChatWidgetActionType.SET_CHAT_TOKEN,
188
188
  payload: undefined
@@ -20,7 +20,7 @@ const handleChatReconnect = async (chatSDK, props, dispatch, setAdapter, initSta
20
20
  // Get chat reconnect context
21
21
  const reconnectChatContext = await getChatReconnectContext(chatSDK, props.chatConfig, props, isAuthenticatedChat);
22
22
 
23
- //Redirect if enabled
23
+ // Redirect if enabled
24
24
  if (reconnectChatContext !== null && reconnectChatContext !== void 0 && reconnectChatContext.redirectURL) {
25
25
  var _props$reconnectChatP;
26
26
  redirectPage(reconnectChatContext.redirectURL, (_props$reconnectChatP = props.reconnectChatPaneProps) === null || _props$reconnectChatP === void 0 ? void 0 : _props$reconnectChatP.redirectInSameWindow);
@@ -42,24 +42,25 @@ const setSurveyMode = async (props, participantType, state, dispatch) => {
42
42
  return;
43
43
  }
44
44
  };
45
- const renderSurvey = async (state, dispatch) => {
45
+
46
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
+ const renderSurvey = async (postChatContext, dispatch) => {
46
48
  if (postChatSurveyMode === PostChatSurveyMode.Link) {
47
49
  setWidgetStateToInactive(dispatch);
48
50
  return;
49
51
  }
50
52
  if (postChatSurveyMode === PostChatSurveyMode.Embed) {
51
- await embedModePostChatWorkflow(state, dispatch);
53
+ await embedModePostChatWorkflow(postChatContext, dispatch);
52
54
  }
53
55
  };
54
56
 
55
57
  // Function for embed mode postchat workflow which is essentially same for both customer and agent
56
58
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
- const embedModePostChatWorkflow = async (state, dispatch) => {
58
- var _state$domainStates2;
59
+ const embedModePostChatWorkflow = async (postChatContext, dispatch) => {
59
60
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
60
61
  Event: TelemetryEvent.EmbedModePostChatWorkflowStarted
61
62
  });
62
- if (state !== null && state !== void 0 && (_state$domainStates2 = state.domainStates) !== null && _state$domainStates2 !== void 0 && _state$domainStates2.postChatContext) {
63
+ if (postChatContext) {
63
64
  dispatch({
64
65
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
65
66
  payload: ConversationState.PostchatLoading
@@ -70,7 +71,7 @@ const embedModePostChatWorkflow = async (state, dispatch) => {
70
71
  payload: ConversationState.Postchat
71
72
  });
72
73
  } else {
73
- const error = `Conversation was Ended but App State was not set correctly: postChatContext = ${state.domainStates.postChatContext}`;
74
+ const error = `Conversation was Ended but App State was not set correctly: postChatContext = ${postChatContext}`;
74
75
  TelemetryHelper.logActionEvent(LogLevel.ERROR, {
75
76
  Event: TelemetryEvent.AppStatesException,
76
77
  ExceptionDetails: {
@@ -86,7 +87,7 @@ const initiatePostChat = async (props, conversationDetailsParam, state, dispatch
86
87
  conversationDetails = conversationDetailsParam;
87
88
  const participantType = ((_conversationDetails = conversationDetails) === null || _conversationDetails === void 0 ? void 0 : _conversationDetails.participantType) ?? postchatContext.participantType;
88
89
  await setSurveyMode(props, participantType, state, dispatch);
89
- await renderSurvey(state, dispatch);
90
+ await renderSurvey(postchatContext, dispatch);
90
91
  };
91
92
 
92
93
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -99,8 +100,8 @@ const isPostChatEnabled = (props, state) => {
99
100
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
100
101
  const getPostChatContext = async (chatSDK, state, dispatch) => {
101
102
  try {
102
- var _state$domainStates3;
103
- if ((state === null || state === void 0 ? void 0 : (_state$domainStates3 = state.domainStates) === null || _state$domainStates3 === void 0 ? void 0 : _state$domainStates3.postChatContext) === undefined) {
103
+ var _state$domainStates2;
104
+ if ((state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : _state$domainStates2.postChatContext) === undefined) {
104
105
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
106
  const context = await chatSDK.getPostChatSurveyContext();
106
107
  TelemetryHelper.logSDKEvent(LogLevel.INFO, {
@@ -111,6 +112,7 @@ const getPostChatContext = async (chatSDK, state, dispatch) => {
111
112
  type: LiveChatWidgetActionType.SET_POST_CHAT_CONTEXT,
112
113
  payload: context
113
114
  });
115
+ return context;
114
116
  }
115
117
  } catch (error) {
116
118
  TelemetryHelper.logSDKEvent(LogLevel.INFO, {
@@ -63,15 +63,29 @@ const setPreChatAndInitiateChat = async (chatSDK, dispatch, setAdapter, isProact
63
63
  const preChatSurveyResponse = await chatSDK.getPreChatSurvey(parseToJson);
64
64
  const showPrechat = isProactiveChat ? preChatSurveyResponse && proactiveChatEnablePrechatState : preChatSurveyResponse && !(props !== null && props !== void 0 && (_props$controlProps = props.controlProps) !== null && _props$controlProps !== void 0 && _props$controlProps.hidePreChatSurveyPane);
65
65
  if (showPrechat) {
66
- dispatch({
67
- type: LiveChatWidgetActionType.SET_PRE_CHAT_SURVEY_RESPONSE,
68
- payload: preChatSurveyResponse
69
- });
70
- dispatch({
71
- type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
72
- payload: ConversationState.Prechat
73
- });
74
- return;
66
+ var _state$domainStates, _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3;
67
+ const isOutOfOperatingHours = (state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_state$domainStates$l = _state$domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : (_state$domainStates$l2 = _state$domainStates$l.LiveWSAndLiveChatEngJoin) === null || _state$domainStates$l2 === void 0 ? void 0 : (_state$domainStates$l3 = _state$domainStates$l2.OutOfOperatingHours) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.toLowerCase()) === "true";
68
+ if (isOutOfOperatingHours) {
69
+ (state === null || state === void 0 ? void 0 : state.appStates.isMinimized) && dispatch({
70
+ type: LiveChatWidgetActionType.SET_MINIMIZED,
71
+ payload: false
72
+ });
73
+ dispatch({
74
+ type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
75
+ payload: ConversationState.OutOfOffice
76
+ });
77
+ return;
78
+ } else {
79
+ dispatch({
80
+ type: LiveChatWidgetActionType.SET_PRE_CHAT_SURVEY_RESPONSE,
81
+ payload: preChatSurveyResponse
82
+ });
83
+ dispatch({
84
+ type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
85
+ payload: ConversationState.Prechat
86
+ });
87
+ return;
88
+ }
75
89
  }
76
90
 
77
91
  //Initiate start chat
@@ -295,17 +309,17 @@ const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdap
295
309
 
296
310
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
297
311
  const setCustomContextParams = async (state, props) => {
298
- var _props$chatConfig, _props$chatConfig$Liv, _state$domainStates, _persistedState$domai8;
312
+ var _props$chatConfig, _props$chatConfig$Liv, _state$domainStates2, _persistedState$domai8;
299
313
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
300
314
  const isAuthenticatedChat = props !== null && props !== void 0 && (_props$chatConfig = props.chatConfig) !== null && _props$chatConfig !== void 0 && (_props$chatConfig$Liv = _props$chatConfig.LiveChatConfigAuthSettings) !== null && _props$chatConfig$Liv !== void 0 && _props$chatConfig$Liv.msdyn_javascriptclientfunction ? true : false;
301
315
  //Should not set custom context for auth chat
302
316
  if (isAuthenticatedChat) {
303
317
  return;
304
318
  }
305
- if (state !== null && state !== void 0 && (_state$domainStates = state.domainStates) !== null && _state$domainStates !== void 0 && _state$domainStates.customContext) {
306
- var _state$domainStates2;
319
+ if (state !== null && state !== void 0 && (_state$domainStates2 = state.domainStates) !== null && _state$domainStates2 !== void 0 && _state$domainStates2.customContext) {
320
+ var _state$domainStates3;
307
321
  optionalParams = Object.assign({}, optionalParams, {
308
- customContext: JSON.parse(JSON.stringify(state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : _state$domainStates2.customContext))
322
+ customContext: JSON.parse(JSON.stringify(state === null || state === void 0 ? void 0 : (_state$domainStates3 = state.domainStates) === null || _state$domainStates3 === void 0 ? void 0 : _state$domainStates3.customContext))
309
323
  });
310
324
  return;
311
325
  }
@@ -353,8 +367,8 @@ const canStartPopoutChat = async props => {
353
367
 
354
368
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
355
369
  const checkIfConversationStillValid = async (chatSDK, dispatch, state) => {
356
- var _state$domainStates3, _state$domainStates3$;
357
- const requestIdFromCache = (_state$domainStates3 = state.domainStates) === null || _state$domainStates3 === void 0 ? void 0 : (_state$domainStates3$ = _state$domainStates3.liveChatContext) === null || _state$domainStates3$ === void 0 ? void 0 : _state$domainStates3$.requestId;
370
+ var _state$domainStates4, _state$domainStates4$;
371
+ const requestIdFromCache = (_state$domainStates4 = state.domainStates) === null || _state$domainStates4 === void 0 ? void 0 : (_state$domainStates4$ = _state$domainStates4.liveChatContext) === null || _state$domainStates4$ === void 0 ? void 0 : _state$domainStates4$.requestId;
358
372
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
359
373
  let conversationDetails = undefined;
360
374