@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.
- package/lib/cjs/common/Constants.js +5 -0
- package/lib/cjs/common/facades/FacadeChatSDK.js +6 -0
- package/lib/cjs/common/telemetry/AppInsightsEvents.js +4 -5
- package/lib/cjs/common/telemetry/TelemetryConstants.js +44 -2
- package/lib/cjs/common/telemetry/loggers/appInsightsLogger.js +26 -10
- package/lib/cjs/common/utils/SecureEventBus.js +307 -0
- package/lib/cjs/common/utils/dispatchCustomEvent.js +25 -0
- package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +16 -4
- package/lib/cjs/components/citationpanestateful/CitationPaneStateful.js +20 -1
- package/lib/cjs/components/headerstateful/HeaderStateful.js +8 -2
- package/lib/cjs/components/livechatwidget/common/ActivitySubscriber/AddActivitySubscriber.js +127 -0
- package/lib/cjs/components/livechatwidget/common/ChatWidgetEvents.js +15 -0
- package/lib/cjs/components/livechatwidget/common/PersistentConversationHandler.js +287 -0
- package/lib/cjs/components/livechatwidget/common/createAdapter.js +2 -0
- package/lib/cjs/components/livechatwidget/common/defaultProps/defaultPersistentChatHistoryProps.js +18 -0
- package/lib/cjs/components/livechatwidget/common/endChat.js +7 -1
- package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +16 -7
- package/lib/cjs/components/livechatwidget/common/renderSurveyHelpers.js +2 -2
- package/lib/cjs/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +3 -3
- package/lib/cjs/components/livechatwidget/common/startChat.js +5 -1
- package/lib/cjs/components/livechatwidget/common/startChatErrorHandler.js +24 -4
- package/lib/cjs/components/livechatwidget/interfaces/IPersistentChatHistoryProps.js +1 -0
- package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +22 -3
- package/lib/cjs/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +29 -2
- package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +12 -3
- package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +36 -5
- package/lib/cjs/components/webchatcontainerstateful/common/activities/botActivity.js +14 -0
- package/lib/cjs/components/webchatcontainerstateful/common/activities/conversationDividerActivity.js +17 -0
- package/lib/cjs/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +97 -0
- package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +3 -1
- package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultWebChatStatefulProps.js +1 -1
- package/lib/cjs/components/webchatcontainerstateful/hooks/usePersistentChatHistory.js +59 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.js +122 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/Constants.js +10 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/ConversationDividerActivity.js +47 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.js +1038 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LoadInlineBannerActivity.js +34 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +50 -1
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityStatusMiddleware.js +16 -2
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultInLineBannerStyle.js +20 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +2 -2
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/HistoryMessageTimestamp.js +59 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +5 -3
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/SendingTimestamp.js +2 -2
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +29 -7
- package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +1 -0
- package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +7 -1
- package/lib/cjs/contexts/createReducer.js +15 -0
- package/lib/cjs/firstresponselatency/FirstMessageTrackerFromBot.js +3 -2
- package/lib/cjs/firstresponselatency/FirstResponseLatencyTracker.js +6 -2
- package/lib/cjs/plugins/newMessageEventHandler.js +4 -1
- package/lib/esm/common/Constants.js +5 -0
- package/lib/esm/common/facades/FacadeChatSDK.js +6 -0
- package/lib/esm/common/telemetry/AppInsightsEvents.js +4 -5
- package/lib/esm/common/telemetry/TelemetryConstants.js +42 -1
- package/lib/esm/common/telemetry/loggers/appInsightsLogger.js +27 -11
- package/lib/esm/common/utils/SecureEventBus.js +328 -0
- package/lib/esm/common/utils/dispatchCustomEvent.js +18 -0
- package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +17 -5
- package/lib/esm/components/citationpanestateful/CitationPaneStateful.js +20 -1
- package/lib/esm/components/headerstateful/HeaderStateful.js +9 -3
- package/lib/esm/components/livechatwidget/common/ActivitySubscriber/AddActivitySubscriber.js +120 -0
- package/lib/esm/components/livechatwidget/common/ChatWidgetEvents.js +8 -0
- package/lib/esm/components/livechatwidget/common/PersistentConversationHandler.js +280 -0
- package/lib/esm/components/livechatwidget/common/createAdapter.js +2 -0
- package/lib/esm/components/livechatwidget/common/defaultProps/defaultPersistentChatHistoryProps.js +11 -0
- package/lib/esm/components/livechatwidget/common/endChat.js +7 -1
- package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +16 -7
- package/lib/esm/components/livechatwidget/common/renderSurveyHelpers.js +2 -2
- package/lib/esm/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +3 -3
- package/lib/esm/components/livechatwidget/common/startChat.js +7 -3
- package/lib/esm/components/livechatwidget/common/startChatErrorHandler.js +23 -4
- package/lib/esm/components/livechatwidget/interfaces/IPersistentChatHistoryProps.js +1 -0
- package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +23 -4
- package/lib/esm/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +31 -4
- package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +13 -4
- package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +39 -5
- package/lib/esm/components/webchatcontainerstateful/common/activities/botActivity.js +7 -0
- package/lib/esm/components/webchatcontainerstateful/common/activities/conversationDividerActivity.js +9 -0
- package/lib/esm/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +90 -0
- package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +3 -1
- package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultWebChatStatefulProps.js +2 -2
- package/lib/esm/components/webchatcontainerstateful/hooks/usePersistentChatHistory.js +51 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.js +115 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/Constants.js +3 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/ConversationDividerActivity.js +39 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.js +1060 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LoadInlineBannerActivity.js +25 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +48 -1
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityStatusMiddleware.js +13 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultInLineBannerStyle.js +13 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +1 -1
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/HistoryMessageTimestamp.js +52 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +3 -2
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/SendingTimestamp.js +1 -1
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +29 -7
- package/lib/esm/contexts/common/LiveChatWidgetActionType.js +1 -0
- package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +7 -1
- package/lib/esm/contexts/createReducer.js +15 -0
- package/lib/esm/firstresponselatency/FirstMessageTrackerFromBot.js +3 -2
- package/lib/esm/firstresponselatency/FirstResponseLatencyTracker.js +6 -2
- package/lib/esm/plugins/newMessageEventHandler.js +4 -1
- package/lib/types/common/Constants.d.ts +4 -0
- package/lib/types/common/facades/FacadeChatSDK.d.ts +3 -1
- package/lib/types/common/telemetry/TelemetryConstants.d.ts +39 -2
- package/lib/types/common/utils/SecureEventBus.d.ts +159 -0
- package/lib/types/common/utils/dispatchCustomEvent.d.ts +2 -0
- package/lib/types/components/livechatwidget/common/ActivitySubscriber/AddActivitySubscriber.d.ts +45 -0
- package/lib/types/components/livechatwidget/common/ChatWidgetEvents.d.ts +7 -0
- package/lib/types/components/livechatwidget/common/PersistentConversationHandler.d.ts +28 -0
- package/lib/types/components/livechatwidget/common/defaultProps/defaultPersistentChatHistoryProps.d.ts +2 -0
- package/lib/types/components/livechatwidget/common/startChatErrorHandler.d.ts +1 -0
- package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetProps.d.ts +2 -0
- package/lib/types/components/livechatwidget/interfaces/IPersistentChatHistoryProps.d.ts +12 -0
- package/lib/types/components/webchatcontainerstateful/common/activities/botActivity.d.ts +7 -0
- package/lib/types/components/webchatcontainerstateful/common/activities/conversationDividerActivity.d.ts +10 -0
- package/lib/types/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.d.ts +2 -0
- package/lib/types/components/webchatcontainerstateful/hooks/usePersistentChatHistory.d.ts +4 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.d.ts +7 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/Constants.d.ts +3 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/ConversationDividerActivity.d.ts +4 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.d.ts +326 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LoadInlineBannerActivity.d.ts +8 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.d.ts +2 -1
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityStatusMiddleware.d.ts +1 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultInLineBannerStyle.d.ts +2 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/HistoryMessageTimestamp.d.ts +2 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.d.ts +1 -1
- package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +1 -0
- package/lib/types/contexts/common/ILiveChatWidgetLocalizedTexts.d.ts +6 -0
- package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +2 -1
- 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["
|
|
8
|
+
AllowedKeys["OrganizationId"] = "OrganizationId";
|
|
9
|
+
AllowedKeys["ConversationId"] = "LiveWorkItemId";
|
|
10
|
+
AllowedKeys["ElapsedTimeInMilliseconds"] = "Duration";
|
|
9
11
|
AllowedKeys["Description"] = "Description";
|
|
10
|
-
AllowedKeys["
|
|
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
|
|
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
|
-
//
|
|
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) {
|