@microsoft/omnichannel-chat-widget 1.4.1-main.9bf5e75 → 1.4.1-main.d29da65

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 (19) hide show
  1. package/lib/cjs/common/utils.js +19 -2
  2. package/lib/cjs/components/emailtranscriptpanestateful/EmailTranscriptPaneStateful.js +4 -1
  3. package/lib/cjs/components/livechatwidget/common/endChat.js +3 -5
  4. package/lib/cjs/components/livechatwidget/common/renderSurveyHelpers.js +11 -9
  5. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +22 -9
  6. package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +3 -1
  7. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios.js +1 -0
  8. package/lib/esm/common/utils.js +16 -0
  9. package/lib/esm/components/emailtranscriptpanestateful/EmailTranscriptPaneStateful.js +5 -2
  10. package/lib/esm/components/livechatwidget/common/endChat.js +3 -5
  11. package/lib/esm/components/livechatwidget/common/renderSurveyHelpers.js +11 -9
  12. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +22 -9
  13. package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +3 -1
  14. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios.js +1 -0
  15. package/lib/types/common/utils.d.ts +9 -0
  16. package/lib/types/components/livechatwidget/common/renderSurveyHelpers.d.ts +1 -1
  17. package/lib/types/components/webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios.d.ts +1 -0
  18. package/lib/types/contexts/common/ILiveChatWidgetLocalizedTexts.d.ts +9 -0
  19. package/package.json +3 -3
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.setTabIndices = exports.setFocusOnSendBox = exports.setFocusOnElement = exports.preventFocusToMoveOutOfElement = exports.parseAdaptiveCardPayload = exports.newGuid = exports.isUndefinedOrEmpty = exports.isNullOrUndefined = exports.isNullOrEmptyString = exports.getWidgetEndChatEventName = exports.getWidgetCacheIdfromProps = exports.getWidgetCacheId = exports.getTimestampHourMinute = exports.getStateFromCache = exports.getLocaleDirection = exports.getIconText = exports.getDomain = exports.getConversationDetailsCall = exports.getBroadcastChannelName = exports.findParentFocusableElementsWithoutChildContainer = exports.findAllFocusableElement = exports.extractPreChatSurveyResponseValues = exports.escapeHtml = exports.debounceLeading = exports.createTimer = exports.createFileAndDownload = exports.checkContactIdError = exports.changeLanguageCodeFormatForWebChat = exports.addDelayInMs = void 0;
6
+ exports.setTabIndices = exports.setFocusOnSendBox = exports.setFocusOnElement = exports.preventFocusToMoveOutOfElement = exports.parseAdaptiveCardPayload = exports.newGuid = exports.isUndefinedOrEmpty = exports.isNullOrUndefined = exports.isNullOrEmptyString = exports.getWidgetEndChatEventName = exports.getWidgetCacheIdfromProps = exports.getWidgetCacheId = exports.getTimestampHourMinute = exports.getStateFromCache = exports.getLocaleDirection = exports.getIconText = exports.getDomain = exports.getConversationDetailsCall = exports.getBroadcastChannelName = exports.formatTemplateString = exports.findParentFocusableElementsWithoutChildContainer = exports.findAllFocusableElement = exports.extractPreChatSurveyResponseValues = exports.escapeHtml = exports.debounceLeading = exports.createTimer = exports.createFileAndDownload = exports.checkContactIdError = exports.changeLanguageCodeFormatForWebChat = exports.addDelayInMs = void 0;
7
7
  var _Constants = require("./Constants");
8
8
  var _TelemetryConstants = require("./telemetry/TelemetryConstants");
9
9
  var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components");
@@ -431,4 +431,21 @@ const createFileAndDownload = (fileName, blobData, mimeType) => {
431
431
  aElement.click();
432
432
  document.body.removeChild(aElement);
433
433
  };
434
- exports.createFileAndDownload = createFileAndDownload;
434
+
435
+ /**
436
+ *
437
+ * Replace placeholders with format {0}..{n} , in a string with values
438
+ *
439
+ * @param template String with placeholders to be replaced
440
+ * @param values array of values to replace the placeholders
441
+ * @returns formatted string with replaced values
442
+ */
443
+ // use of any for values as array of any type is passed
444
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
445
+ exports.createFileAndDownload = createFileAndDownload;
446
+ const formatTemplateString = (templateMessage, values) => {
447
+ return templateMessage.replace(/{(\d+)}/g, (match, index) => {
448
+ return typeof values[index] !== "undefined" ? values[index] : match;
449
+ });
450
+ };
451
+ exports.formatTemplateString = formatTemplateString;
@@ -16,6 +16,7 @@ var _Constants = require("../../common/Constants");
16
16
  var _TelemetryHelper = require("../../common/telemetry/TelemetryHelper");
17
17
  var _useChatContextStore = _interopRequireDefault(require("../../hooks/useChatContextStore"));
18
18
  var _useChatSDKStore = _interopRequireDefault(require("../../hooks/useChatSDKStore"));
19
+ var _defaultMiddlewareLocalizedTexts = require("../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts");
19
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
21
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
21
22
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -55,6 +56,7 @@ const EmailTranscriptPaneStateful = props => {
55
56
  };
56
57
  try {
57
58
  await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.emailLiveChatTranscript(chatTranscriptBody));
59
+ _NotificationHandler.NotificationHandler.notifySuccess(_NotificationScenarios.NotificationScenarios.EmailAddressSaved, _defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts === null || _defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts === void 0 ? void 0 : _defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_FILE_EMAIL_ADDRESS_RECORDED_SUCCESS);
58
60
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
59
61
  Event: _TelemetryConstants.TelemetryEvent.EmailTranscriptSent,
60
62
  Description: "Transcript sent to email successfully."
@@ -66,7 +68,8 @@ const EmailTranscriptPaneStateful = props => {
66
68
  exception: ex
67
69
  }
68
70
  });
69
- _NotificationHandler.NotificationHandler.notifyError(_NotificationScenarios.NotificationScenarios.EmailTranscriptError, (props === null || props === void 0 ? void 0 : props.bannerMessageOnError) ?? "Email transcript to " + email + " failed.");
71
+ const message = (0, _utils.formatTemplateString)(_defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_FILE_EMAIL_ADDRESS_RECORDED_ERROR, [email]);
72
+ _NotificationHandler.NotificationHandler.notifyError(_NotificationScenarios.NotificationScenarios.EmailTranscriptError, (props === null || props === void 0 ? void 0 : props.bannerMessageOnError) ?? message);
70
73
  }
71
74
  },
72
75
  onCancel: () => {
@@ -19,7 +19,7 @@ var _TelemetryManager = require("../../../common/telemetry/TelemetryManager");
19
19
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
20
  const prepareEndChat = async (props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter) => {
21
21
  try {
22
- var _conversationDetails$, _state$domainStates, _state$domainStates2;
22
+ var _conversationDetails$, _state$domainStates;
23
23
  // Use Case: If call is ongoing, end the call by simulating end call button click
24
24
  endVoiceVideoCallIfOngoing(chatSDK, dispatch);
25
25
  const conversationDetails = await (0, _utils.getConversationDetailsCall)(chatSDK);
@@ -44,10 +44,8 @@ const prepareEndChat = async (props, chatSDK, state, dispatch, setAdapter, setWe
44
44
  }
45
45
 
46
46
  // Use Case: Can render post chat scenarios
47
- await (0, _renderSurveyHelpers.getPostChatContext)(chatSDK, state, dispatch);
48
-
49
47
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
- const postchatContext = state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : _state$domainStates.postChatContext;
48
+ const postchatContext = (await (0, _renderSurveyHelpers.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);
51
49
  if (postchatContext === undefined) {
52
50
  var _state$appStates2;
53
51
  // For Customer intiated conversations, just close chat widget
@@ -66,7 +64,7 @@ const prepareEndChat = async (props, chatSDK, state, dispatch, setAdapter, setWe
66
64
  endChat(props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, true, true);
67
65
 
68
66
  // Initiate post chat render
69
- if (state !== null && state !== void 0 && (_state$domainStates2 = state.domainStates) !== null && _state$domainStates2 !== void 0 && _state$domainStates2.postChatContext) {
67
+ if (postchatContext) {
70
68
  await (0, _renderSurveyHelpers.initiatePostChat)(props, conversationDetails, state, dispatch, postchatContext);
71
69
  return;
72
70
  }
@@ -48,24 +48,25 @@ const setSurveyMode = async (props, participantType, state, dispatch) => {
48
48
  return;
49
49
  }
50
50
  };
51
- const renderSurvey = async (state, dispatch) => {
51
+
52
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
53
+ const renderSurvey = async (postChatContext, dispatch) => {
52
54
  if (postChatSurveyMode === _PostChatSurveyMode.PostChatSurveyMode.Link) {
53
55
  setWidgetStateToInactive(dispatch);
54
56
  return;
55
57
  }
56
58
  if (postChatSurveyMode === _PostChatSurveyMode.PostChatSurveyMode.Embed) {
57
- await embedModePostChatWorkflow(state, dispatch);
59
+ await embedModePostChatWorkflow(postChatContext, dispatch);
58
60
  }
59
61
  };
60
62
 
61
63
  // Function for embed mode postchat workflow which is essentially same for both customer and agent
62
64
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
63
- const embedModePostChatWorkflow = async (state, dispatch) => {
64
- var _state$domainStates2;
65
+ const embedModePostChatWorkflow = async (postChatContext, dispatch) => {
65
66
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
66
67
  Event: _TelemetryConstants.TelemetryEvent.EmbedModePostChatWorkflowStarted
67
68
  });
68
- if (state !== null && state !== void 0 && (_state$domainStates2 = state.domainStates) !== null && _state$domainStates2 !== void 0 && _state$domainStates2.postChatContext) {
69
+ if (postChatContext) {
69
70
  dispatch({
70
71
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
71
72
  payload: _ConversationState.ConversationState.PostchatLoading
@@ -76,7 +77,7 @@ const embedModePostChatWorkflow = async (state, dispatch) => {
76
77
  payload: _ConversationState.ConversationState.Postchat
77
78
  });
78
79
  } else {
79
- const error = `Conversation was Ended but App State was not set correctly: postChatContext = ${state.domainStates.postChatContext}`;
80
+ const error = `Conversation was Ended but App State was not set correctly: postChatContext = ${postChatContext}`;
80
81
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
81
82
  Event: _TelemetryConstants.TelemetryEvent.AppStatesException,
82
83
  ExceptionDetails: {
@@ -92,7 +93,7 @@ const initiatePostChat = async (props, conversationDetailsParam, state, dispatch
92
93
  conversationDetails = conversationDetailsParam;
93
94
  const participantType = ((_conversationDetails = conversationDetails) === null || _conversationDetails === void 0 ? void 0 : _conversationDetails.participantType) ?? postchatContext.participantType;
94
95
  await setSurveyMode(props, participantType, state, dispatch);
95
- await renderSurvey(state, dispatch);
96
+ await renderSurvey(postchatContext, dispatch);
96
97
  };
97
98
 
98
99
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -107,8 +108,8 @@ const isPostChatEnabled = (props, state) => {
107
108
  exports.checkPostChatEnabled = isPostChatEnabled;
108
109
  const getPostChatContext = async (chatSDK, state, dispatch) => {
109
110
  try {
110
- var _state$domainStates3;
111
- if ((state === null || state === void 0 ? void 0 : (_state$domainStates3 = state.domainStates) === null || _state$domainStates3 === void 0 ? void 0 : _state$domainStates3.postChatContext) === undefined) {
111
+ var _state$domainStates2;
112
+ if ((state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : _state$domainStates2.postChatContext) === undefined) {
112
113
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
113
114
  const context = await chatSDK.getPostChatSurveyContext();
114
115
  _TelemetryHelper.TelemetryHelper.logSDKEvent(_TelemetryConstants.LogLevel.INFO, {
@@ -119,6 +120,7 @@ const getPostChatContext = async (chatSDK, state, dispatch) => {
119
120
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_POST_CHAT_CONTEXT,
120
121
  payload: context
121
122
  });
123
+ return context;
122
124
  }
123
125
  } catch (error) {
124
126
  _TelemetryHelper.TelemetryHelper.logSDKEvent(_TelemetryConstants.LogLevel.INFO, {
@@ -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
  };
@@ -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: () => {
@@ -14,7 +14,7 @@ import { TelemetryManager } from "../../../common/telemetry/TelemetryManager";
14
14
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
15
  const prepareEndChat = async (props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter) => {
16
16
  try {
17
- var _conversationDetails$, _state$domainStates, _state$domainStates2;
17
+ var _conversationDetails$, _state$domainStates;
18
18
  // Use Case: If call is ongoing, end the call by simulating end call button click
19
19
  endVoiceVideoCallIfOngoing(chatSDK, dispatch);
20
20
  const conversationDetails = await getConversationDetailsCall(chatSDK);
@@ -39,10 +39,8 @@ const prepareEndChat = async (props, chatSDK, state, dispatch, setAdapter, setWe
39
39
  }
40
40
 
41
41
  // Use Case: Can render post chat scenarios
42
- await getPostChatContext(chatSDK, state, dispatch);
43
-
44
42
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
- 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);
46
44
  if (postchatContext === undefined) {
47
45
  var _state$appStates2;
48
46
  // For Customer intiated conversations, just close chat widget
@@ -61,7 +59,7 @@ const prepareEndChat = async (props, chatSDK, state, dispatch, setAdapter, setWe
61
59
  endChat(props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, true, true);
62
60
 
63
61
  // Initiate post chat render
64
- if (state !== null && state !== void 0 && (_state$domainStates2 = state.domainStates) !== null && _state$domainStates2 !== void 0 && _state$domainStates2.postChatContext) {
62
+ if (postchatContext) {
65
63
  await initiatePostChat(props, conversationDetails, state, dispatch, postchatContext);
66
64
  return;
67
65
  }
@@ -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, {
@@ -47,13 +47,11 @@ const createMagicCodeSuccessResponse = signin => {
47
47
  };
48
48
  };
49
49
  export const WebChatContainerStateful = props => {
50
- 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;
50
+ 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;
51
51
  const {
52
52
  BasicWebChat
53
53
  } = Components;
54
54
  const [state, dispatch] = useChatContextStore();
55
- const magicCodeBroadcastChannel = new window.BroadcastChannel(Constants.magicCodeBroadcastChannel); // eslint-disable-line @typescript-eslint/no-explicit-any
56
- const magicCodeResponseBroadcastChannel = new window.BroadcastChannel(Constants.magicCodeResponseBroadcastChannel); // eslint-disable-line @typescript-eslint/no-explicit-any
57
55
  const {
58
56
  webChatContainerProps,
59
57
  contextDataStore
@@ -61,7 +59,7 @@ export const WebChatContainerStateful = props => {
61
59
  const containerStyles = {
62
60
  root: Object.assign({}, defaultWebChatContainerStatefulProps.containerStyles, webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.containerStyles, {
63
61
  display: state.appStates.isMinimized ? "none" : ""
64
- }) // Use this instead of removing WebChat from the picture so that the activity observer inside the adapter is not invoked
62
+ }) // Use this instead of removing WebChat from the picture so that the activity observer inside the adapter is not invoked
65
63
  };
66
64
 
67
65
  const localizedTexts = {
@@ -95,6 +93,21 @@ export const WebChatContainerStateful = props => {
95
93
  }
96
94
  }, []);
97
95
  useEffect(() => {
96
+ var _props$webChatContain3, _props$webChatContain4;
97
+ if (!((_props$webChatContain3 = props.webChatContainerProps) !== null && _props$webChatContain3 !== void 0 && (_props$webChatContain4 = _props$webChatContain3.botMagicCode) !== null && _props$webChatContain4 !== void 0 && _props$webChatContain4.disabled)) {
98
+ return;
99
+ }
100
+ if (!window.BroadcastChannel) {
101
+ // eslint-disable-line @typescript-eslint/no-explicit-any
102
+ TelemetryHelper.logActionEvent(LogLevel.ERROR, {
103
+ Event: TelemetryEvent.SuppressBotMagicCodeFailed,
104
+ Description: "BroadcastChannel not supported by default on current browser"
105
+ });
106
+ return;
107
+ }
108
+ const magicCodeBroadcastChannel = new window.BroadcastChannel(Constants.magicCodeBroadcastChannel); // eslint-disable-line @typescript-eslint/no-explicit-any
109
+ const magicCodeResponseBroadcastChannel = new window.BroadcastChannel(Constants.magicCodeResponseBroadcastChannel); // eslint-disable-line @typescript-eslint/no-explicit-any
110
+
98
111
  const eventListener = event => {
99
112
  // eslint-disable-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-empty-function
100
113
  const {
@@ -148,8 +161,8 @@ export const WebChatContainerStateful = props => {
148
161
  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.textWhiteSpace}}
149
162
 
150
163
  .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 {
151
- 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.webChatStyles) === null || _defaultWebChatContai === void 0 ? void 0 : _defaultWebChatContai.bubbleBackground)};
152
- 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.webChatStyles) === null || _defaultWebChatContai2 === void 0 ? void 0 : _defaultWebChatContai2.bubbleTextColor)};
164
+ 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.webChatStyles) === null || _defaultWebChatContai === void 0 ? void 0 : _defaultWebChatContai.bubbleBackground)};
165
+ 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.webChatStyles) === null || _defaultWebChatContai2 === void 0 ? void 0 : _defaultWebChatContai2.bubbleTextColor)};
153
166
  }
154
167
 
155
168
  div[class="ac-textBlock"] a:link,
@@ -157,11 +170,11 @@ export const WebChatContainerStateful = props => {
157
170
  div[class="ac-textBlock"] a:hover,
158
171
  div[class="ac-textBlock"] a:active {
159
172
  color: ${(webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : (_webChatContainerProp7 = webChatContainerProps.adaptiveCardStyles) === null || _webChatContainerProp7 === void 0 ? void 0 : _webChatContainerProp7.anchorColor) ?? defaultAdaptiveCardStyles.anchorColor};
160
- }
173
+ }
161
174
 
162
175
  .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.buttonWhiteSpace} !important;}
163
176
 
164
- .ms_lcw_webchat_received_message img.webchat__markdown__external-link-icon {
177
+ .ms_lcw_webchat_received_message img.webchat__markdown__external-link-icon {
165
178
  background-image : url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIzIDMgMTggMTgiICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik03LjI1MDEgNC41MDAxN0gxMC43NDk1QzExLjE2MzcgNC41MDAxNyAxMS40OTk1IDQuODM1OTYgMTEuNDk5NSA1LjI1MDE3QzExLjQ5OTUgNS42Mjk4NiAxMS4yMTczIDUuOTQzNjYgMTAuODUxMyA1Ljk5MzMyTDEwLjc0OTUgNi4wMDAxN0g3LjI0OTc0QzYuMDcwNzkgNS45OTk2MSA1LjEwMzQ5IDYuOTA2NTYgNS4wMDc4NiA4LjA2MTEyTDUuMDAwMjggOC4yMjAwM0w1LjAwMzEyIDE2Ljc1MDdDNS4wMDM0MyAxNy45NDE1IDUuOTI4ODUgMTguOTE2MSA3LjA5OTY2IDE4Ljk5NDlMNy4yNTM3MSAxOS4wMDAxTDE1Ljc1MTggMTguOTg4NEMxNi45NDE1IDE4Ljk4NjggMTcuOTE0NSAxOC4wNjIgMTcuOTkzNSAxNi44OTIzTDE3Ljk5ODcgMTYuNzM4NFYxMy4yMzIxQzE3Ljk5ODcgMTIuODE3OSAxOC4zMzQ1IDEyLjQ4MjEgMTguNzQ4NyAxMi40ODIxQzE5LjEyODQgMTIuNDgyMSAxOS40NDIyIDEyLjc2NDMgMTkuNDkxOCAxMy4xMzAzTDE5LjQ5ODcgMTMuMjMyMVYxNi43Mzg0QzE5LjQ5ODcgMTguNzQwNyAxNy45MjkzIDIwLjM3NjkgMTUuOTUyOCAyMC40ODI5TDE1Ljc1MzggMjAuNDg4NEw3LjI1ODI3IDIwLjUwMDFMNy4wNTQ5NSAyMC40OTQ5QzUuMTQyMzkgMjAuMzk1NCAzLjYwODk1IDE4Ljg2MjcgMy41MDgzNyAxNi45NTAyTDMuNTAzMTIgMTYuNzUxMUwzLjUwMDg5IDguMjUyN0wzLjUwNTI5IDguMDUwMkMzLjYwNTM5IDYuMTM3NDkgNS4xMzg2NyA0LjYwNDQ5IDcuMDUwOTYgNC41MDUyN0w3LjI1MDEgNC41MDAxN0gxMC43NDk1SDcuMjUwMVpNMTMuNzQ4MSAzLjAwMTQ2TDIwLjMwMTggMy4wMDE5N0wyMC40MDE0IDMuMDE1NzVMMjAuNTAyMiAzLjA0MzkzTDIwLjU1OSAzLjA2ODAzQzIwLjYxMjIgMy4wOTEyMiAyMC42NjM0IDMuMTIxNjMgMjAuNzExMSAzLjE1ODg1TDIwLjc4MDQgMy4yMjE1NkwyMC44NjQxIDMuMzIwMTRMMjAuOTE4MyAzLjQxMDI1TDIwLjk1NyAzLjUwMDU3TDIwLjk3NjIgMy41NjQ3NkwyMC45ODk4IDMuNjI4NjJMMjAuOTk5MiAzLjcyMjgyTDIwLjk5OTcgMTAuMjU1NEMyMC45OTk3IDEwLjY2OTYgMjAuNjYzOSAxMS4wMDU0IDIwLjI0OTcgMTEuMDA1NEMxOS44NyAxMS4wMDU0IDE5LjU1NjIgMTAuNzIzMiAxOS41MDY1IDEwLjM1NzFMMTkuNDk5NyAxMC4yNTU0TDE5LjQ5ODkgNS41NjE0N0wxMi4yNzk3IDEyLjc4NDdDMTIuMDEzNCAxMy4wNTEgMTEuNTk2OCAxMy4wNzUzIDExLjMwMzEgMTIuODU3NUwxMS4yMTkgMTIuNzg0OUMxMC45NTI3IDEyLjUxODcgMTAuOTI4NCAxMi4xMDIxIDExLjE0NjIgMTEuODA4NEwxMS4yMTg4IDExLjcyNDNMMTguNDM2OSA0LjUwMTQ2SDEzLjc0ODFDMTMuMzY4NCA0LjUwMTQ2IDEzLjA1NDYgNC4yMTkzMSAxMy4wMDUgMy44NTMyNEwxMi45OTgxIDMuNzUxNDZDMTIuOTk4MSAzLjM3MTc3IDEzLjI4MDMgMy4wNTc5NyAxMy42NDY0IDMuMDA4MzFMMTMuNzQ4MSAzLjAwMTQ2WiIgZmlsbD0iI0ZGRkZGRiIgLz48L3N2Zz4) !important;
166
179
  height: '.75em';
167
180
  marginLeft: '.25em';
@@ -179,7 +192,7 @@ export const WebChatContainerStateful = props => {
179
192
  .ms_lcw_webchat_received_message a:hover,
180
193
  .ms_lcw_webchat_received_message a:active {
181
194
  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 === null || defaultReceivedMessageAnchorStyles === void 0 ? void 0 : defaultReceivedMessageAnchorStyles.color)};
182
- }
195
+ }
183
196
  .ms_lcw_webchat_sent_message a:link,
184
197
  .ms_lcw_webchat_sent_message a:visited,
185
198
  .ms_lcw_webchat_sent_message a:hover,
@@ -26,5 +26,7 @@ export const defaultMiddlewareLocalizedTexts = {
26
26
  MIDDLEWARE_MESSAGE_RETRY: "Retry",
27
27
  MIDDLEWARE_BANNER_CHAT_DISCONNECT: "Your conversation has been disconnected. For additional assistance, please start a new chat.",
28
28
  THIRD_PARTY_COOKIES_BLOCKED_ALERT_MESSAGE: "Third party cookies are blocked. Reloading this page will start a new conversation.",
29
- MIDDLEWARE_BANNER_FILE_IS_MALICIOUS: "{0} has been blocked because the file may contain a malware."
29
+ MIDDLEWARE_BANNER_FILE_IS_MALICIOUS: "{0} has been blocked because the file may contain a malware.",
30
+ MIDDLEWARE_BANNER_FILE_EMAIL_ADDRESS_RECORDED_SUCCESS: "Email will be sent after chat ends!",
31
+ MIDDLEWARE_BANNER_FILE_EMAIL_ADDRESS_RECORDED_ERROR: "Email {0} could not be saved, try again later."
30
32
  };
@@ -3,6 +3,7 @@ export let NotificationScenarios;
3
3
  NotificationScenarios["Connection"] = "connection";
4
4
  NotificationScenarios["DownloadTranscriptError"] = "download transcript";
5
5
  NotificationScenarios["EmailTranscriptError"] = "email transcript";
6
+ NotificationScenarios["EmailAddressSaved"] = "email address saved";
6
7
  NotificationScenarios["AttachmentError"] = "attachment";
7
8
  NotificationScenarios["InternetConnection"] = "internet connection";
8
9
  NotificationScenarios["MaxSizeError"] = "max size";
@@ -33,3 +33,12 @@ export declare const debounceLeading: (fn: any, ms?: number) => (...args: any[])
33
33
  export declare const getConversationDetailsCall: (chatSDK: any) => Promise<any>;
34
34
  export declare const checkContactIdError: (e: any) => void;
35
35
  export declare const createFileAndDownload: (fileName: string, blobData: string, mimeType: string) => void;
36
+ /**
37
+ *
38
+ * Replace placeholders with format {0}..{n} , in a string with values
39
+ *
40
+ * @param template String with placeholders to be replaced
41
+ * @param values array of values to replace the placeholders
42
+ * @returns formatted string with replaced values
43
+ */
44
+ export declare const formatTemplateString: (templateMessage: string, values: any) => string;
@@ -4,6 +4,6 @@ import { ILiveChatWidgetContext } from "../../../contexts/common/ILiveChatWidget
4
4
  import { ILiveChatWidgetProps } from "../interfaces/ILiveChatWidgetProps";
5
5
  declare const initiatePostChat: (props: ILiveChatWidgetProps, conversationDetailsParam: any, state: ILiveChatWidgetContext, dispatch: Dispatch<ILiveChatWidgetAction>, postchatContext: any) => Promise<void>;
6
6
  declare const isPostChatEnabled: (props: ILiveChatWidgetProps, state: ILiveChatWidgetContext) => boolean;
7
- declare const getPostChatContext: (chatSDK: any, state: ILiveChatWidgetContext, dispatch: Dispatch<ILiveChatWidgetAction>) => Promise<void>;
7
+ declare const getPostChatContext: (chatSDK: any, state: ILiveChatWidgetContext, dispatch: Dispatch<ILiveChatWidgetAction>) => Promise<any>;
8
8
  declare const setWidgetStateToInactive: (dispatch: Dispatch<ILiveChatWidgetAction>) => Promise<void>;
9
9
  export { initiatePostChat, setWidgetStateToInactive, getPostChatContext, isPostChatEnabled as checkPostChatEnabled };
@@ -2,6 +2,7 @@ export declare enum NotificationScenarios {
2
2
  Connection = "connection",
3
3
  DownloadTranscriptError = "download transcript",
4
4
  EmailTranscriptError = "email transcript",
5
+ EmailAddressSaved = "email address saved",
5
6
  AttachmentError = "attachment",
6
7
  InternetConnection = "internet connection",
7
8
  MaxSizeError = "max size",
@@ -28,4 +28,13 @@ export interface ILiveChatWidgetLocalizedTexts {
28
28
  * e.g. "{0} has been blocked because the file may contain a malware."
29
29
  */
30
30
  MIDDLEWARE_BANNER_FILE_IS_MALICIOUS?: string;
31
+ /**
32
+ * Success message, indicating the email address introduced has been registered to receive the transcript.
33
+ */
34
+ MIDDLEWARE_BANNER_FILE_EMAIL_ADDRESS_RECORDED_SUCCESS?: string;
35
+ /**
36
+ * Error message, indicating the email address introduced couldnt be registered.
37
+ * {0} - e-mail address introduced
38
+ */
39
+ MIDDLEWARE_BANNER_FILE_EMAIL_ADDRESS_RECORDED_ERROR?: string;
31
40
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microsoft/omnichannel-chat-widget",
3
- "version": "1.4.1-main.9bf5e75",
3
+ "version": "1.4.1-main.d29da65",
4
4
  "description": "Microsoft Omnichannel Chat Widget",
5
5
  "main": "lib/cjs/index.js",
6
6
  "types": "lib/types/index.d.ts",
@@ -74,8 +74,8 @@
74
74
  "webpack-cli": "^4.9.2"
75
75
  },
76
76
  "dependencies": {
77
- "@microsoft/omnichannel-chat-components": "^1.0.8",
78
- "@microsoft/omnichannel-chat-sdk": "1.5.4",
77
+ "@microsoft/omnichannel-chat-components": "^1.0.9",
78
+ "@microsoft/omnichannel-chat-sdk": "1.5.5",
79
79
  "abort-controller-es5": "^2.0.1",
80
80
  "dompurify": "^2.3.4",
81
81
  "markdown-it": "^12.3.2",