@microsoft/omnichannel-chat-widget 1.0.2-main.b2301a3 → 1.0.3-main.05297ce

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 (26) hide show
  1. package/lib/cjs/common/telemetry/TelemetryConstants.js +2 -0
  2. package/lib/cjs/common/utils.js +2 -2
  3. package/lib/cjs/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +13 -7
  4. package/lib/cjs/components/livechatwidget/common/endChat.js +0 -4
  5. package/lib/cjs/components/livechatwidget/common/updateSessionDataForTelemetry.js +14 -0
  6. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +14 -12
  7. package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +3 -0
  8. package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +13 -6
  9. package/lib/cjs/components/webchatcontainerstateful/common/mockchatsdk.js +3 -1
  10. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentUploadValidatorMiddleware.js +27 -13
  11. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/dataMaskingMiddleware.js +25 -12
  12. package/lib/esm/common/telemetry/TelemetryConstants.js +2 -0
  13. package/lib/esm/common/utils.js +2 -2
  14. package/lib/esm/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +13 -7
  15. package/lib/esm/components/livechatwidget/common/endChat.js +0 -4
  16. package/lib/esm/components/livechatwidget/common/updateSessionDataForTelemetry.js +14 -0
  17. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +15 -13
  18. package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +3 -0
  19. package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +13 -6
  20. package/lib/esm/components/webchatcontainerstateful/common/mockchatsdk.js +3 -1
  21. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentUploadValidatorMiddleware.js +27 -13
  22. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/dataMaskingMiddleware.js +25 -12
  23. package/lib/types/common/telemetry/TelemetryConstants.d.ts +3 -1
  24. package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetProps.d.ts +1 -0
  25. package/lib/types/components/webchatcontainerstateful/common/mockchatsdk.d.ts +3 -1
  26. package/package.json +3 -3
@@ -60,6 +60,8 @@ exports.BroadcastEvent = BroadcastEvent;
60
60
  BroadcastEvent["BotAuthConfigRequest"] = "BotAuthConfigRequest";
61
61
  BroadcastEvent["BotAuthConfigResponse"] = "BotAuthConfigResponse";
62
62
  BroadcastEvent["HideChatVisibilityChangeEvent"] = "hideChatVisibilityChangeEvent";
63
+ BroadcastEvent["UpdateSessionDataForTelemetry"] = "UpdateSessionDataForTelemetry";
64
+ BroadcastEvent["UpdateConversationDataForTelemetry"] = "UpdateConversationDataForTelemetry";
63
65
  })(BroadcastEvent || (exports.BroadcastEvent = BroadcastEvent = {}));
64
66
  let TelemetryEvent;
65
67
  exports.TelemetryEvent = TelemetryEvent;
@@ -5,9 +5,9 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.setTabIndices = exports.setFocusOnSendBox = exports.setFocusOnElement = exports.preventFocusToMoveOutOfElement = exports.parseAdaptiveCardPayload = exports.newGuid = exports.isUndefinedOrEmpty = exports.isNullOrUndefined = exports.isNullOrEmptyString = exports.getWidgetEndChatEventName = 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.changeLanguageCodeFormatForWebChat = exports.addDelayInMs = void 0;
7
7
  var _Constants = require("./Constants");
8
+ var _TelemetryConstants = require("./telemetry/TelemetryConstants");
8
9
  var _DataStoreManager = require("./contextDataStore/DataStoreManager");
9
10
  var _KeyCodes = require("./KeyCodes");
10
- var _TelemetryConstants = require("./telemetry/TelemetryConstants");
11
11
  var _md5Typescript = require("md5-typescript");
12
12
  var _TelemetryHelper = require("./telemetry/TelemetryHelper");
13
13
  var _this = void 0;
@@ -171,7 +171,7 @@ exports.getTimestampHourMinute = getTimestampHourMinute;
171
171
  const parseAdaptiveCardPayload = (payload, requiredFieldMissingMessage) => {
172
172
  if (payload && payload !== "{}") {
173
173
  try {
174
- const parsedPayload = JSON.parse(payload.replace(/*/g, "*"));
174
+ const parsedPayload = JSON.parse(payload.replace("*", "*"));
175
175
  const body = parsedPayload.body;
176
176
  if (body) {
177
177
  //Parse ID field into available options and add required error messages
@@ -817,7 +817,7 @@ const dummyDefaultProps = {
817
817
  minHeight: "25px",
818
818
  width: "100%",
819
819
  minWidth: "250px",
820
- padding: "0 10px 5px 10px"
820
+ padding: "5px"
821
821
  },
822
822
  downloadTranscriptButtonStyleProps: {
823
823
  icon: {
@@ -1756,13 +1756,19 @@ const dummyDefaultProps = {
1756
1756
  }
1757
1757
  },
1758
1758
  localizedTexts: {
1759
+ /*
1760
+ MIDDLEWARE_BANNER_FILE parameters:
1761
+ {0} = File limit size
1762
+ {1} = File extension
1763
+ {2} = File name
1764
+ */
1759
1765
  MIDDLEWARE_BANNER_FILE_NULL_ERROR: "There was an error uploading the file, please try again.",
1760
- MIDDLEWARE_BANNER_FILE_SIZE_WITHOUT_EXTENSION_ERROR: "File exceeds the allowed limit of {0} MB and please upload the file with an appropriate file extension.",
1761
- MIDDLEWARE_BANNER_FILE_SIZE_EXTENSION_ERROR: "File exceeds the allowed limit of {0} MB and {1} files are not supported.",
1762
- MIDDLEWARE_BANNER_FILE_WITHOUT_EXTENSION: "File upload error. Please upload the file with an appropriate file extension.",
1763
- MIDDLEWARE_BANNER_FILE_EXTENSION_ERROR: "{0} files are not supported.",
1764
- MIDDLEWARE_BANNER_FILE_SIZE_ERROR: "File exceeds the allowed limit of {0} MB.",
1765
- MIDDLEWARE_BANNER_FILE_IS_EMPTY_ERROR: "This file can't be attached because it's empty. Please try again with a different file.",
1766
+ MIDDLEWARE_BANNER_FILE_SIZE_WITHOUT_EXTENSION_ERROR: "File {2} exceeds the allowed limit of {0} MB and please upload the file with an appropriate file extension.",
1767
+ MIDDLEWARE_BANNER_FILE_SIZE_EXTENSION_ERROR: "File {2} exceeds the allowed limit of {0} MB and {1} files are not supported.",
1768
+ MIDDLEWARE_BANNER_FILE_WITHOUT_EXTENSION: "File upload error. Please upload the file {2} with an appropriate file extension.",
1769
+ MIDDLEWARE_BANNER_FILE_EXTENSION_ERROR: "{1} files are not supported.",
1770
+ MIDDLEWARE_BANNER_FILE_SIZE_ERROR: "File {2} exceeds the allowed limit of {0} MB.",
1771
+ MIDDLEWARE_BANNER_FILE_IS_EMPTY_ERROR: "This file {2} can't be attached because it's empty. Please try again with a different file.",
1766
1772
  MIDDLEWARE_BANNER_ERROR_MESSAGE: "Upload failed, please try again.",
1767
1773
  MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE: "You're back online.",
1768
1774
  MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION: "Unable to connect—please check your internet connection.",
@@ -77,10 +77,6 @@ const endChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, a
77
77
  }
78
78
  }
79
79
  // Need to clear these states immediately when chat ended from OC.
80
- dispatch({
81
- type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CUSTOM_CONTEXT,
82
- payload: undefined
83
- });
84
80
  dispatch({
85
81
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CHAT_TOKEN,
86
82
  payload: undefined
@@ -4,6 +4,8 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.updateSessionDataForTelemetry = void 0;
7
+ var _TelemetryConstants = require("../../../common/telemetry/TelemetryConstants");
8
+ var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components");
7
9
  var _LiveChatWidgetActionType = require("../../../contexts/common/LiveChatWidgetActionType");
8
10
  var _TelemetryHelper = require("../../../common/telemetry/TelemetryHelper");
9
11
  var _TelemetryManager = require("../../../common/telemetry/TelemetryManager");
@@ -17,6 +19,12 @@ const updateSessionDataForTelemetry = async (chatSDK, dispatch) => {
17
19
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_TELEMETRY_DATA,
18
20
  payload: telemetryData
19
21
  });
22
+ _omnichannelChatComponents.BroadcastService.postMessage({
23
+ eventName: _TelemetryConstants.BroadcastEvent.UpdateSessionDataForTelemetry,
24
+ payload: {
25
+ chatSession
26
+ }
27
+ });
20
28
  await updateConversationDataForTelemetry(chatSDK, dispatch);
21
29
  }
22
30
  };
@@ -32,5 +40,11 @@ const updateConversationDataForTelemetry = async (chatSDK, dispatch) => {
32
40
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_TELEMETRY_DATA,
33
41
  payload: telemetryData
34
42
  });
43
+ _omnichannelChatComponents.BroadcastService.postMessage({
44
+ eventName: _TelemetryConstants.BroadcastEvent.UpdateConversationDataForTelemetry,
45
+ payload: {
46
+ liveWorkItem
47
+ }
48
+ });
35
49
  }
36
50
  };
@@ -6,20 +6,22 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = exports.LiveChatWidgetStateful = void 0;
7
7
  var _TelemetryConstants = require("../../../common/telemetry/TelemetryConstants");
8
8
  var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components");
9
+ var _Constants = require("../../../common/Constants");
9
10
  var _react = require("@fluentui/react");
10
11
  var _react2 = _interopRequireWildcard(require("react"));
11
12
  var _startChat = require("../common/startChat");
12
13
  var _utils = require("../../../common/utils");
13
14
  var _endChat = require("../common/endChat");
15
+ var _reconnectChatHelper = require("../common/reconnectChatHelper");
14
16
  var _componentController = require("../../../controller/componentController");
15
17
  var _ActivityStreamHandler = require("../common/ActivityStreamHandler");
16
18
  var _CallingContainerStateful = _interopRequireDefault(require("../../callingcontainerstateful/CallingContainerStateful"));
17
19
  var _ChatButtonStateful = _interopRequireDefault(require("../../chatbuttonstateful/ChatButtonStateful"));
18
20
  var _botframeworkWebchat = require("botframework-webchat");
19
21
  var _ConfirmationPaneStateful = _interopRequireDefault(require("../../confirmationpanestateful/ConfirmationPaneStateful"));
22
+ var _ConversationEndEntity = require("../../../contexts/common/ConversationEndEntity");
20
23
  var _ConversationState = require("../../../contexts/common/ConversationState");
21
24
  var _DataStoreManager = require("../../../common/contextDataStore/DataStoreManager");
22
- var _Constants = require("../../../common/Constants");
23
25
  var _EmailTranscriptPaneStateful = _interopRequireDefault(require("../../emailtranscriptpanestateful/EmailTranscriptPaneStateful"));
24
26
  var _HeaderStateful = _interopRequireDefault(require("../../headerstateful/HeaderStateful"));
25
27
  var _LiveChatWidgetActionType = require("../../../contexts/common/LiveChatWidgetActionType");
@@ -40,6 +42,8 @@ var _defaultScrollBarProps = require("../common/defaultProps/defaultScrollBarPro
40
42
  var _defaultWebChatContainerStatefulProps = require("../../webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps");
41
43
  var _disposeTelemetryLoggers = require("../common/disposeTelemetryLoggers");
42
44
  var _getGeneralStylesForButton = require("../common/getGeneralStylesForButton");
45
+ var _agentEndConversationHelper = require("../common/agentEndConversationHelper");
46
+ var _chatDisconnectHelper = require("../common/chatDisconnectHelper");
43
47
  var _initCallingSdk = require("../common/initCallingSdk");
44
48
  var _initConfirmationPropsComposer = require("../common/initConfirmationPropsComposer");
45
49
  var _initWebChatComposer = require("../common/initWebChatComposer");
@@ -50,10 +54,6 @@ var _startProactiveChat = require("../common/startProactiveChat");
50
54
  var _useChatAdapterStore = _interopRequireDefault(require("../../../hooks/useChatAdapterStore"));
51
55
  var _useChatContextStore = _interopRequireDefault(require("../../../hooks/useChatContextStore"));
52
56
  var _useChatSDKStore = _interopRequireDefault(require("../../../hooks/useChatSDKStore"));
53
- var _ConversationEndEntity = require("../../../contexts/common/ConversationEndEntity");
54
- var _agentEndConversationHelper = require("../common/agentEndConversationHelper");
55
- var _reconnectChatHelper = require("../common/reconnectChatHelper");
56
- var _chatDisconnectHelper = require("../common/chatDisconnectHelper");
57
57
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
58
58
  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); }
59
59
  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; }
@@ -198,6 +198,12 @@ const LiveChatWidgetStateful = props => {
198
198
  });
199
199
  });
200
200
  }
201
+ if (props.initialCustomContext) {
202
+ dispatch({
203
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CUSTOM_CONTEXT,
204
+ payload: props.initialCustomContext
205
+ });
206
+ }
201
207
 
202
208
  // Initialize global dir
203
209
  const globalDir = ((_props$controlProps9 = props.controlProps) === null || _props$controlProps9 === void 0 ? void 0 : _props$controlProps9.dir) ?? (0, _utils.getLocaleDirection)((_props$chatConfig2 = props.chatConfig) === null || _props$chatConfig2 === void 0 ? void 0 : (_props$chatConfig2$Ch = _props$chatConfig2.ChatWidgetLanguage) === null || _props$chatConfig2$Ch === void 0 ? void 0 : _props$chatConfig2$Ch.msdyn_localeid);
@@ -258,16 +264,12 @@ const LiveChatWidgetStateful = props => {
258
264
  _omnichannelChatComponents.BroadcastService.getMessageByEventName(_TelemetryConstants.BroadcastEvent.HideChatVisibilityChangeEvent).subscribe(async event => {
259
265
  var _event$payload;
260
266
  if ((event === null || event === void 0 ? void 0 : (_event$payload = event.payload) === null || _event$payload === void 0 ? void 0 : _event$payload.isChatHidden) !== undefined) {
261
- var _event$payload2, _props$controlProps10;
262
- _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
263
- Event: _TelemetryConstants.TelemetryEvent.ChatVisibilityChanged,
264
- Description: "Chat visibility changed to " + (event === null || event === void 0 ? void 0 : (_event$payload2 = event.payload) === null || _event$payload2 === void 0 ? void 0 : _event$payload2.isChatHidden)
265
- });
267
+ var _props$controlProps10;
266
268
  if ((_props$controlProps10 = props.controlProps) !== null && _props$controlProps10 !== void 0 && _props$controlProps10.hideStartChatButton) {
267
- var _event$payload3;
269
+ var _event$payload2;
268
270
  dispatch({
269
271
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_MINIMIZED,
270
- payload: event === null || event === void 0 ? void 0 : (_event$payload3 = event.payload) === null || _event$payload3 === void 0 ? void 0 : _event$payload3.isChatHidden
272
+ payload: event === null || event === void 0 ? void 0 : (_event$payload2 = event.payload) === null || _event$payload2 === void 0 ? void 0 : _event$payload2.isChatHidden
271
273
  });
272
274
  }
273
275
  const dateNow = Date.now();
@@ -7,6 +7,7 @@ exports.default = exports.PreChatSurveyPaneStateful = void 0;
7
7
  var _Constants = require("../../common/Constants");
8
8
  var _TelemetryConstants = require("../../common/telemetry/TelemetryConstants");
9
9
  var _react = _interopRequireWildcard(require("react"));
10
+ var _markdownIt = _interopRequireDefault(require("markdown-it"));
10
11
  var _utils = require("../../common/utils");
11
12
  var _ConversationState = require("../../contexts/common/ConversationState");
12
13
  var _LiveChatWidgetActionType = require("../../contexts/common/LiveChatWidgetActionType");
@@ -21,6 +22,8 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
21
22
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
23
  const PreChatSurveyPaneStateful = props => {
23
24
  var _surveyProps$stylePro, _props$surveyProps, _props$surveyProps$co;
25
+ // Set MarkDown global variable to be used for prechat adaptive cards
26
+ window["markdownit"] = _markdownIt.default;
24
27
  const [state, dispatch] = (0, _useChatContextStore.default)();
25
28
  const {
26
29
  surveyProps,
@@ -4,14 +4,21 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.defaultMiddlewareLocalizedTexts = void 0;
7
+ /*
8
+ MIDDLEWARE_BANNER_FILE parameters:
9
+ {0} = File limit size
10
+ {1} = File extension
11
+ {2} = File name
12
+ */
13
+
7
14
  const defaultMiddlewareLocalizedTexts = {
8
15
  MIDDLEWARE_BANNER_FILE_NULL_ERROR: "There was an error uploading the file, please try again.",
9
- MIDDLEWARE_BANNER_FILE_SIZE_WITHOUT_EXTENSION_ERROR: "File exceeds the allowed limit of {0} MB and please upload the file with an appropriate file extension.",
10
- MIDDLEWARE_BANNER_FILE_SIZE_EXTENSION_ERROR: "File exceeds the allowed limit of {0} MB and {1} files are not supported.",
11
- MIDDLEWARE_BANNER_FILE_WITHOUT_EXTENSION: "File upload error. Please upload the file with an appropriate file extension.",
12
- MIDDLEWARE_BANNER_FILE_EXTENSION_ERROR: "{0} files are not supported.",
13
- MIDDLEWARE_BANNER_FILE_SIZE_ERROR: "File exceeds the allowed limit of {0} MB.",
14
- MIDDLEWARE_BANNER_FILE_IS_EMPTY_ERROR: "This file can't be attached because it's empty. Please try again with a different file.",
16
+ MIDDLEWARE_BANNER_FILE_SIZE_WITHOUT_EXTENSION_ERROR: "File {2} exceeds the allowed limit of {0} MB and please upload the file with an appropriate file extension.",
17
+ MIDDLEWARE_BANNER_FILE_SIZE_EXTENSION_ERROR: "File {2} exceeds the allowed limit of {0} MB and {1} files are not supported.",
18
+ MIDDLEWARE_BANNER_FILE_WITHOUT_EXTENSION: "File upload error. Please upload the file {2} with an appropriate file extension.",
19
+ MIDDLEWARE_BANNER_FILE_EXTENSION_ERROR: "{1} files are not supported.",
20
+ MIDDLEWARE_BANNER_FILE_SIZE_ERROR: "File {2} exceeds the allowed limit of {0} MB.",
21
+ MIDDLEWARE_BANNER_FILE_IS_EMPTY_ERROR: "This file {2} can't be attached because it's empty. Please try again with a different file.",
15
22
  MIDDLEWARE_BANNER_ERROR_MESSAGE: "Upload failed, please try again.",
16
23
  MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE: "You’re back online.",
17
24
  MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION: "Unable to connect—please check your internet connection.",
@@ -32,7 +32,9 @@ class MockChatSDK {
32
32
  return "";
33
33
  }
34
34
  getConversationDetails() {
35
- return {};
35
+ return {
36
+ State: "Active"
37
+ };
36
38
  }
37
39
  getCurrentLiveChatContext() {
38
40
  return {
@@ -76,6 +76,11 @@ const getMaxUploadFileSize = (maxFileSizeSupportedByDynamicsStr, contentType) =>
76
76
  const isImage = contentType => {
77
77
  return _Constants.AMSConstants.supportedImagesMimeTypes.includes(contentType);
78
78
  };
79
+ const textEllipsis = function (str) {
80
+ let maxLength = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 20;
81
+ const ellipsis = "...";
82
+ return str.length > maxLength ? str.slice(0, maxLength - ellipsis.length) + ellipsis : str;
83
+ };
79
84
  const buildErrorMessage = (fileName, supportedFileExtension, supportedFileSize, fileIsEmpty, maxUploadFileSize, maxFileSizeSupportedByDynamics, localizedTexts) => {
80
85
  let errorMessage = "";
81
86
  if (!fileName || !maxUploadFileSize) {
@@ -91,10 +96,11 @@ const buildErrorMessage = (fileName, supportedFileExtension, supportedFileSize,
91
96
  if (!supportedFileExtension && !supportedFileSize) {
92
97
  errorMessage = getFileSizeAndFileExtensionErrorMessage(fileName, maxUploadFileSize, maxFileSizeSupportedByDynamics, localizedTexts);
93
98
  } else if (!supportedFileSize) {
94
- errorMessage = getFileSizeErrorMessage(maxUploadFileSize, maxFileSizeSupportedByDynamics, localizedTexts);
99
+ errorMessage = getFileSizeErrorMessage(fileName, maxUploadFileSize, maxFileSizeSupportedByDynamics, localizedTexts);
95
100
  } else if (!supportedFileExtension) {
96
101
  errorMessage = getFileExtensionErrorMessage(fileName, localizedTexts);
97
102
  } else if (fileIsEmpty) {
103
+ var _errorMessage;
98
104
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
99
105
  Event: _TelemetryConstants.TelemetryEvent.AttachmentUploadValidatorMiddlewareFailed,
100
106
  Description: "Attachment validation failed",
@@ -102,7 +108,8 @@ const buildErrorMessage = (fileName, supportedFileExtension, supportedFileSize,
102
108
  ErrorDetails: "File provided is empty"
103
109
  }
104
110
  });
105
- errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_IS_EMPTY_ERROR ?? "";
111
+ errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_IS_EMPTY_ERROR || "";
112
+ if ((_errorMessage = errorMessage) !== null && _errorMessage !== void 0 && _errorMessage.includes("{2}")) errorMessage = errorMessage.replace("{2}", textEllipsis(fileName));
106
113
  } else {
107
114
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
108
115
  Event: _TelemetryConstants.TelemetryEvent.AttachmentUploadValidatorMiddlewareFailed,
@@ -116,19 +123,18 @@ const buildErrorMessage = (fileName, supportedFileExtension, supportedFileSize,
116
123
  return errorMessage;
117
124
  };
118
125
  const getFileSizeAndFileExtensionErrorMessage = (fileName, maxUploadFileSize, maxFileSizeSupportedByDynamics, localizedTexts) => {
126
+ var _errorMessage3;
119
127
  const index = fileName.lastIndexOf(".");
120
128
  let errorMessage, exceptionDetails;
121
129
  if (index < 0) {
122
130
  errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_SIZE_WITHOUT_EXTENSION_ERROR;
123
131
  exceptionDetails = `File exceeded the allowed limit of ${maxUploadFileSize} MB and File provided without file extension`;
124
132
  } else {
125
- var _errorMessage;
133
+ var _errorMessage2;
126
134
  const fileExtension = fileName.substring(index);
127
135
  errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_SIZE_EXTENSION_ERROR;
136
+ if ((_errorMessage2 = errorMessage) !== null && _errorMessage2 !== void 0 && _errorMessage2.includes("{1}")) errorMessage = errorMessage.replace("{1}", fileExtension);
128
137
  exceptionDetails = `File exceeds the allowed limit of ${maxUploadFileSize} MB and ${fileExtension} files are not supported`;
129
- if ((_errorMessage = errorMessage) !== null && _errorMessage !== void 0 && _errorMessage.includes("{1}")) {
130
- errorMessage = errorMessage.replace("{1}", fileExtension);
131
- }
132
138
  }
133
139
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
134
140
  Event: _TelemetryConstants.TelemetryEvent.AttachmentUploadValidatorMiddlewareFailed,
@@ -137,10 +143,12 @@ const getFileSizeAndFileExtensionErrorMessage = (fileName, maxUploadFileSize, ma
137
143
  ErrorDetails: `${exceptionDetails} Dynamics file size limit=${maxFileSizeSupportedByDynamics} AMS image size limit=${_Constants.AMSConstants.maxSupportedImageSize} AMS file size limit=${_Constants.AMSConstants.maxSupportedFileSize}`
138
144
  }
139
145
  });
140
- return errorMessage ? errorMessage.includes("{0}") ? errorMessage.replace("{0}", maxUploadFileSize) : errorMessage : "";
146
+ if ((_errorMessage3 = errorMessage) !== null && _errorMessage3 !== void 0 && _errorMessage3.includes("{0}")) errorMessage = errorMessage.replace("{0}", maxUploadFileSize);
147
+ return errorMessage ? errorMessage.includes("{2}") ? errorMessage.replace("{2}", textEllipsis(fileName)) : errorMessage : "";
141
148
  };
142
149
  const getFileExtensionErrorMessage = (fileName, localizedTexts) => {
143
150
  const index = fileName.lastIndexOf(".");
151
+ let errorMessage;
144
152
  if (index < 0) {
145
153
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
146
154
  Event: _TelemetryConstants.TelemetryEvent.AttachmentUploadValidatorMiddlewareFailed,
@@ -149,8 +157,10 @@ const getFileExtensionErrorMessage = (fileName, localizedTexts) => {
149
157
  ErrorDetails: "File provided without file extension"
150
158
  }
151
159
  });
152
- return localizedTexts.MIDDLEWARE_BANNER_FILE_WITHOUT_EXTENSION ?? "";
160
+ errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_WITHOUT_EXTENSION;
161
+ return errorMessage ? errorMessage.includes("{2}") ? errorMessage.replace("{2}", textEllipsis(fileName)) : errorMessage : "";
153
162
  } else {
163
+ var _errorMessage4, _errorMessage5;
154
164
  const fileExtension = fileName.substring(index);
155
165
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
156
166
  Event: _TelemetryConstants.TelemetryEvent.AttachmentUploadValidatorMiddlewareFailed,
@@ -159,11 +169,14 @@ const getFileExtensionErrorMessage = (fileName, localizedTexts) => {
159
169
  ErrorDetails: `${fileExtension} files extension is not supported.`
160
170
  }
161
171
  });
162
- const errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_EXTENSION_ERROR;
163
- return errorMessage ? errorMessage.includes("{0}") ? errorMessage.replace("{0}", fileExtension) : errorMessage : "";
172
+ errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_EXTENSION_ERROR;
173
+ if ((_errorMessage4 = errorMessage) !== null && _errorMessage4 !== void 0 && _errorMessage4.includes("{0}")) errorMessage = errorMessage.replace("{0}", fileExtension); //keeping backwards compatibility for this localized string
174
+ if ((_errorMessage5 = errorMessage) !== null && _errorMessage5 !== void 0 && _errorMessage5.includes("{1}")) errorMessage = errorMessage.replace("{1}", fileExtension);
175
+ return errorMessage && errorMessage.length > 0 ? errorMessage : "";
164
176
  }
165
177
  };
166
- const getFileSizeErrorMessage = (maxUploadFileSize, maxFileSizeSupportedByDynamics, localizedTexts) => {
178
+ const getFileSizeErrorMessage = (fileName, maxUploadFileSize, maxFileSizeSupportedByDynamics, localizedTexts) => {
179
+ var _errorMessage6;
167
180
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
168
181
  Event: _TelemetryConstants.TelemetryEvent.AttachmentUploadValidatorMiddlewareFailed,
169
182
  Description: "Attachment validation failed",
@@ -171,8 +184,9 @@ const getFileSizeErrorMessage = (maxUploadFileSize, maxFileSizeSupportedByDynami
171
184
  ErrorDetails: `File exceeds the allowed limit of ${maxUploadFileSize}MB. Dynamics file size limit=${maxFileSizeSupportedByDynamics} AMS image size limit=${_Constants.AMSConstants.maxSupportedImageSize} AMS file size limit=${_Constants.AMSConstants.maxSupportedFileSize}`
172
185
  }
173
186
  });
174
- const errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_SIZE_ERROR;
175
- return errorMessage ? errorMessage.includes("{0}") ? errorMessage.replace("{0}", maxUploadFileSize) : errorMessage : "";
187
+ let errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_SIZE_ERROR;
188
+ if ((_errorMessage6 = errorMessage) !== null && _errorMessage6 !== void 0 && _errorMessage6.includes("{0}")) errorMessage = errorMessage.replace("{0}", maxUploadFileSize);
189
+ return errorMessage ? errorMessage.includes("{2}") ? errorMessage.replace("{2}", textEllipsis(fileName)) : errorMessage : "";
176
190
  };
177
191
 
178
192
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
@@ -28,22 +28,25 @@ const applyDataMasking = (action, regexCollection) => {
28
28
  });
29
29
  return action;
30
30
  }
31
- let isRuleMatched = false;
32
31
  for (const ruleId of Object.keys(regexCollection)) {
33
32
  const item = regexCollection[ruleId];
34
33
  if (item) {
34
+ let ruleInfiniteException = false;
35
+ let ruleApplied = false;
35
36
  try {
36
37
  const regex = new RegExp(item, "gi");
37
38
  let match;
38
39
  // eslint-disable-next-line no-cond-assign
39
40
  while (match = regex.exec(text)) {
40
41
  const replaceStr = match[0].replace(/./gi, maskedChar);
41
- text = text.replace(match[0], replaceStr);
42
- _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
43
- Event: _TelemetryConstants.TelemetryEvent.DataMaskingRuleApplied,
44
- Description: `Data Masking Rule Id: ${ruleId} applied.`
45
- });
46
- isRuleMatched = true;
42
+ const modifiedText = text.replace(match[0], replaceStr);
43
+ if (modifiedText == text) {
44
+ ruleInfiniteException = true;
45
+ console.warn(`The data masking rule ${item} is ignored because it matches empty strings. Please modify this rule.`);
46
+ break;
47
+ }
48
+ ruleApplied = true;
49
+ text = modifiedText;
47
50
  }
48
51
  } catch (err) {
49
52
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
@@ -54,11 +57,21 @@ const applyDataMasking = (action, regexCollection) => {
54
57
  }
55
58
  });
56
59
  }
57
- }
58
-
59
- // Exit if rule matched
60
- if (isRuleMatched === true) {
61
- break;
60
+ if (ruleApplied) {
61
+ _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
62
+ Event: _TelemetryConstants.TelemetryEvent.DataMaskingRuleApplied,
63
+ Description: `Data Masking Rule Id: ${ruleId} applied.`
64
+ });
65
+ }
66
+ if (ruleInfiniteException) {
67
+ _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
68
+ Event: _TelemetryConstants.TelemetryEvent.DataMaskingRuleApplyFailed,
69
+ ExceptionDetails: {
70
+ RuleId: ruleId,
71
+ Exception: "The data masking rule matches empty strings."
72
+ }
73
+ });
74
+ }
62
75
  }
63
76
  }
64
77
  action.payload.text = text;
@@ -55,6 +55,8 @@ export let BroadcastEvent;
55
55
  BroadcastEvent["BotAuthConfigRequest"] = "BotAuthConfigRequest";
56
56
  BroadcastEvent["BotAuthConfigResponse"] = "BotAuthConfigResponse";
57
57
  BroadcastEvent["HideChatVisibilityChangeEvent"] = "hideChatVisibilityChangeEvent";
58
+ BroadcastEvent["UpdateSessionDataForTelemetry"] = "UpdateSessionDataForTelemetry";
59
+ BroadcastEvent["UpdateConversationDataForTelemetry"] = "UpdateConversationDataForTelemetry";
58
60
  })(BroadcastEvent || (BroadcastEvent = {}));
59
61
  export let TelemetryEvent;
60
62
  (function (TelemetryEvent) {
@@ -1,8 +1,8 @@
1
1
  var _this = this;
2
2
  import { AriaTelemetryConstants, Constants, LocaleConstants } from "./Constants";
3
+ import { BroadcastEvent, LogLevel, TelemetryEvent } from "./telemetry/TelemetryConstants";
3
4
  import { DataStoreManager } from "./contextDataStore/DataStoreManager";
4
5
  import { KeyCodes } from "./KeyCodes";
5
- import { BroadcastEvent, LogLevel, TelemetryEvent } from "./telemetry/TelemetryConstants";
6
6
  import { Md5 } from "md5-typescript";
7
7
  import { TelemetryHelper } from "./telemetry/TelemetryHelper";
8
8
  const getElementBySelector = selector => {
@@ -154,7 +154,7 @@ export const getTimestampHourMinute = timestampStr => {
154
154
  export const parseAdaptiveCardPayload = (payload, requiredFieldMissingMessage) => {
155
155
  if (payload && payload !== "{}") {
156
156
  try {
157
- const parsedPayload = JSON.parse(payload.replace(/&#42;/g, "*"));
157
+ const parsedPayload = JSON.parse(payload.replace("*", "&#42;"));
158
158
  const body = parsedPayload.body;
159
159
  if (body) {
160
160
  //Parse ID field into available options and add required error messages
@@ -811,7 +811,7 @@ export const dummyDefaultProps = {
811
811
  minHeight: "25px",
812
812
  width: "100%",
813
813
  minWidth: "250px",
814
- padding: "0 10px 5px 10px"
814
+ padding: "5px"
815
815
  },
816
816
  downloadTranscriptButtonStyleProps: {
817
817
  icon: {
@@ -1750,13 +1750,19 @@ export const dummyDefaultProps = {
1750
1750
  }
1751
1751
  },
1752
1752
  localizedTexts: {
1753
+ /*
1754
+ MIDDLEWARE_BANNER_FILE parameters:
1755
+ {0} = File limit size
1756
+ {1} = File extension
1757
+ {2} = File name
1758
+ */
1753
1759
  MIDDLEWARE_BANNER_FILE_NULL_ERROR: "There was an error uploading the file, please try again.",
1754
- MIDDLEWARE_BANNER_FILE_SIZE_WITHOUT_EXTENSION_ERROR: "File exceeds the allowed limit of {0} MB and please upload the file with an appropriate file extension.",
1755
- MIDDLEWARE_BANNER_FILE_SIZE_EXTENSION_ERROR: "File exceeds the allowed limit of {0} MB and {1} files are not supported.",
1756
- MIDDLEWARE_BANNER_FILE_WITHOUT_EXTENSION: "File upload error. Please upload the file with an appropriate file extension.",
1757
- MIDDLEWARE_BANNER_FILE_EXTENSION_ERROR: "{0} files are not supported.",
1758
- MIDDLEWARE_BANNER_FILE_SIZE_ERROR: "File exceeds the allowed limit of {0} MB.",
1759
- MIDDLEWARE_BANNER_FILE_IS_EMPTY_ERROR: "This file can't be attached because it's empty. Please try again with a different file.",
1760
+ MIDDLEWARE_BANNER_FILE_SIZE_WITHOUT_EXTENSION_ERROR: "File {2} exceeds the allowed limit of {0} MB and please upload the file with an appropriate file extension.",
1761
+ MIDDLEWARE_BANNER_FILE_SIZE_EXTENSION_ERROR: "File {2} exceeds the allowed limit of {0} MB and {1} files are not supported.",
1762
+ MIDDLEWARE_BANNER_FILE_WITHOUT_EXTENSION: "File upload error. Please upload the file {2} with an appropriate file extension.",
1763
+ MIDDLEWARE_BANNER_FILE_EXTENSION_ERROR: "{1} files are not supported.",
1764
+ MIDDLEWARE_BANNER_FILE_SIZE_ERROR: "File {2} exceeds the allowed limit of {0} MB.",
1765
+ MIDDLEWARE_BANNER_FILE_IS_EMPTY_ERROR: "This file {2} can't be attached because it's empty. Please try again with a different file.",
1760
1766
  MIDDLEWARE_BANNER_ERROR_MESSAGE: "Upload failed, please try again.",
1761
1767
  MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE: "You're back online.",
1762
1768
  MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION: "Unable to connect—please check your internet connection.",
@@ -71,10 +71,6 @@ const endChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, a
71
71
  }
72
72
  }
73
73
  // Need to clear these states immediately when chat ended from OC.
74
- dispatch({
75
- type: LiveChatWidgetActionType.SET_CUSTOM_CONTEXT,
76
- payload: undefined
77
- });
78
74
  dispatch({
79
75
  type: LiveChatWidgetActionType.SET_CHAT_TOKEN,
80
76
  payload: undefined
@@ -1,3 +1,5 @@
1
+ import { BroadcastEvent } from "../../../common/telemetry/TelemetryConstants";
2
+ import { BroadcastService } from "@microsoft/omnichannel-chat-components";
1
3
  import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
2
4
  import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
3
5
  import { TelemetryManager } from "../../../common/telemetry/TelemetryManager";
@@ -12,6 +14,12 @@ export const updateSessionDataForTelemetry = async (chatSDK, dispatch) => {
12
14
  type: LiveChatWidgetActionType.SET_TELEMETRY_DATA,
13
15
  payload: telemetryData
14
16
  });
17
+ BroadcastService.postMessage({
18
+ eventName: BroadcastEvent.UpdateSessionDataForTelemetry,
19
+ payload: {
20
+ chatSession
21
+ }
22
+ });
15
23
  await updateConversationDataForTelemetry(chatSDK, dispatch);
16
24
  }
17
25
  };
@@ -26,5 +34,11 @@ const updateConversationDataForTelemetry = async (chatSDK, dispatch) => {
26
34
  type: LiveChatWidgetActionType.SET_TELEMETRY_DATA,
27
35
  payload: telemetryData
28
36
  });
37
+ BroadcastService.postMessage({
38
+ eventName: BroadcastEvent.UpdateConversationDataForTelemetry,
39
+ payload: {
40
+ liveWorkItem
41
+ }
42
+ });
29
43
  }
30
44
  };
@@ -1,20 +1,22 @@
1
1
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
2
  import { BroadcastEvent, LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
3
3
  import { BroadcastService, BroadcastServiceInitialize, decodeComponentString } from "@microsoft/omnichannel-chat-components";
4
+ import { Constants, E2VVOptions, LiveWorkItemState } from "../../../common/Constants";
4
5
  import { Stack } from "@fluentui/react";
5
6
  import React, { useEffect, useRef, useState } from "react";
6
7
  import { checkIfConversationStillValid, initStartChat, prepareStartChat, setPreChatAndInitiateChat } from "../common/startChat";
7
- import { createTimer, getBroadcastChannelName, getLocaleDirection, getStateFromCache, getWidgetCacheId, getWidgetEndChatEventName, isNullOrEmptyString, isUndefinedOrEmpty, getConversationDetailsCall } from "../../../common/utils";
8
+ import { createTimer, getBroadcastChannelName, getConversationDetailsCall, getLocaleDirection, getStateFromCache, getWidgetCacheId, getWidgetEndChatEventName, isNullOrEmptyString, isUndefinedOrEmpty } from "../../../common/utils";
8
9
  import { endChat, prepareEndChat } from "../common/endChat";
10
+ import { handleChatReconnect, isReconnectEnabled } from "../common/reconnectChatHelper";
9
11
  import { shouldShowCallingContainer, shouldShowChatButton, shouldShowConfirmationPane, shouldShowEmailTranscriptPane, shouldShowHeader, shouldShowLoadingPane, shouldShowOutOfOfficeHoursPane, shouldShowPostChatLoadingPane, shouldShowPostChatSurveyPane, shouldShowPreChatSurveyPane, shouldShowProactiveChatPane, shouldShowReconnectChatPane, shouldShowWebChatContainer } from "../../../controller/componentController";
10
12
  import { ActivityStreamHandler } from "../common/ActivityStreamHandler";
11
13
  import CallingContainerStateful from "../../callingcontainerstateful/CallingContainerStateful";
12
14
  import ChatButtonStateful from "../../chatbuttonstateful/ChatButtonStateful";
13
15
  import { Components } from "botframework-webchat";
14
16
  import ConfirmationPaneStateful from "../../confirmationpanestateful/ConfirmationPaneStateful";
17
+ import { ConversationEndEntity } from "../../../contexts/common/ConversationEndEntity";
15
18
  import { ConversationState } from "../../../contexts/common/ConversationState";
16
19
  import { DataStoreManager } from "../../../common/contextDataStore/DataStoreManager";
17
- import { Constants, E2VVOptions, LiveWorkItemState } from "../../../common/Constants";
18
20
  import { ElementType } from "@microsoft/omnichannel-chat-components";
19
21
  import EmailTranscriptPaneStateful from "../../emailtranscriptpanestateful/EmailTranscriptPaneStateful";
20
22
  import HeaderStateful from "../../headerstateful/HeaderStateful";
@@ -36,6 +38,8 @@ import { defaultScrollBarProps } from "../common/defaultProps/defaultScrollBarPr
36
38
  import { defaultWebChatContainerStatefulProps } from "../../webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps";
37
39
  import { disposeTelemetryLoggers } from "../common/disposeTelemetryLoggers";
38
40
  import { getGeneralStylesForButton } from "../common/getGeneralStylesForButton";
41
+ import { handleAgentEndConversation } from "../common/agentEndConversationHelper";
42
+ import { handleChatDisconnect } from "../common/chatDisconnectHelper";
39
43
  import { initCallingSdk } from "../common/initCallingSdk";
40
44
  import { initConfirmationPropsComposer } from "../common/initConfirmationPropsComposer";
41
45
  import { initWebChatComposer } from "../common/initWebChatComposer";
@@ -46,10 +50,6 @@ import { startProactiveChat } from "../common/startProactiveChat";
46
50
  import useChatAdapterStore from "../../../hooks/useChatAdapterStore";
47
51
  import useChatContextStore from "../../../hooks/useChatContextStore";
48
52
  import useChatSDKStore from "../../../hooks/useChatSDKStore";
49
- import { ConversationEndEntity } from "../../../contexts/common/ConversationEndEntity";
50
- import { handleAgentEndConversation } from "../common/agentEndConversationHelper";
51
- import { handleChatReconnect, isReconnectEnabled } from "../common/reconnectChatHelper";
52
- import { handleChatDisconnect } from "../common/chatDisconnectHelper";
53
53
  export const LiveChatWidgetStateful = props => {
54
54
  var _props$webChatContain, _props$styleProps, _chatSDK$omnichannelC, _props$controlProps, _props$controlProps2, _props$webChatContain3, _props$webChatContain4, _props$styleProps2, _props$controlProps15, _props$controlProps16, _props$componentOverr, _props$controlProps17, _props$componentOverr2, _props$controlProps18, _props$componentOverr3, _props$controlProps19, _props$componentOverr4, _props$controlProps20, _props$componentOverr5, _props$controlProps21, _props$componentOverr6, _props$controlProps22, _props$componentOverr7, _props$controlProps23, _props$controlProps24, _props$componentOverr8, _props$controlProps25, _props$componentOverr9, _props$controlProps26, _props$componentOverr10, _props$componentOverr11, _props$componentOverr12;
55
55
  const [state, dispatch] = useChatContextStore();
@@ -190,6 +190,12 @@ export const LiveChatWidgetStateful = props => {
190
190
  });
191
191
  });
192
192
  }
193
+ if (props.initialCustomContext) {
194
+ dispatch({
195
+ type: LiveChatWidgetActionType.SET_CUSTOM_CONTEXT,
196
+ payload: props.initialCustomContext
197
+ });
198
+ }
193
199
 
194
200
  // Initialize global dir
195
201
  const globalDir = ((_props$controlProps9 = props.controlProps) === null || _props$controlProps9 === void 0 ? void 0 : _props$controlProps9.dir) ?? getLocaleDirection((_props$chatConfig2 = props.chatConfig) === null || _props$chatConfig2 === void 0 ? void 0 : (_props$chatConfig2$Ch = _props$chatConfig2.ChatWidgetLanguage) === null || _props$chatConfig2$Ch === void 0 ? void 0 : _props$chatConfig2$Ch.msdyn_localeid);
@@ -250,16 +256,12 @@ export const LiveChatWidgetStateful = props => {
250
256
  BroadcastService.getMessageByEventName(BroadcastEvent.HideChatVisibilityChangeEvent).subscribe(async event => {
251
257
  var _event$payload;
252
258
  if ((event === null || event === void 0 ? void 0 : (_event$payload = event.payload) === null || _event$payload === void 0 ? void 0 : _event$payload.isChatHidden) !== undefined) {
253
- var _event$payload2, _props$controlProps10;
254
- TelemetryHelper.logActionEvent(LogLevel.INFO, {
255
- Event: TelemetryEvent.ChatVisibilityChanged,
256
- Description: "Chat visibility changed to " + (event === null || event === void 0 ? void 0 : (_event$payload2 = event.payload) === null || _event$payload2 === void 0 ? void 0 : _event$payload2.isChatHidden)
257
- });
259
+ var _props$controlProps10;
258
260
  if ((_props$controlProps10 = props.controlProps) !== null && _props$controlProps10 !== void 0 && _props$controlProps10.hideStartChatButton) {
259
- var _event$payload3;
261
+ var _event$payload2;
260
262
  dispatch({
261
263
  type: LiveChatWidgetActionType.SET_MINIMIZED,
262
- payload: event === null || event === void 0 ? void 0 : (_event$payload3 = event.payload) === null || _event$payload3 === void 0 ? void 0 : _event$payload3.isChatHidden
264
+ payload: event === null || event === void 0 ? void 0 : (_event$payload2 = event.payload) === null || _event$payload2 === void 0 ? void 0 : _event$payload2.isChatHidden
263
265
  });
264
266
  }
265
267
  const dateNow = Date.now();
@@ -1,6 +1,7 @@
1
1
  import { HtmlAttributeNames, Regex } from "../../common/Constants";
2
2
  import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
3
3
  import React, { useEffect } from "react";
4
+ import MarkdownIt from "markdown-it";
4
5
  import { extractPreChatSurveyResponseValues, findAllFocusableElement, getStateFromCache, isUndefinedOrEmpty, parseAdaptiveCardPayload } from "../../common/utils";
5
6
  import { ConversationState } from "../../contexts/common/ConversationState";
6
7
  import { LiveChatWidgetActionType } from "../../contexts/common/LiveChatWidgetActionType";
@@ -13,6 +14,8 @@ import useChatContextStore from "../../hooks/useChatContextStore";
13
14
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
15
  export const PreChatSurveyPaneStateful = props => {
15
16
  var _surveyProps$stylePro, _props$surveyProps, _props$surveyProps$co;
17
+ // Set MarkDown global variable to be used for prechat adaptive cards
18
+ window["markdownit"] = MarkdownIt;
16
19
  const [state, dispatch] = useChatContextStore();
17
20
  const {
18
21
  surveyProps,
@@ -1,11 +1,18 @@
1
+ /*
2
+ MIDDLEWARE_BANNER_FILE parameters:
3
+ {0} = File limit size
4
+ {1} = File extension
5
+ {2} = File name
6
+ */
7
+
1
8
  export const defaultMiddlewareLocalizedTexts = {
2
9
  MIDDLEWARE_BANNER_FILE_NULL_ERROR: "There was an error uploading the file, please try again.",
3
- MIDDLEWARE_BANNER_FILE_SIZE_WITHOUT_EXTENSION_ERROR: "File exceeds the allowed limit of {0} MB and please upload the file with an appropriate file extension.",
4
- MIDDLEWARE_BANNER_FILE_SIZE_EXTENSION_ERROR: "File exceeds the allowed limit of {0} MB and {1} files are not supported.",
5
- MIDDLEWARE_BANNER_FILE_WITHOUT_EXTENSION: "File upload error. Please upload the file with an appropriate file extension.",
6
- MIDDLEWARE_BANNER_FILE_EXTENSION_ERROR: "{0} files are not supported.",
7
- MIDDLEWARE_BANNER_FILE_SIZE_ERROR: "File exceeds the allowed limit of {0} MB.",
8
- MIDDLEWARE_BANNER_FILE_IS_EMPTY_ERROR: "This file can't be attached because it's empty. Please try again with a different file.",
10
+ MIDDLEWARE_BANNER_FILE_SIZE_WITHOUT_EXTENSION_ERROR: "File {2} exceeds the allowed limit of {0} MB and please upload the file with an appropriate file extension.",
11
+ MIDDLEWARE_BANNER_FILE_SIZE_EXTENSION_ERROR: "File {2} exceeds the allowed limit of {0} MB and {1} files are not supported.",
12
+ MIDDLEWARE_BANNER_FILE_WITHOUT_EXTENSION: "File upload error. Please upload the file {2} with an appropriate file extension.",
13
+ MIDDLEWARE_BANNER_FILE_EXTENSION_ERROR: "{1} files are not supported.",
14
+ MIDDLEWARE_BANNER_FILE_SIZE_ERROR: "File {2} exceeds the allowed limit of {0} MB.",
15
+ MIDDLEWARE_BANNER_FILE_IS_EMPTY_ERROR: "This file {2} can't be attached because it's empty. Please try again with a different file.",
9
16
  MIDDLEWARE_BANNER_ERROR_MESSAGE: "Upload failed, please try again.",
10
17
  MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE: "You’re back online.",
11
18
  MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION: "Unable to connect—please check your internet connection.",
@@ -25,7 +25,9 @@ export class MockChatSDK {
25
25
  return "";
26
26
  }
27
27
  getConversationDetails() {
28
- return {};
28
+ return {
29
+ State: "Active"
30
+ };
29
31
  }
30
32
  getCurrentLiveChatContext() {
31
33
  return {
@@ -70,6 +70,11 @@ const getMaxUploadFileSize = (maxFileSizeSupportedByDynamicsStr, contentType) =>
70
70
  const isImage = contentType => {
71
71
  return AMSConstants.supportedImagesMimeTypes.includes(contentType);
72
72
  };
73
+ const textEllipsis = function (str) {
74
+ let maxLength = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 20;
75
+ const ellipsis = "...";
76
+ return str.length > maxLength ? str.slice(0, maxLength - ellipsis.length) + ellipsis : str;
77
+ };
73
78
  const buildErrorMessage = (fileName, supportedFileExtension, supportedFileSize, fileIsEmpty, maxUploadFileSize, maxFileSizeSupportedByDynamics, localizedTexts) => {
74
79
  let errorMessage = "";
75
80
  if (!fileName || !maxUploadFileSize) {
@@ -85,10 +90,11 @@ const buildErrorMessage = (fileName, supportedFileExtension, supportedFileSize,
85
90
  if (!supportedFileExtension && !supportedFileSize) {
86
91
  errorMessage = getFileSizeAndFileExtensionErrorMessage(fileName, maxUploadFileSize, maxFileSizeSupportedByDynamics, localizedTexts);
87
92
  } else if (!supportedFileSize) {
88
- errorMessage = getFileSizeErrorMessage(maxUploadFileSize, maxFileSizeSupportedByDynamics, localizedTexts);
93
+ errorMessage = getFileSizeErrorMessage(fileName, maxUploadFileSize, maxFileSizeSupportedByDynamics, localizedTexts);
89
94
  } else if (!supportedFileExtension) {
90
95
  errorMessage = getFileExtensionErrorMessage(fileName, localizedTexts);
91
96
  } else if (fileIsEmpty) {
97
+ var _errorMessage;
92
98
  TelemetryHelper.logActionEvent(LogLevel.ERROR, {
93
99
  Event: TelemetryEvent.AttachmentUploadValidatorMiddlewareFailed,
94
100
  Description: "Attachment validation failed",
@@ -96,7 +102,8 @@ const buildErrorMessage = (fileName, supportedFileExtension, supportedFileSize,
96
102
  ErrorDetails: "File provided is empty"
97
103
  }
98
104
  });
99
- errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_IS_EMPTY_ERROR ?? "";
105
+ errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_IS_EMPTY_ERROR || "";
106
+ if ((_errorMessage = errorMessage) !== null && _errorMessage !== void 0 && _errorMessage.includes("{2}")) errorMessage = errorMessage.replace("{2}", textEllipsis(fileName));
100
107
  } else {
101
108
  TelemetryHelper.logActionEvent(LogLevel.ERROR, {
102
109
  Event: TelemetryEvent.AttachmentUploadValidatorMiddlewareFailed,
@@ -110,19 +117,18 @@ const buildErrorMessage = (fileName, supportedFileExtension, supportedFileSize,
110
117
  return errorMessage;
111
118
  };
112
119
  const getFileSizeAndFileExtensionErrorMessage = (fileName, maxUploadFileSize, maxFileSizeSupportedByDynamics, localizedTexts) => {
120
+ var _errorMessage3;
113
121
  const index = fileName.lastIndexOf(".");
114
122
  let errorMessage, exceptionDetails;
115
123
  if (index < 0) {
116
124
  errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_SIZE_WITHOUT_EXTENSION_ERROR;
117
125
  exceptionDetails = `File exceeded the allowed limit of ${maxUploadFileSize} MB and File provided without file extension`;
118
126
  } else {
119
- var _errorMessage;
127
+ var _errorMessage2;
120
128
  const fileExtension = fileName.substring(index);
121
129
  errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_SIZE_EXTENSION_ERROR;
130
+ if ((_errorMessage2 = errorMessage) !== null && _errorMessage2 !== void 0 && _errorMessage2.includes("{1}")) errorMessage = errorMessage.replace("{1}", fileExtension);
122
131
  exceptionDetails = `File exceeds the allowed limit of ${maxUploadFileSize} MB and ${fileExtension} files are not supported`;
123
- if ((_errorMessage = errorMessage) !== null && _errorMessage !== void 0 && _errorMessage.includes("{1}")) {
124
- errorMessage = errorMessage.replace("{1}", fileExtension);
125
- }
126
132
  }
127
133
  TelemetryHelper.logActionEvent(LogLevel.ERROR, {
128
134
  Event: TelemetryEvent.AttachmentUploadValidatorMiddlewareFailed,
@@ -131,10 +137,12 @@ const getFileSizeAndFileExtensionErrorMessage = (fileName, maxUploadFileSize, ma
131
137
  ErrorDetails: `${exceptionDetails} Dynamics file size limit=${maxFileSizeSupportedByDynamics} AMS image size limit=${AMSConstants.maxSupportedImageSize} AMS file size limit=${AMSConstants.maxSupportedFileSize}`
132
138
  }
133
139
  });
134
- return errorMessage ? errorMessage.includes("{0}") ? errorMessage.replace("{0}", maxUploadFileSize) : errorMessage : "";
140
+ if ((_errorMessage3 = errorMessage) !== null && _errorMessage3 !== void 0 && _errorMessage3.includes("{0}")) errorMessage = errorMessage.replace("{0}", maxUploadFileSize);
141
+ return errorMessage ? errorMessage.includes("{2}") ? errorMessage.replace("{2}", textEllipsis(fileName)) : errorMessage : "";
135
142
  };
136
143
  const getFileExtensionErrorMessage = (fileName, localizedTexts) => {
137
144
  const index = fileName.lastIndexOf(".");
145
+ let errorMessage;
138
146
  if (index < 0) {
139
147
  TelemetryHelper.logActionEvent(LogLevel.ERROR, {
140
148
  Event: TelemetryEvent.AttachmentUploadValidatorMiddlewareFailed,
@@ -143,8 +151,10 @@ const getFileExtensionErrorMessage = (fileName, localizedTexts) => {
143
151
  ErrorDetails: "File provided without file extension"
144
152
  }
145
153
  });
146
- return localizedTexts.MIDDLEWARE_BANNER_FILE_WITHOUT_EXTENSION ?? "";
154
+ errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_WITHOUT_EXTENSION;
155
+ return errorMessage ? errorMessage.includes("{2}") ? errorMessage.replace("{2}", textEllipsis(fileName)) : errorMessage : "";
147
156
  } else {
157
+ var _errorMessage4, _errorMessage5;
148
158
  const fileExtension = fileName.substring(index);
149
159
  TelemetryHelper.logActionEvent(LogLevel.ERROR, {
150
160
  Event: TelemetryEvent.AttachmentUploadValidatorMiddlewareFailed,
@@ -153,11 +163,14 @@ const getFileExtensionErrorMessage = (fileName, localizedTexts) => {
153
163
  ErrorDetails: `${fileExtension} files extension is not supported.`
154
164
  }
155
165
  });
156
- const errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_EXTENSION_ERROR;
157
- return errorMessage ? errorMessage.includes("{0}") ? errorMessage.replace("{0}", fileExtension) : errorMessage : "";
166
+ errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_EXTENSION_ERROR;
167
+ if ((_errorMessage4 = errorMessage) !== null && _errorMessage4 !== void 0 && _errorMessage4.includes("{0}")) errorMessage = errorMessage.replace("{0}", fileExtension); //keeping backwards compatibility for this localized string
168
+ if ((_errorMessage5 = errorMessage) !== null && _errorMessage5 !== void 0 && _errorMessage5.includes("{1}")) errorMessage = errorMessage.replace("{1}", fileExtension);
169
+ return errorMessage && errorMessage.length > 0 ? errorMessage : "";
158
170
  }
159
171
  };
160
- const getFileSizeErrorMessage = (maxUploadFileSize, maxFileSizeSupportedByDynamics, localizedTexts) => {
172
+ const getFileSizeErrorMessage = (fileName, maxUploadFileSize, maxFileSizeSupportedByDynamics, localizedTexts) => {
173
+ var _errorMessage6;
161
174
  TelemetryHelper.logActionEvent(LogLevel.ERROR, {
162
175
  Event: TelemetryEvent.AttachmentUploadValidatorMiddlewareFailed,
163
176
  Description: "Attachment validation failed",
@@ -165,8 +178,9 @@ const getFileSizeErrorMessage = (maxUploadFileSize, maxFileSizeSupportedByDynami
165
178
  ErrorDetails: `File exceeds the allowed limit of ${maxUploadFileSize}MB. Dynamics file size limit=${maxFileSizeSupportedByDynamics} AMS image size limit=${AMSConstants.maxSupportedImageSize} AMS file size limit=${AMSConstants.maxSupportedFileSize}`
166
179
  }
167
180
  });
168
- const errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_SIZE_ERROR;
169
- return errorMessage ? errorMessage.includes("{0}") ? errorMessage.replace("{0}", maxUploadFileSize) : errorMessage : "";
181
+ let errorMessage = localizedTexts.MIDDLEWARE_BANNER_FILE_SIZE_ERROR;
182
+ if ((_errorMessage6 = errorMessage) !== null && _errorMessage6 !== void 0 && _errorMessage6.includes("{0}")) errorMessage = errorMessage.replace("{0}", maxUploadFileSize);
183
+ return errorMessage ? errorMessage.includes("{2}") ? errorMessage.replace("{2}", textEllipsis(fileName)) : errorMessage : "";
170
184
  };
171
185
 
172
186
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
@@ -22,22 +22,25 @@ const applyDataMasking = (action, regexCollection) => {
22
22
  });
23
23
  return action;
24
24
  }
25
- let isRuleMatched = false;
26
25
  for (const ruleId of Object.keys(regexCollection)) {
27
26
  const item = regexCollection[ruleId];
28
27
  if (item) {
28
+ let ruleInfiniteException = false;
29
+ let ruleApplied = false;
29
30
  try {
30
31
  const regex = new RegExp(item, "gi");
31
32
  let match;
32
33
  // eslint-disable-next-line no-cond-assign
33
34
  while (match = regex.exec(text)) {
34
35
  const replaceStr = match[0].replace(/./gi, maskedChar);
35
- text = text.replace(match[0], replaceStr);
36
- TelemetryHelper.logActionEvent(LogLevel.INFO, {
37
- Event: TelemetryEvent.DataMaskingRuleApplied,
38
- Description: `Data Masking Rule Id: ${ruleId} applied.`
39
- });
40
- isRuleMatched = true;
36
+ const modifiedText = text.replace(match[0], replaceStr);
37
+ if (modifiedText == text) {
38
+ ruleInfiniteException = true;
39
+ console.warn(`The data masking rule ${item} is ignored because it matches empty strings. Please modify this rule.`);
40
+ break;
41
+ }
42
+ ruleApplied = true;
43
+ text = modifiedText;
41
44
  }
42
45
  } catch (err) {
43
46
  TelemetryHelper.logActionEvent(LogLevel.ERROR, {
@@ -48,11 +51,21 @@ const applyDataMasking = (action, regexCollection) => {
48
51
  }
49
52
  });
50
53
  }
51
- }
52
-
53
- // Exit if rule matched
54
- if (isRuleMatched === true) {
55
- break;
54
+ if (ruleApplied) {
55
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
56
+ Event: TelemetryEvent.DataMaskingRuleApplied,
57
+ Description: `Data Masking Rule Id: ${ruleId} applied.`
58
+ });
59
+ }
60
+ if (ruleInfiniteException) {
61
+ TelemetryHelper.logActionEvent(LogLevel.ERROR, {
62
+ Event: TelemetryEvent.DataMaskingRuleApplyFailed,
63
+ ExceptionDetails: {
64
+ RuleId: ruleId,
65
+ Exception: "The data masking rule matches empty strings."
66
+ }
67
+ });
68
+ }
56
69
  }
57
70
  }
58
71
  action.payload.text = text;
@@ -48,7 +48,9 @@ export declare enum BroadcastEvent {
48
48
  SigninCardReceived = "SignInCardReceived",
49
49
  BotAuthConfigRequest = "BotAuthConfigRequest",
50
50
  BotAuthConfigResponse = "BotAuthConfigResponse",
51
- HideChatVisibilityChangeEvent = "hideChatVisibilityChangeEvent"
51
+ HideChatVisibilityChangeEvent = "hideChatVisibilityChangeEvent",
52
+ UpdateSessionDataForTelemetry = "UpdateSessionDataForTelemetry",
53
+ UpdateConversationDataForTelemetry = "UpdateConversationDataForTelemetry"
52
54
  }
53
55
  export declare enum TelemetryEvent {
54
56
  CallAdded = "CallAdded",
@@ -53,5 +53,6 @@ export interface ILiveChatWidgetProps {
53
53
  liveChatContextFromCache?: ILiveChatWidgetContext;
54
54
  contextDataStore?: IContextDataStore;
55
55
  getAuthToken?: (authClientFunction?: string) => Promise<string | null>;
56
+ initialCustomContext?: any;
56
57
  scrollBarProps?: IScrollBarProps;
57
58
  }
@@ -7,7 +7,9 @@ export declare class MockChatSDK {
7
7
  getChatToken(): null;
8
8
  createChatAdapter(): MockAdapter;
9
9
  getPreChatSurvey(parseToJson: boolean): string;
10
- getConversationDetails(): {};
10
+ getConversationDetails(): {
11
+ State: string;
12
+ };
11
13
  getCurrentLiveChatContext(): {
12
14
  chatToken: {};
13
15
  requestId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microsoft/omnichannel-chat-widget",
3
- "version": "1.0.2-main.b2301a3",
3
+ "version": "1.0.3-main.05297ce",
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
  },
75
75
  "dependencies": {
76
76
  "@fluentui/react": "^8.49.1",
77
- "@microsoft/omnichannel-chat-components": "0.1.0-main.f4c21f0",
78
- "@microsoft/omnichannel-chat-sdk": "1.2.1-main.171bfbe",
77
+ "@microsoft/omnichannel-chat-components": "1.0.1",
78
+ "@microsoft/omnichannel-chat-sdk": "1.3.0",
79
79
  "abort-controller-es5": "^2.0.1",
80
80
  "dompurify": "^2.3.4",
81
81
  "markdown-it": "^12.3.2",