@microsoft/omnichannel-chat-widget 1.8.3 → 1.8.4-main.424a580

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 (132) hide show
  1. package/lib/cjs/common/Constants.js +5 -0
  2. package/lib/cjs/common/facades/FacadeChatSDK.js +6 -0
  3. package/lib/cjs/common/telemetry/AppInsightsEvents.js +4 -5
  4. package/lib/cjs/common/telemetry/TelemetryConstants.js +44 -2
  5. package/lib/cjs/common/telemetry/loggers/appInsightsLogger.js +26 -10
  6. package/lib/cjs/common/utils/SecureEventBus.js +307 -0
  7. package/lib/cjs/common/utils/dispatchCustomEvent.js +25 -0
  8. package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +16 -4
  9. package/lib/cjs/components/citationpanestateful/CitationPaneStateful.js +20 -1
  10. package/lib/cjs/components/headerstateful/HeaderStateful.js +8 -2
  11. package/lib/cjs/components/livechatwidget/common/ActivitySubscriber/AddActivitySubscriber.js +127 -0
  12. package/lib/cjs/components/livechatwidget/common/ChatWidgetEvents.js +15 -0
  13. package/lib/cjs/components/livechatwidget/common/PersistentConversationHandler.js +287 -0
  14. package/lib/cjs/components/livechatwidget/common/createAdapter.js +2 -0
  15. package/lib/cjs/components/livechatwidget/common/defaultProps/defaultPersistentChatHistoryProps.js +18 -0
  16. package/lib/cjs/components/livechatwidget/common/endChat.js +7 -1
  17. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +16 -7
  18. package/lib/cjs/components/livechatwidget/common/renderSurveyHelpers.js +2 -2
  19. package/lib/cjs/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +3 -3
  20. package/lib/cjs/components/livechatwidget/common/startChat.js +5 -1
  21. package/lib/cjs/components/livechatwidget/common/startChatErrorHandler.js +24 -4
  22. package/lib/cjs/components/livechatwidget/interfaces/IPersistentChatHistoryProps.js +1 -0
  23. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +22 -3
  24. package/lib/cjs/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +29 -2
  25. package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +12 -3
  26. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +36 -5
  27. package/lib/cjs/components/webchatcontainerstateful/common/activities/botActivity.js +14 -0
  28. package/lib/cjs/components/webchatcontainerstateful/common/activities/conversationDividerActivity.js +17 -0
  29. package/lib/cjs/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +97 -0
  30. package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +3 -1
  31. package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultWebChatStatefulProps.js +1 -1
  32. package/lib/cjs/components/webchatcontainerstateful/hooks/usePersistentChatHistory.js +59 -0
  33. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.js +122 -0
  34. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/Constants.js +10 -0
  35. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/ConversationDividerActivity.js +47 -0
  36. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.js +1038 -0
  37. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LoadInlineBannerActivity.js +34 -0
  38. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +50 -1
  39. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityStatusMiddleware.js +16 -2
  40. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultInLineBannerStyle.js +20 -0
  41. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +2 -2
  42. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/HistoryMessageTimestamp.js +59 -0
  43. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +5 -3
  44. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/SendingTimestamp.js +2 -2
  45. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +29 -7
  46. package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +1 -0
  47. package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +7 -1
  48. package/lib/cjs/contexts/createReducer.js +15 -0
  49. package/lib/cjs/firstresponselatency/FirstMessageTrackerFromBot.js +3 -2
  50. package/lib/cjs/firstresponselatency/FirstResponseLatencyTracker.js +6 -2
  51. package/lib/cjs/plugins/newMessageEventHandler.js +4 -1
  52. package/lib/esm/common/Constants.js +5 -0
  53. package/lib/esm/common/facades/FacadeChatSDK.js +6 -0
  54. package/lib/esm/common/telemetry/AppInsightsEvents.js +4 -5
  55. package/lib/esm/common/telemetry/TelemetryConstants.js +42 -1
  56. package/lib/esm/common/telemetry/loggers/appInsightsLogger.js +27 -11
  57. package/lib/esm/common/utils/SecureEventBus.js +328 -0
  58. package/lib/esm/common/utils/dispatchCustomEvent.js +18 -0
  59. package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +17 -5
  60. package/lib/esm/components/citationpanestateful/CitationPaneStateful.js +20 -1
  61. package/lib/esm/components/headerstateful/HeaderStateful.js +9 -3
  62. package/lib/esm/components/livechatwidget/common/ActivitySubscriber/AddActivitySubscriber.js +120 -0
  63. package/lib/esm/components/livechatwidget/common/ChatWidgetEvents.js +8 -0
  64. package/lib/esm/components/livechatwidget/common/PersistentConversationHandler.js +280 -0
  65. package/lib/esm/components/livechatwidget/common/createAdapter.js +2 -0
  66. package/lib/esm/components/livechatwidget/common/defaultProps/defaultPersistentChatHistoryProps.js +11 -0
  67. package/lib/esm/components/livechatwidget/common/endChat.js +7 -1
  68. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +16 -7
  69. package/lib/esm/components/livechatwidget/common/renderSurveyHelpers.js +2 -2
  70. package/lib/esm/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +3 -3
  71. package/lib/esm/components/livechatwidget/common/startChat.js +7 -3
  72. package/lib/esm/components/livechatwidget/common/startChatErrorHandler.js +23 -4
  73. package/lib/esm/components/livechatwidget/interfaces/IPersistentChatHistoryProps.js +1 -0
  74. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +23 -4
  75. package/lib/esm/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +31 -4
  76. package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +13 -4
  77. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +39 -5
  78. package/lib/esm/components/webchatcontainerstateful/common/activities/botActivity.js +7 -0
  79. package/lib/esm/components/webchatcontainerstateful/common/activities/conversationDividerActivity.js +9 -0
  80. package/lib/esm/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +90 -0
  81. package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +3 -1
  82. package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultWebChatStatefulProps.js +2 -2
  83. package/lib/esm/components/webchatcontainerstateful/hooks/usePersistentChatHistory.js +51 -0
  84. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.js +115 -0
  85. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/Constants.js +3 -0
  86. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/ConversationDividerActivity.js +39 -0
  87. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.js +1060 -0
  88. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LoadInlineBannerActivity.js +25 -0
  89. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +48 -1
  90. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityStatusMiddleware.js +13 -0
  91. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultInLineBannerStyle.js +13 -0
  92. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +1 -1
  93. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/HistoryMessageTimestamp.js +52 -0
  94. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +3 -2
  95. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/SendingTimestamp.js +1 -1
  96. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +29 -7
  97. package/lib/esm/contexts/common/LiveChatWidgetActionType.js +1 -0
  98. package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +7 -1
  99. package/lib/esm/contexts/createReducer.js +15 -0
  100. package/lib/esm/firstresponselatency/FirstMessageTrackerFromBot.js +3 -2
  101. package/lib/esm/firstresponselatency/FirstResponseLatencyTracker.js +6 -2
  102. package/lib/esm/plugins/newMessageEventHandler.js +4 -1
  103. package/lib/types/common/Constants.d.ts +4 -0
  104. package/lib/types/common/facades/FacadeChatSDK.d.ts +3 -1
  105. package/lib/types/common/telemetry/TelemetryConstants.d.ts +39 -2
  106. package/lib/types/common/utils/SecureEventBus.d.ts +159 -0
  107. package/lib/types/common/utils/dispatchCustomEvent.d.ts +2 -0
  108. package/lib/types/components/livechatwidget/common/ActivitySubscriber/AddActivitySubscriber.d.ts +45 -0
  109. package/lib/types/components/livechatwidget/common/ChatWidgetEvents.d.ts +7 -0
  110. package/lib/types/components/livechatwidget/common/PersistentConversationHandler.d.ts +28 -0
  111. package/lib/types/components/livechatwidget/common/defaultProps/defaultPersistentChatHistoryProps.d.ts +2 -0
  112. package/lib/types/components/livechatwidget/common/startChatErrorHandler.d.ts +1 -0
  113. package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetProps.d.ts +2 -0
  114. package/lib/types/components/livechatwidget/interfaces/IPersistentChatHistoryProps.d.ts +12 -0
  115. package/lib/types/components/webchatcontainerstateful/common/activities/botActivity.d.ts +7 -0
  116. package/lib/types/components/webchatcontainerstateful/common/activities/conversationDividerActivity.d.ts +10 -0
  117. package/lib/types/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.d.ts +2 -0
  118. package/lib/types/components/webchatcontainerstateful/hooks/usePersistentChatHistory.d.ts +4 -0
  119. package/lib/types/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.d.ts +7 -0
  120. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/Constants.d.ts +3 -0
  121. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/ConversationDividerActivity.d.ts +4 -0
  122. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.d.ts +326 -0
  123. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LoadInlineBannerActivity.d.ts +8 -0
  124. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.d.ts +2 -1
  125. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityStatusMiddleware.d.ts +1 -0
  126. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultInLineBannerStyle.d.ts +2 -0
  127. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/HistoryMessageTimestamp.d.ts +2 -0
  128. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.d.ts +1 -1
  129. package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +1 -0
  130. package/lib/types/contexts/common/ILiveChatWidgetLocalizedTexts.d.ts +6 -0
  131. package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +2 -1
  132. package/package.json +3 -3
@@ -68,9 +68,11 @@ export let BroadcastEvent;
68
68
  BroadcastEvent["OnWidgetError"] = "OnWidgetError";
69
69
  BroadcastEvent["FMLTrackingCompletedAck"] = "FMLTrackingCompletedAck";
70
70
  BroadcastEvent["FMLTrackingCompleted"] = "FMLTrackingCompleted";
71
+ BroadcastEvent["PersistentConversationReset"] = "PersistentConversationReset";
71
72
  })(BroadcastEvent || (BroadcastEvent = {}));
72
73
  export let TelemetryEvent;
73
74
  (function (TelemetryEvent) {
75
+ TelemetryEvent["FetchPersistentChatHistoryFailed"] = "FetchPersistentChatHistoryFailed";
74
76
  TelemetryEvent["CallAdded"] = "CallAdded";
75
77
  TelemetryEvent["LocalVideoStreamAdded"] = "LocalVideoStreamAdded";
76
78
  TelemetryEvent["LocalVideoStreamRemoved"] = "LocalVideoStreamRemoved";
@@ -116,6 +118,7 @@ export let TelemetryEvent;
116
118
  TelemetryEvent["EndChatFailed"] = "EndChatFailed";
117
119
  TelemetryEvent["SettingCustomContext"] = "SettingCustomContext";
118
120
  TelemetryEvent["WebChatLoaded"] = "WebChatLoaded";
121
+ TelemetryEvent["PersistentChatHistoryEnabled"] = "PersistentChatHistoryEnabled";
119
122
  TelemetryEvent["LCWChatButtonActionCompleted"] = "LCWChatButtonActionCompleted";
120
123
  TelemetryEvent["LCWChatButtonClicked"] = "LCWChatButtonClicked";
121
124
  TelemetryEvent["LCWChatButtonShow"] = "LCWChatButtonShow";
@@ -280,8 +283,37 @@ export let TelemetryEvent;
280
283
  TelemetryEvent["UXCitationPaneCompleted"] = "UXCitationPaneCompleted";
281
284
  TelemetryEvent["UXLiveChatWidgetStart"] = "UXLiveChatWidgetStart";
282
285
  TelemetryEvent["UXLiveChatWidgetCompleted"] = "UXLiveChatWidgetCompleted";
286
+ TelemetryEvent["UXPostChatPaneStarted"] = "UXPostChatPaneStarted";
287
+ TelemetryEvent["UXPostChatPaneCompleted"] = "UXPostChatPaneCompleted";
283
288
  TelemetryEvent["AppInsightsInitialized"] = "AppInsightsInitialized";
284
289
  TelemetryEvent["AppInsightsInitFailed"] = "AppInsightsInitFailed";
290
+ TelemetryEvent["ConvertPersistentChatHistoryMessageToActivityFailed"] = "ConvertPersistentChatHistoryMessageToActivityFailed";
291
+ TelemetryEvent["UXLCWPersistentChatHistoryInitialized"] = "UXLCWPersistentChatHistoryInitialized";
292
+ TelemetryEvent["LCWPersistentChatHistoryFetchStarted"] = "LCWPersistentChatHistoryFetchStarted";
293
+ TelemetryEvent["LCWPersistentChatHistoryFetchCompleted"] = "LCWPersistentChatHistoryFetchCompleted";
294
+ TelemetryEvent["LCWPersistentChatHistoryFetchFailed"] = "LCWPersistentChatHistoryFetchFailed";
295
+ TelemetryEvent["LCWWebChatStorePollingStarted"] = "LCWWebChatStorePollingStarted";
296
+ TelemetryEvent["LCWWebChatStoreReady"] = "LCWWebChatStoreReady";
297
+ TelemetryEvent["LCWWebChatConnected"] = "LCWWebChatConnected";
298
+ TelemetryEvent["LCWWebChatDisconnected"] = "LCWWebChatDisconnected";
299
+ TelemetryEvent["LCWWebChatConnectionCheckFailed"] = "LCWWebChatConnectionCheckFailed";
300
+ TelemetryEvent["LCWPersistentConversationHandlerInitialized"] = "LCWPersistentConversationHandlerInitialized";
301
+ TelemetryEvent["LCWPersistentHistoryPullBlocked"] = "LCWPersistentHistoryPullBlocked";
302
+ TelemetryEvent["LCWPersistentHistoryPullCompleted"] = "LCWPersistentHistoryPullCompleted";
303
+ TelemetryEvent["LCWLazyLoadInitializationStarted"] = "LCWLazyLoadInitializationStarted";
304
+ TelemetryEvent["LCWLazyLoadContainerNotFound"] = "LCWLazyLoadContainerNotFound";
305
+ TelemetryEvent["LCWLazyLoadInitializationCompleted"] = "LCWLazyLoadInitializationCompleted";
306
+ TelemetryEvent["LCWLazyLoadSessionMetrics"] = "LCWLazyLoadSessionMetrics";
307
+ TelemetryEvent["LCWLazyLoadTargetElementNotFound"] = "LCWLazyLoadTargetElementNotFound";
308
+ TelemetryEvent["LCWLazyLoadScrollFailed"] = "LCWLazyLoadScrollFailed";
309
+ TelemetryEvent["LCWLazyLoadActivityMounted"] = "LCWLazyLoadActivityMounted";
310
+ TelemetryEvent["LCWLazyLoadReset"] = "LCWLazyLoadReset";
311
+ TelemetryEvent["LCWLazyLoadNoMoreHistory"] = "LCWLazyLoadNoMoreHistory";
312
+ TelemetryEvent["LCWLazyLoadDestroyed"] = "LCWLazyLoadDestroyed";
313
+ TelemetryEvent["SecureEventBusUnauthorizedDispatch"] = "SecureEventBusUnauthorizedDispatch";
314
+ TelemetryEvent["SecureEventBusListenerError"] = "SecureEventBusListenerError";
315
+ TelemetryEvent["SecureEventBusDispatchError"] = "SecureEventBusDispatchError";
316
+ TelemetryEvent["StartChatComplete"] = "StartChatComplete";
285
317
  })(TelemetryEvent || (TelemetryEvent = {}));
286
318
  export let TelemetryConstants = /*#__PURE__*/function () {
287
319
  function TelemetryConstants() {
@@ -349,6 +381,9 @@ export let TelemetryConstants = /*#__PURE__*/function () {
349
381
  case TelemetryEvent.PostChatWorkflowFromAgent:
350
382
  case TelemetryEvent.PostChatWorkflowFromBot:
351
383
  case TelemetryEvent.AppStatesException:
384
+ case TelemetryEvent.SecureEventBusUnauthorizedDispatch:
385
+ case TelemetryEvent.SecureEventBusListenerError:
386
+ case TelemetryEvent.SecureEventBusDispatchError:
352
387
  return ScenarioType.ACTIONS;
353
388
  case TelemetryEvent.StartChatSDKCall:
354
389
  case TelemetryEvent.StartChatEventReceived:
@@ -408,4 +443,10 @@ export let TelemetryConstants = /*#__PURE__*/function () {
408
443
  }
409
444
  }]);
410
445
  return TelemetryConstants;
411
- }();
446
+ }();
447
+ export let ConversationStage;
448
+ (function (ConversationStage) {
449
+ ConversationStage["Initialization"] = "Initialization";
450
+ ConversationStage["CSREngagement"] = "CSR Engagement";
451
+ ConversationStage["ConversationEnd"] = "Conversation End";
452
+ })(ConversationStage || (ConversationStage = {}));
@@ -1,19 +1,16 @@
1
- import { LogLevel, TelemetryEvent } from "../TelemetryConstants";
1
+ import { ConversationStage, LogLevel, TelemetryEvent } from "../TelemetryConstants";
2
2
  import ScenarioMarker from "../ScenarioMarker";
3
3
  import { TelemetryHelper } from "../TelemetryHelper";
4
4
  import { AppInsightsTelemetryMessage } from "../../Constants";
5
5
  import { AppInsightsEventMapping } from "../AppInsightsEvents";
6
6
  var AllowedKeys;
7
7
  (function (AllowedKeys) {
8
- AllowedKeys["LogLevel"] = "LogLevel";
8
+ AllowedKeys["OrganizationId"] = "OrganizationId";
9
+ AllowedKeys["ConversationId"] = "LiveWorkItemId";
10
+ AllowedKeys["ElapsedTimeInMilliseconds"] = "Duration";
9
11
  AllowedKeys["Description"] = "Description";
10
- AllowedKeys["ExceptionDetails"] = "ExceptionDetails";
11
- AllowedKeys["ChannelId"] = "ChannelId";
12
+ AllowedKeys["ChannelId"] = "ChannelType";
12
13
  AllowedKeys["LCWRuntimeId"] = "ClientSessionId";
13
- AllowedKeys["ConversationId"] = "LiveWorkItemId";
14
- AllowedKeys["ChatId"] = "ChatThreadId";
15
- AllowedKeys["OrganizationId"] = "OrganizationId";
16
- AllowedKeys["ElapsedTimeInMilliseconds"] = "DurationInMilliseconds";
17
14
  })(AllowedKeys || (AllowedKeys = {}));
18
15
  let initializationPromise = null;
19
16
  export const appInsightsLogger = appInsightsKey => {
@@ -86,9 +83,9 @@ export const appInsightsLogger = appInsightsKey => {
86
83
  if (!_logger) return;
87
84
  const eventName = telemetryInput === null || telemetryInput === void 0 ? void 0 : (_telemetryInput$paylo = telemetryInput.payload) === null || _telemetryInput$paylo === void 0 ? void 0 : _telemetryInput$paylo.Event;
88
85
  const telemetryInfo = telemetryInput === null || telemetryInput === void 0 ? void 0 : (_telemetryInput$telem = telemetryInput.telemetryInfo) === null || _telemetryInput$telem === void 0 ? void 0 : _telemetryInput$telem.telemetryInfo;
89
- const eventProperties = setEventProperties(telemetryInfo);
90
86
  if (eventName) {
91
87
  const trackingEventName = getTrackingEventName(logLevel, eventName);
88
+ const eventProperties = setEventProperties(trackingEventName, telemetryInfo);
92
89
  _logger.trackEvent({
93
90
  name: trackingEventName,
94
91
  properties: eventProperties
@@ -107,17 +104,36 @@ export const appInsightsLogger = appInsightsKey => {
107
104
  };
108
105
 
109
106
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
110
- function setEventProperties(telemetryInfo) {
107
+ function setEventProperties(eventName, telemetryInfo) {
111
108
  const eventProperties = {};
112
109
  if (telemetryInfo) {
113
110
  for (const key in AllowedKeys) {
114
- const finalKey = AllowedKeys[key]; // get renamed keys for LCWRuntimeId, ConversationId, ChatId
111
+ const finalKey = AllowedKeys[key]; // get renamed keys for LCWRuntimeId, ConversationId
115
112
  const value = telemetryInfo[key];
116
113
  if (value !== undefined && value !== null && value !== "") {
117
114
  eventProperties[finalKey] = value;
118
115
  }
119
116
  }
120
117
  }
118
+ // Include exception details in description for error events
119
+ if (telemetryInfo !== null && telemetryInfo !== void 0 && telemetryInfo.ExceptionDetails) {
120
+ eventProperties[AllowedKeys.Description] = JSON.stringify(telemetryInfo.ExceptionDetails);
121
+ }
122
+ const customProperties = (() => {
123
+ if (!(telemetryInfo !== null && telemetryInfo !== void 0 && telemetryInfo.CustomProperties)) {
124
+ return {};
125
+ }
126
+ try {
127
+ return typeof telemetryInfo.CustomProperties === "string" ? JSON.parse(telemetryInfo.CustomProperties) : telemetryInfo.CustomProperties;
128
+ } catch (error) {
129
+ console.warn("Failed to parse CustomProperties:", error);
130
+ return {};
131
+ }
132
+ })();
133
+ // Additional properties
134
+ eventProperties["ConversationStage"] = customProperties.ConversationStage ?? ConversationStage.CSREngagement;
135
+ eventProperties["Scenario"] = "Conversation Diagnostics";
136
+ eventProperties["OperationName"] = eventName.includes(": ") ? eventName.split(": ")[1] : eventName;
121
137
  return eventProperties;
122
138
  }
123
139
  function getTrackingEventName(logLevel, eventName) {
@@ -0,0 +1,328 @@
1
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
3
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
4
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
5
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
6
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
7
+ import { TelemetryHelper } from "../telemetry/TelemetryHelper";
8
+ import { LogLevel, TelemetryEvent } from "../telemetry/TelemetryConstants";
9
+
10
+ /**
11
+ * SecureEventBus - A private, authenticated event system for internal chat widget communication
12
+ *
13
+ * This replaces the vulnerable global window event system to prevent external scripts
14
+ * from injecting malicious events into the chat widget.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const eventBus = SecureEventBus.getInstance();
19
+ * const token = eventBus.getAuthToken();
20
+ *
21
+ * // Subscribe to an event
22
+ * const unsubscribe = eventBus.subscribe('userMessage', (payload) => {
23
+ * console.log('Message received:', payload);
24
+ * });
25
+ *
26
+ * // Dispatch an event
27
+ * eventBus.dispatch('userMessage', { text: 'Hello' }, token);
28
+ *
29
+ * // Unsubscribe
30
+ * unsubscribe();
31
+ * ```
32
+ */
33
+
34
+ /**
35
+ * Interface representing an event listener with callback and unique identifier
36
+ */
37
+ /**
38
+ * SecureEventBus class implementing the singleton pattern for secure event communication.
39
+ * Provides authentication-based event dispatching to prevent unauthorized external access.
40
+ */
41
+ let SecureEventBus = /*#__PURE__*/function () {
42
+ /**
43
+ * Private constructor to enforce singleton pattern.
44
+ * Generates a unique authentication token for this session.
45
+ */
46
+ function SecureEventBus() {
47
+ _classCallCheck(this, SecureEventBus);
48
+ _defineProperty(this, "listeners", new Map());
49
+ _defineProperty(this, "authToken", void 0);
50
+ _defineProperty(this, "eventCounter", 0);
51
+ // Generate a secure, unique token for this session
52
+ this.authToken = this.generateAuthToken();
53
+ }
54
+
55
+ /**
56
+ * Get the singleton instance of SecureEventBus.
57
+ * Creates a new instance if one doesn't exist.
58
+ *
59
+ * @returns The singleton instance of SecureEventBus
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * const eventBus = SecureEventBus.getInstance();
64
+ * ```
65
+ */
66
+ _createClass(SecureEventBus, [{
67
+ key: "generateAuthToken",
68
+ value:
69
+ /**
70
+ * Generate a cryptographically secure authentication token.
71
+ * Uses crypto.getRandomValues when available, falls back to Math.random.
72
+ *
73
+ * @private
74
+ * @returns A 64-character hexadecimal string representing the authentication token
75
+ */
76
+ function generateAuthToken() {
77
+ const array = new Uint8Array(32);
78
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
79
+ crypto.getRandomValues(array);
80
+ } else {
81
+ // Fallback for environments without crypto.getRandomValues
82
+ for (let i = 0; i < array.length; i++) {
83
+ array[i] = Math.floor(Math.random() * 256);
84
+ }
85
+ }
86
+ return Array.from(array, byte => byte.toString(16).padStart(2, "0")).join("");
87
+ }
88
+
89
+ /**
90
+ * Get the authentication token for this SecureEventBus instance.
91
+ * This token is required for dispatching events and should only be used internally.
92
+ *
93
+ * @returns The authentication token string
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * const eventBus = SecureEventBus.getInstance();
98
+ * const token = eventBus.getAuthToken();
99
+ * eventBus.dispatch('myEvent', { data: 'value' }, token);
100
+ * ```
101
+ */
102
+ }, {
103
+ key: "getAuthToken",
104
+ value: function getAuthToken() {
105
+ return this.authToken;
106
+ }
107
+
108
+ /**
109
+ * Dispatch an event with authentication to all registered listeners.
110
+ * Verifies the authentication token before dispatching to prevent unauthorized access.
111
+ *
112
+ * @param eventName - The name of the event to dispatch
113
+ * @param payload - The data to send with the event (optional)
114
+ * @param token - Authentication token (must match the internal token)
115
+ * @returns true if event was successfully dispatched, false if unauthorized or error occurred
116
+ *
117
+ * @example
118
+ * ```typescript
119
+ * const eventBus = SecureEventBus.getInstance();
120
+ * const token = eventBus.getAuthToken();
121
+ *
122
+ * // Dispatch with payload
123
+ * const success = eventBus.dispatch('userAction', { action: 'click', target: 'button' }, token);
124
+ *
125
+ * // Dispatch without payload
126
+ * eventBus.dispatch('windowClosed', undefined, token);
127
+ * ```
128
+ */
129
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
130
+ }, {
131
+ key: "dispatch",
132
+ value: function dispatch(eventName, payload, token) {
133
+ // Verify authentication token
134
+ if (token !== this.authToken) {
135
+ TelemetryHelper.logActionEvent(LogLevel.ERROR, {
136
+ Event: TelemetryEvent.SecureEventBusUnauthorizedDispatch,
137
+ Description: `Unauthorized event dispatch attempt blocked: ${eventName}`,
138
+ ExceptionDetails: {
139
+ eventName,
140
+ providedToken: token ? "provided" : "missing",
141
+ expectedToken: "secured"
142
+ }
143
+ });
144
+ return false;
145
+ }
146
+ const listeners = this.listeners.get(eventName);
147
+ if (!listeners || listeners.length === 0) {
148
+ return true; // No listeners, but not an error
149
+ }
150
+
151
+ // Dispatch to all registered listeners
152
+ try {
153
+ listeners.forEach(listener => {
154
+ try {
155
+ listener.callback(payload);
156
+ } catch (error) {
157
+ TelemetryHelper.logActionEvent(LogLevel.ERROR, {
158
+ Event: TelemetryEvent.SecureEventBusListenerError,
159
+ Description: `Error in event listener for event: ${eventName}`,
160
+ ExceptionDetails: error
161
+ });
162
+ }
163
+ });
164
+ return true;
165
+ } catch (error) {
166
+ TelemetryHelper.logActionEvent(LogLevel.ERROR, {
167
+ Event: TelemetryEvent.SecureEventBusDispatchError,
168
+ Description: `Error dispatching event: ${eventName}`,
169
+ ExceptionDetails: error
170
+ });
171
+ return false;
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Subscribe to an event with a callback function.
177
+ * The callback will be executed whenever the specified event is dispatched.
178
+ *
179
+ * @param eventName - The name of the event to listen for
180
+ * @param callback - The function to execute when the event is fired
181
+ * @returns A function that can be called to unsubscribe from the event
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * const eventBus = SecureEventBus.getInstance();
186
+ *
187
+ * // Subscribe to an event
188
+ * const unsubscribe = eventBus.subscribe('chatMessage', (message) => {
189
+ * console.log('New message:', message.text);
190
+ * console.log('From user:', message.userId);
191
+ * });
192
+ *
193
+ * // Later, unsubscribe
194
+ * unsubscribe();
195
+ * ```
196
+ */
197
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
198
+ }, {
199
+ key: "subscribe",
200
+ value: function subscribe(eventName, callback) {
201
+ const listenerId = `listener_${++this.eventCounter}`;
202
+ if (!this.listeners.has(eventName)) {
203
+ this.listeners.set(eventName, []);
204
+ }
205
+ const listeners = this.listeners.get(eventName);
206
+ if (!listeners) {
207
+ throw new Error(`Listeners for event "${eventName}" not found.`);
208
+ }
209
+ const listener = {
210
+ callback,
211
+ id: listenerId
212
+ };
213
+ listeners.push(listener);
214
+
215
+ // Return unsubscribe function
216
+ return () => {
217
+ const currentListeners = this.listeners.get(eventName);
218
+ if (currentListeners) {
219
+ const index = currentListeners.findIndex(l => l.id === listenerId);
220
+ if (index !== -1) {
221
+ currentListeners.splice(index, 1);
222
+ }
223
+
224
+ // Clean up empty listener arrays
225
+ if (currentListeners.length === 0) {
226
+ this.listeners.delete(eventName);
227
+ }
228
+ }
229
+ };
230
+ }
231
+
232
+ /**
233
+ * Remove all listeners for a specific event.
234
+ * This completely removes the event from the internal listeners map.
235
+ *
236
+ * @param eventName - The name of the event to remove all listeners for
237
+ *
238
+ * @example
239
+ * ```typescript
240
+ * const eventBus = SecureEventBus.getInstance();
241
+ *
242
+ * // Remove all listeners for 'chatClosed' event
243
+ * eventBus.removeAllListeners('chatClosed');
244
+ * ```
245
+ */
246
+ }, {
247
+ key: "removeAllListeners",
248
+ value: function removeAllListeners(eventName) {
249
+ this.listeners.delete(eventName);
250
+ }
251
+
252
+ /**
253
+ * Clear all listeners for all events.
254
+ * This resets the entire event bus to its initial state.
255
+ * Useful for cleanup during application shutdown or testing.
256
+ *
257
+ * @example
258
+ * ```typescript
259
+ * const eventBus = SecureEventBus.getInstance();
260
+ *
261
+ * // Clear all event listeners
262
+ * eventBus.clear();
263
+ * ```
264
+ */
265
+ }, {
266
+ key: "clear",
267
+ value: function clear() {
268
+ this.listeners.clear();
269
+ }
270
+
271
+ /**
272
+ * Get the number of listeners for a specific event.
273
+ * Useful for debugging and monitoring purposes.
274
+ *
275
+ * @param eventName - The name of the event to count listeners for
276
+ * @returns The number of listeners registered for the event
277
+ *
278
+ * @example
279
+ * ```typescript
280
+ * const eventBus = SecureEventBus.getInstance();
281
+ *
282
+ * // Check how many listeners are registered for 'userAction'
283
+ * const count = eventBus.getListenerCount('userAction');
284
+ * console.log(`${count} listeners registered for userAction`);
285
+ * ```
286
+ */
287
+ }, {
288
+ key: "getListenerCount",
289
+ value: function getListenerCount(eventName) {
290
+ var _this$listeners$get;
291
+ return ((_this$listeners$get = this.listeners.get(eventName)) === null || _this$listeners$get === void 0 ? void 0 : _this$listeners$get.length) || 0;
292
+ }
293
+
294
+ /**
295
+ * Get all registered event names.
296
+ * Returns an array of event names that currently have listeners.
297
+ * Useful for debugging and monitoring purposes.
298
+ *
299
+ * @returns An array of event names that have registered listeners
300
+ *
301
+ * @example
302
+ * ```typescript
303
+ * const eventBus = SecureEventBus.getInstance();
304
+ *
305
+ * // Get all registered events
306
+ * const events = eventBus.getRegisteredEvents();
307
+ * console.log('Active events:', events);
308
+ * // Output: ['userAction', 'chatMessage', 'windowResize']
309
+ * ```
310
+ */
311
+ }, {
312
+ key: "getRegisteredEvents",
313
+ value: function getRegisteredEvents() {
314
+ return Array.from(this.listeners.keys());
315
+ }
316
+ }], [{
317
+ key: "getInstance",
318
+ value: function getInstance() {
319
+ if (!SecureEventBus.instance) {
320
+ SecureEventBus.instance = new SecureEventBus();
321
+ }
322
+ return SecureEventBus.instance;
323
+ }
324
+ }]);
325
+ return SecureEventBus;
326
+ }();
327
+ _defineProperty(SecureEventBus, "instance", null);
328
+ export default SecureEventBus;
@@ -0,0 +1,18 @@
1
+ import SecureEventBus from "./SecureEventBus";
2
+
3
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4
+ const dispatchCustomEvent = (name, payload) => {
5
+ try {
6
+ const eventBus = SecureEventBus.getInstance();
7
+ const authToken = eventBus.getAuthToken();
8
+
9
+ // Dispatch through the secure event bus instead of global window
10
+ const success = eventBus.dispatch(name, payload, authToken);
11
+ if (!success) {
12
+ console.error("Failed to dispatch secure event:", name);
13
+ }
14
+ } catch (error) {
15
+ console.error("Error dispatching secure custom event:", name, payload, error);
16
+ }
17
+ };
18
+ export default dispatchCustomEvent;
@@ -1,4 +1,4 @@
1
- import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
1
+ import { ConversationStage, LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
2
2
  import React, { useEffect, useRef, useState } from "react";
3
3
  import { createTimer, setFocusOnElement } from "../../common/utils";
4
4
  import { ChatButton } from "@microsoft/omnichannel-chat-components";
@@ -17,7 +17,10 @@ export const ChatButtonStateful = props => {
17
17
  uiTimer = createTimer();
18
18
  TelemetryHelper.logLoadingEventToAllTelemetry(LogLevel.INFO, {
19
19
  Event: TelemetryEvent.UXLCWChatButtonLoadingStart,
20
- Description: "Chat button loading started"
20
+ Description: "Chat button loading started",
21
+ CustomProperties: {
22
+ ConversationStage: ConversationStage.Initialization
23
+ }
21
24
  });
22
25
  }, []);
23
26
 
@@ -40,7 +43,10 @@ export const ChatButtonStateful = props => {
40
43
  ref.current = async () => {
41
44
  TelemetryHelper.logActionEventToAllTelemetry(LogLevel.INFO, {
42
45
  Event: TelemetryEvent.LCWChatButtonClicked,
43
- Description: "Chat button click action started"
46
+ Description: "Chat button click action started",
47
+ CustomProperties: {
48
+ ConversationStage: ConversationStage.Initialization
49
+ }
44
50
  });
45
51
  if (state.appStates.isMinimized) {
46
52
  dispatch({
@@ -60,7 +66,10 @@ export const ChatButtonStateful = props => {
60
66
  }
61
67
  TelemetryHelper.logActionEventToAllTelemetry(LogLevel.INFO, {
62
68
  Event: TelemetryEvent.LCWChatButtonActionCompleted,
63
- Description: "Chat button action completed"
69
+ Description: "Chat button action completed",
70
+ CustomProperties: {
71
+ ConversationStage: ConversationStage.Initialization
72
+ }
64
73
  });
65
74
  };
66
75
  const outOfOfficeStyleProps = Object.assign({}, defaultOutOfOfficeChatButtonStyleProps, outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.styleProps);
@@ -114,7 +123,10 @@ export const ChatButtonStateful = props => {
114
123
  TelemetryHelper.logLoadingEventToAllTelemetry(LogLevel.INFO, {
115
124
  Event: TelemetryEvent.UXLCWChatButtonLoadingCompleted,
116
125
  Description: "Chat button loading completed",
117
- ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
126
+ ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed,
127
+ CustomProperties: {
128
+ ConversationStage: ConversationStage.Initialization
129
+ }
118
130
  });
119
131
  }, []);
120
132
  useEffect(() => {
@@ -33,7 +33,7 @@ export const CitationPaneStateful = props => {
33
33
  const [paneStyle, setPaneStyle] = useState(null);
34
34
  const [isReady, setIsReady] = useState(false);
35
35
 
36
- // Move focus to the container
36
+ // Initial focus pattern (mirrors ConfirmationPaneStateful): focus first focusable element (will re-attempt after visibility becomes true)
37
37
  useEffect(() => {
38
38
  preventFocusToMoveOutOfElement(controlId);
39
39
  const focusableElements = findAllFocusableElement(`#${controlId}`);
@@ -55,6 +55,25 @@ export const CitationPaneStateful = props => {
55
55
  });
56
56
  }, []);
57
57
 
58
+ // Retry focus once pane is actually visible (isReady) in case initial attempt occurred while wrapper was visibility:hidden
59
+ useEffect(() => {
60
+ if (!isReady) return;
61
+ const focusableElements = findAllFocusableElement(`#${controlId}`);
62
+ if (focusableElements && focusableElements.length > 0) {
63
+ const first = focusableElements[0];
64
+ // If focused element is not already inside the pane, move focus
65
+ if (!first.contains(document.activeElement) && !(document.activeElement && document.activeElement.id.startsWith(controlId))) {
66
+ requestAnimationFrame(() => {
67
+ if (first.isConnected) {
68
+ first.focus({
69
+ preventScroll: true
70
+ });
71
+ }
72
+ });
73
+ }
74
+ }
75
+ }, [isReady, controlId]);
76
+
58
77
  // Compute the widget bounds and set pane style accordingly (95% of widget size
59
78
  // and centered inside the widget). If the widget container can't be found,
60
79
  // fall back to the default pane styles from defaultCitationPaneProps.
@@ -1,4 +1,4 @@
1
- import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
1
+ import { ConversationStage, LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
2
2
  import React, { useEffect, useRef, useState } from "react";
3
3
  import { ConfirmationState } from "../../common/Constants";
4
4
  import { ConversationState } from "../../contexts/common/ConversationState";
@@ -61,7 +61,10 @@ export const HeaderStateful = props => {
61
61
  var _props$headerProps, _props$headerProps$co, _props$headerProps$co2;
62
62
  TelemetryHelper.logActionEventToAllTelemetry(LogLevel.INFO, {
63
63
  Event: TelemetryEvent.HeaderCloseButtonClicked,
64
- Description: "Header Close action started."
64
+ Description: "Header Close action started.",
65
+ CustomProperties: {
66
+ ConversationStage: ConversationStage.ConversationEnd
67
+ }
65
68
  });
66
69
  if (localConfirmationPaneState.current !== ConfirmationState.Ok) {
67
70
  dispatch({
@@ -76,7 +79,10 @@ export const HeaderStateful = props => {
76
79
  }
77
80
  TelemetryHelper.logActionEventToAllTelemetry(LogLevel.INFO, {
78
81
  Event: TelemetryEvent.CloseChatActionCompleted,
79
- Description: "Header Close action completed."
82
+ Description: "Header Close action completed.",
83
+ CustomProperties: {
84
+ ConversationStage: ConversationStage.ConversationEnd
85
+ }
80
86
  });
81
87
  const closeButtonId = ((_props$headerProps = props.headerProps) === null || _props$headerProps === void 0 ? void 0 : (_props$headerProps$co = _props$headerProps.controlProps) === null || _props$headerProps$co === void 0 ? void 0 : (_props$headerProps$co2 = _props$headerProps$co.closeButtonProps) === null || _props$headerProps$co2 === void 0 ? void 0 : _props$headerProps$co2.id) ?? `${controlProps.id}-close-button`;
82
88
  if (closeButtonId) {