@microsoft/omnichannel-chat-widget 1.8.3 → 1.8.4-main.4478bbf

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 (118) 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 +43 -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/headerstateful/HeaderStateful.js +8 -2
  10. package/lib/cjs/components/livechatwidget/common/ActivitySubscriber/AddActivitySubscriber.js +127 -0
  11. package/lib/cjs/components/livechatwidget/common/ChatWidgetEvents.js +15 -0
  12. package/lib/cjs/components/livechatwidget/common/PersistentConversationHandler.js +284 -0
  13. package/lib/cjs/components/livechatwidget/common/createAdapter.js +2 -0
  14. package/lib/cjs/components/livechatwidget/common/defaultProps/defaultPersistentChatHistoryProps.js +18 -0
  15. package/lib/cjs/components/livechatwidget/common/endChat.js +7 -1
  16. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +7 -5
  17. package/lib/cjs/components/livechatwidget/common/renderSurveyHelpers.js +2 -2
  18. package/lib/cjs/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +3 -3
  19. package/lib/cjs/components/livechatwidget/common/startChat.js +5 -1
  20. package/lib/cjs/components/livechatwidget/common/startChatErrorHandler.js +24 -4
  21. package/lib/cjs/components/livechatwidget/interfaces/IPersistentChatHistoryProps.js +1 -0
  22. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +12 -3
  23. package/lib/cjs/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +29 -2
  24. package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +12 -3
  25. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +31 -5
  26. package/lib/cjs/components/webchatcontainerstateful/common/activities/botActivity.js +14 -0
  27. package/lib/cjs/components/webchatcontainerstateful/common/activities/conversationDividerActivity.js +17 -0
  28. package/lib/cjs/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +97 -0
  29. package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +2 -1
  30. package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultWebChatStatefulProps.js +1 -1
  31. package/lib/cjs/components/webchatcontainerstateful/hooks/usePersistentChatHistory.js +59 -0
  32. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.js +122 -0
  33. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/Constants.js +10 -0
  34. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/ConversationDividerActivity.js +18 -0
  35. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.js +1038 -0
  36. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LoadInlineBannerActivity.js +34 -0
  37. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +44 -0
  38. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityStatusMiddleware.js +16 -2
  39. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultInLineBannerStyle.js +20 -0
  40. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +2 -2
  41. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/HistoryMessageTimestamp.js +59 -0
  42. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +5 -3
  43. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/SendingTimestamp.js +2 -2
  44. package/lib/cjs/firstresponselatency/FirstMessageTrackerFromBot.js +3 -2
  45. package/lib/cjs/firstresponselatency/FirstResponseLatencyTracker.js +6 -2
  46. package/lib/cjs/plugins/newMessageEventHandler.js +4 -1
  47. package/lib/esm/common/Constants.js +5 -0
  48. package/lib/esm/common/facades/FacadeChatSDK.js +6 -0
  49. package/lib/esm/common/telemetry/AppInsightsEvents.js +4 -5
  50. package/lib/esm/common/telemetry/TelemetryConstants.js +41 -1
  51. package/lib/esm/common/telemetry/loggers/appInsightsLogger.js +27 -11
  52. package/lib/esm/common/utils/SecureEventBus.js +328 -0
  53. package/lib/esm/common/utils/dispatchCustomEvent.js +18 -0
  54. package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +17 -5
  55. package/lib/esm/components/headerstateful/HeaderStateful.js +9 -3
  56. package/lib/esm/components/livechatwidget/common/ActivitySubscriber/AddActivitySubscriber.js +120 -0
  57. package/lib/esm/components/livechatwidget/common/ChatWidgetEvents.js +8 -0
  58. package/lib/esm/components/livechatwidget/common/PersistentConversationHandler.js +277 -0
  59. package/lib/esm/components/livechatwidget/common/createAdapter.js +2 -0
  60. package/lib/esm/components/livechatwidget/common/defaultProps/defaultPersistentChatHistoryProps.js +11 -0
  61. package/lib/esm/components/livechatwidget/common/endChat.js +7 -1
  62. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +7 -5
  63. package/lib/esm/components/livechatwidget/common/renderSurveyHelpers.js +2 -2
  64. package/lib/esm/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +3 -3
  65. package/lib/esm/components/livechatwidget/common/startChat.js +7 -3
  66. package/lib/esm/components/livechatwidget/common/startChatErrorHandler.js +23 -4
  67. package/lib/esm/components/livechatwidget/interfaces/IPersistentChatHistoryProps.js +1 -0
  68. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +13 -4
  69. package/lib/esm/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +31 -4
  70. package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +13 -4
  71. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +34 -5
  72. package/lib/esm/components/webchatcontainerstateful/common/activities/botActivity.js +7 -0
  73. package/lib/esm/components/webchatcontainerstateful/common/activities/conversationDividerActivity.js +9 -0
  74. package/lib/esm/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +90 -0
  75. package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +2 -1
  76. package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultWebChatStatefulProps.js +2 -2
  77. package/lib/esm/components/webchatcontainerstateful/hooks/usePersistentChatHistory.js +51 -0
  78. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.js +115 -0
  79. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/Constants.js +3 -0
  80. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/ConversationDividerActivity.js +10 -0
  81. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.js +1060 -0
  82. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LoadInlineBannerActivity.js +25 -0
  83. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +42 -0
  84. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityStatusMiddleware.js +13 -0
  85. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultInLineBannerStyle.js +13 -0
  86. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +1 -1
  87. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/HistoryMessageTimestamp.js +52 -0
  88. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +3 -2
  89. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/SendingTimestamp.js +1 -1
  90. package/lib/esm/firstresponselatency/FirstMessageTrackerFromBot.js +3 -2
  91. package/lib/esm/firstresponselatency/FirstResponseLatencyTracker.js +6 -2
  92. package/lib/esm/plugins/newMessageEventHandler.js +4 -1
  93. package/lib/types/common/Constants.d.ts +4 -0
  94. package/lib/types/common/facades/FacadeChatSDK.d.ts +3 -1
  95. package/lib/types/common/telemetry/TelemetryConstants.d.ts +38 -2
  96. package/lib/types/common/utils/SecureEventBus.d.ts +159 -0
  97. package/lib/types/common/utils/dispatchCustomEvent.d.ts +2 -0
  98. package/lib/types/components/livechatwidget/common/ActivitySubscriber/AddActivitySubscriber.d.ts +45 -0
  99. package/lib/types/components/livechatwidget/common/ChatWidgetEvents.d.ts +7 -0
  100. package/lib/types/components/livechatwidget/common/PersistentConversationHandler.d.ts +28 -0
  101. package/lib/types/components/livechatwidget/common/defaultProps/defaultPersistentChatHistoryProps.d.ts +2 -0
  102. package/lib/types/components/livechatwidget/common/startChatErrorHandler.d.ts +1 -0
  103. package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetProps.d.ts +2 -0
  104. package/lib/types/components/livechatwidget/interfaces/IPersistentChatHistoryProps.d.ts +7 -0
  105. package/lib/types/components/webchatcontainerstateful/common/activities/botActivity.d.ts +7 -0
  106. package/lib/types/components/webchatcontainerstateful/common/activities/conversationDividerActivity.d.ts +10 -0
  107. package/lib/types/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.d.ts +2 -0
  108. package/lib/types/components/webchatcontainerstateful/hooks/usePersistentChatHistory.d.ts +4 -0
  109. package/lib/types/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.d.ts +7 -0
  110. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/Constants.d.ts +3 -0
  111. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/ConversationDividerActivity.d.ts +4 -0
  112. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.d.ts +326 -0
  113. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LoadInlineBannerActivity.d.ts +8 -0
  114. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityStatusMiddleware.d.ts +1 -0
  115. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultInLineBannerStyle.d.ts +2 -0
  116. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/HistoryMessageTimestamp.d.ts +2 -0
  117. package/lib/types/contexts/common/ILiveChatWidgetLocalizedTexts.d.ts +1 -0
  118. package/package.json +3 -3
@@ -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 } from "react";
3
3
  import { ParticipantType } from "../../common/Constants";
4
4
  import { CustomerVoiceEvents } from "./enums/CustomerVoiceEvents";
@@ -6,9 +6,10 @@ import { PostChatSurveyMode } from "./enums/PostChatSurveyMode";
6
6
  import { PostChatSurveyPane } from "@microsoft/omnichannel-chat-components";
7
7
  import { TelemetryHelper } from "../../common/telemetry/TelemetryHelper";
8
8
  import { defaultGeneralPostChatSurveyPaneStyleProps } from "./common/defaultStyleProps/defaultgeneralPostChatSurveyPaneStyleProps";
9
- import { findAllFocusableElement } from "../../common/utils";
9
+ import { createTimer, findAllFocusableElement } from "../../common/utils";
10
10
  import useChatContextStore from "../../hooks/useChatContextStore";
11
11
  import isValidSurveyUrl from "./common/isValidSurveyUrl";
12
+ let uiTimer;
12
13
  const generateSurveyInviteLink = function (surveyInviteLink, isEmbed, locale, compact, customerVoiceSurveyCorrelationId) {
13
14
  let showMultiLingual = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
14
15
  const surveyLinkParams = new URLSearchParams({
@@ -22,6 +23,16 @@ const generateSurveyInviteLink = function (surveyInviteLink, isEmbed, locale, co
22
23
  };
23
24
  export const PostChatSurveyPaneStateful = props => {
24
25
  var _props$styleProps, _state$appStates, _props$controlProps;
26
+ useEffect(() => {
27
+ uiTimer = createTimer();
28
+ TelemetryHelper.logLoadingEventToAllTelemetry(LogLevel.INFO, {
29
+ Event: TelemetryEvent.UXPostChatPaneStarted,
30
+ Description: "Postchat survey pane loading started.",
31
+ CustomProperties: {
32
+ ConversationStage: ConversationStage.ConversationEnd
33
+ }
34
+ });
35
+ }, []);
25
36
  const [state] = useChatContextStore();
26
37
  const generalStyleProps = Object.assign({}, defaultGeneralPostChatSurveyPaneStyleProps, (_props$styleProps = props.styleProps) === null || _props$styleProps === void 0 ? void 0 : _props$styleProps.generalStyleProps, {
27
38
  display: state.appStates.isMinimized ? "none" : "contents"
@@ -72,7 +83,14 @@ export const PostChatSurveyPaneStateful = props => {
72
83
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
73
84
  Event: TelemetryEvent.PostChatSurveyLoaded
74
85
  });
75
-
86
+ TelemetryHelper.logLoadingEventToAllTelemetry(LogLevel.INFO, {
87
+ Event: TelemetryEvent.UXPostChatPaneCompleted,
88
+ ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed,
89
+ Description: "Postchat survey pane loading completed.",
90
+ CustomProperties: {
91
+ ConversationStage: ConversationStage.ConversationEnd
92
+ }
93
+ });
76
94
  //Customer Voice Telemetry Events
77
95
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
78
96
  window.addEventListener("message", message => {
@@ -87,7 +105,10 @@ export const PostChatSurveyPaneStateful = props => {
87
105
  } else if (data === CustomerVoiceEvents.FormResponseSubmitted) {
88
106
  TelemetryHelper.logActionEventToAllTelemetry(LogLevel.INFO, {
89
107
  Event: TelemetryEvent.CustomerVoiceFormResponseSubmitted,
90
- Description: "Customer Voice form response submitted."
108
+ Description: "Customer Voice form response submitted.",
109
+ CustomProperties: {
110
+ ConversationStage: ConversationStage.ConversationEnd
111
+ }
91
112
  });
92
113
  } else if (data === CustomerVoiceEvents.FormResponseError) {
93
114
  TelemetryHelper.logActionEventToAllTelemetry(LogLevel.ERROR, {
@@ -95,6 +116,9 @@ export const PostChatSurveyPaneStateful = props => {
95
116
  Description: "Customer Voice form response error.",
96
117
  ExceptionDetails: {
97
118
  message: "Customer Voice form response error."
119
+ },
120
+ CustomProperties: {
121
+ ConversationStage: ConversationStage.ConversationEnd
98
122
  }
99
123
  });
100
124
  } else if (typeof data === "string" && data.startsWith(CustomerVoiceEvents.FormsError)) {
@@ -103,6 +127,9 @@ export const PostChatSurveyPaneStateful = props => {
103
127
  Description: "Customer Voice failed to load with forms error.",
104
128
  ExceptionDetails: {
105
129
  message: `Customer Voice forms error details: ${data}`
130
+ },
131
+ CustomProperties: {
132
+ ConversationStage: ConversationStage.ConversationEnd
106
133
  }
107
134
  });
108
135
  }
@@ -1,5 +1,5 @@
1
1
  import { HtmlAttributeNames, Regex } from "../../common/Constants";
2
- import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
2
+ import { ConversationStage, LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
3
3
  import React, { useEffect } from "react";
4
4
  import { createTimer, extractPreChatSurveyResponseValues, findAllFocusableElement, getStateFromCache, getWidgetCacheId, isUndefinedOrEmpty, parseAdaptiveCardPayload } from "../../common/utils";
5
5
  import { ConversationState } from "../../contexts/common/ConversationState";
@@ -19,7 +19,10 @@ export const PreChatSurveyPaneStateful = props => {
19
19
  uiTimer = createTimer();
20
20
  TelemetryHelper.logLoadingEventToAllTelemetry(LogLevel.INFO, {
21
21
  Event: TelemetryEvent.UXPrechatPaneStart,
22
- Description: "Prechat survey pane loading started."
22
+ Description: "Prechat survey pane loading started.",
23
+ CustomProperties: {
24
+ ConversationStage: ConversationStage.Initialization
25
+ }
23
26
  });
24
27
  }, []);
25
28
 
@@ -70,7 +73,10 @@ export const PreChatSurveyPaneStateful = props => {
70
73
  onSubmit: async values => {
71
74
  TelemetryHelper.logActionEventToAllTelemetry(LogLevel.INFO, {
72
75
  Event: TelemetryEvent.PrechatSubmitted,
73
- Description: "Prechat survey submitted."
76
+ Description: "Prechat survey submitted.",
77
+ CustomProperties: {
78
+ ConversationStage: ConversationStage.Initialization
79
+ }
74
80
  });
75
81
  dispatch({
76
82
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
@@ -144,7 +150,10 @@ export const PreChatSurveyPaneStateful = props => {
144
150
  TelemetryHelper.logLoadingEventToAllTelemetry(LogLevel.INFO, {
145
151
  Event: TelemetryEvent.UXPrechatPaneCompleted,
146
152
  ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed,
147
- Description: "Prechat survey pane loading completed."
153
+ Description: "Prechat survey pane loading completed.",
154
+ CustomProperties: {
155
+ ConversationStage: ConversationStage.Initialization
156
+ }
148
157
  });
149
158
  }, []);
150
159
 
@@ -11,6 +11,7 @@ import { NotificationHandler } from "./webchatcontroller/notification/Notificati
11
11
  import { NotificationScenarios } from "./webchatcontroller/enums/NotificationScenarios";
12
12
  import { TelemetryHelper } from "../../common/telemetry/TelemetryHelper";
13
13
  import { WebChatActionType } from "./webchatcontroller/enums/WebChatActionType";
14
+ import WebChatEventSubscribers from "./webchatcontroller/WebChatEventSubscribers";
14
15
  import { WebChatStoreLoader } from "./webchatcontroller/WebChatStoreLoader";
15
16
  import { createIOSOptimizedEmojiFont } from "./common/utils/fontUtils";
16
17
  import { defaultAdaptiveCardStyles } from "./common/defaultStyles/defaultAdaptiveCardStyles";
@@ -20,7 +21,13 @@ import { defaultSentMessageAnchorStyles } from "./webchatcontroller/middlewares/
20
21
  import { defaultSystemMessageBoxStyles } from "./webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSystemMessageBoxStyles";
21
22
  import { defaultUserMessageBoxStyles } from "./webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultUserMessageBoxStyles";
22
23
  import { defaultWebChatContainerStatefulProps } from "./common/defaultProps/defaultWebChatContainerStatefulProps";
24
+ import { isPersistentChatEnabled } from "../livechatwidget/common/liveChatConfigUtils";
23
25
  import { useChatContextStore } from "../..";
26
+ import useFacadeSDKStore from "../../hooks/useFacadeChatSDKStore";
27
+ import usePersistentChatHistory from "./hooks/usePersistentChatHistory";
28
+
29
+ // Types for better type safety
30
+
24
31
  let uiTimer;
25
32
  const broadcastChannelMessageEvent = "message";
26
33
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -49,7 +56,9 @@ const createMagicCodeSuccessResponse = signin => {
49
56
  };
50
57
  };
51
58
  export const WebChatContainerStateful = props => {
52
- var _props$webChatContain, _defaultWebChatContai, _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _webChatContainerProp7, _webChatContainerProp8, _props$webChatContain6, _props$webChatContain7, _defaultWebChatContai2, _props$webChatContain8, _props$webChatContain9, _defaultWebChatContai3, _webChatContainerProp9, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _webChatContainerProp13, _webChatContainerProp14, _webChatContainerProp15, _webChatContainerProp16, _webChatContainerProp17, _webChatContainerProp18, _webChatContainerProp19, _webChatContainerProp20, _webChatContainerProp21, _webChatContainerProp22, _webChatContainerProp23, _props$webChatContain10, _props$webChatContain11, _webChatContainerProp24, _webChatContainerProp25, _webChatContainerProp26, _webChatContainerProp27, _props$citationPanePr, _props$citationPanePr2, _props$citationPanePr3, _props$citationPanePr4, _props$citationPanePr5;
59
+ var _props$webChatContain, _defaultWebChatContai, _extendedChatConfig$L, _props$persistentChat, _extendedChatConfig$L2, _extendedChatConfig$L3, _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _webChatContainerProp7, _webChatContainerProp8, _props$webChatContain6, _props$webChatContain7, _defaultWebChatContai2, _props$webChatContain8, _props$webChatContain9, _defaultWebChatContai3, _webChatContainerProp9, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _webChatContainerProp13, _webChatContainerProp14, _webChatContainerProp15, _webChatContainerProp16, _webChatContainerProp17, _webChatContainerProp18, _webChatContainerProp19, _webChatContainerProp20, _webChatContainerProp21, _webChatContainerProp22, _webChatContainerProp23, _props$webChatContain10, _props$webChatContain11, _webChatContainerProp24, _webChatContainerProp25, _webChatContainerProp26, _webChatContainerProp27, _props$persistentChat2, _props$citationPanePr, _props$citationPanePr2, _props$citationPanePr3, _props$citationPanePr4, _props$citationPanePr5;
60
+ const [facadeChatSDK] = useFacadeSDKStore();
61
+
53
62
  // Create a font family that includes emoji support, based on the primary font or default
54
63
  const webChatStyles = ((_props$webChatContain = props.webChatContainerProps) === null || _props$webChatContain === void 0 ? void 0 : _props$webChatContain.webChatStyles) ?? defaultWebChatContainerStatefulProps.webChatStyles;
55
64
  const primaryFont = (webChatStyles === null || webChatStyles === void 0 ? void 0 : webChatStyles.primaryFont) ?? ((_defaultWebChatContai = defaultWebChatContainerStatefulProps.webChatStyles) === null || _defaultWebChatContai === void 0 ? void 0 : _defaultWebChatContai.primaryFont);
@@ -70,9 +79,6 @@ export const WebChatContainerStateful = props => {
70
79
  // Guard to prevent handling multiple rapid clicks which could cause
71
80
  // the dim layer and pane to re-render out of sync and create a flicker.
72
81
  const citationOpeningRef = useRef(false);
73
-
74
- // ...existing code...
75
-
76
82
  const {
77
83
  BasicWebChat
78
84
  } = Components;
@@ -82,6 +88,21 @@ export const WebChatContainerStateful = props => {
82
88
  contextDataStore
83
89
  } = props;
84
90
 
91
+ // Type the chatConfig properly to avoid 'any' usage
92
+ const extendedChatConfig = props.chatConfig;
93
+ const isHistoryEnabledInConfig = extendedChatConfig === null || extendedChatConfig === void 0 ? void 0 : (_extendedChatConfig$L = extendedChatConfig.LcwFcbConfiguration) === null || _extendedChatConfig$L === void 0 ? void 0 : _extendedChatConfig$L.lcwPersistentChatHistoryEnabled;
94
+ const isHistoryEnabledViaProps = props === null || props === void 0 ? void 0 : (_props$persistentChat = props.persistentChatHistoryProps) === null || _props$persistentChat === void 0 ? void 0 : _props$persistentChat.persistentChatHistoryEnabled;
95
+ const isPersistentChatEnabledForWidget = !!(extendedChatConfig !== null && extendedChatConfig !== void 0 && (_extendedChatConfig$L2 = extendedChatConfig.LiveChatConfigAuthSettings) !== null && _extendedChatConfig$L2 !== void 0 && _extendedChatConfig$L2.msdyn_javascriptclientfunction) || isPersistentChatEnabled(extendedChatConfig === null || extendedChatConfig === void 0 ? void 0 : (_extendedChatConfig$L3 = extendedChatConfig.LiveWSAndLiveChatEngJoin) === null || _extendedChatConfig$L3 === void 0 ? void 0 : _extendedChatConfig$L3.msdyn_conversationmode);
96
+
97
+ // Persistent chat history is enabled if explicitly set via props, or if enabled in config
98
+ // Props take precedence over config settings
99
+ const isPersistentHistoryEnabled = isHistoryEnabledViaProps || isHistoryEnabledInConfig;
100
+
101
+ // Check if both persistent chat and widget support are enabled
102
+ const shouldLoadPersistentHistoryMessages = isPersistentHistoryEnabled && isPersistentChatEnabledForWidget;
103
+ if (shouldLoadPersistentHistoryMessages) {
104
+ usePersistentChatHistory(facadeChatSDK, (props === null || props === void 0 ? void 0 : props.persistentChatHistoryProps) ?? {});
105
+ }
85
106
  // Delegated click handler for citation anchors. Placed after state is
86
107
  // available so we can prefer reading citations from app state and fall
87
108
  // back to the legacy window map for backward-compatibility in tests.
@@ -383,7 +404,15 @@ export const WebChatContainerStateful = props => {
383
404
  `), /*#__PURE__*/React.createElement(Stack, {
384
405
  styles: containerStyles,
385
406
  className: "webchat__stacked-layout_container"
386
- }, /*#__PURE__*/React.createElement(BasicWebChat, null)), citationPaneOpen && /*#__PURE__*/React.createElement(CitationPaneStateful, {
407
+ }, /*#__PURE__*/React.createElement("div", {
408
+ id: "ms_lcw_webchat_root",
409
+ style: {
410
+ height: "100%",
411
+ width: "100%"
412
+ }
413
+ }, shouldLoadPersistentHistoryMessages && /*#__PURE__*/React.createElement(WebChatEventSubscribers, {
414
+ persistentChatHistoryEnabled: props === null || props === void 0 ? void 0 : (_props$persistentChat2 = props.persistentChatHistoryProps) === null || _props$persistentChat2 === void 0 ? void 0 : _props$persistentChat2.persistentChatHistoryEnabled
415
+ }), /*#__PURE__*/React.createElement(BasicWebChat, null))), citationPaneOpen && /*#__PURE__*/React.createElement(CitationPaneStateful, {
387
416
  id: ((_props$citationPanePr = props.citationPaneProps) === null || _props$citationPanePr === void 0 ? void 0 : _props$citationPanePr.id) || HtmlAttributeNames.ocwCitationPaneClassName,
388
417
  title: ((_props$citationPanePr2 = props.citationPaneProps) === null || _props$citationPanePr2 === void 0 ? void 0 : _props$citationPanePr2.title) || HtmlAttributeNames.ocwCitationPaneTitle,
389
418
  contentHtml: citationPaneText,
@@ -0,0 +1,7 @@
1
+ const botActivity = {
2
+ from: {
3
+ role: "bot"
4
+ },
5
+ type: "message"
6
+ };
7
+ export default botActivity;
@@ -0,0 +1,9 @@
1
+ import { Constants } from "../../../../common/Constants";
2
+ import botActivity from "./botActivity";
3
+ const conversationDividerActivity = {
4
+ ...botActivity,
5
+ channelData: {
6
+ tags: [Constants.conversationDividerTag]
7
+ }
8
+ };
9
+ export default conversationDividerActivity;
@@ -0,0 +1,90 @@
1
+ import { Constants } from "../../../../common/Constants";
2
+ import botActivity from "../activities/botActivity";
3
+
4
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
+ const convertStringValueToInt = value => {
6
+ if (typeof value !== "string" || value === "") {
7
+ return undefined;
8
+ }
9
+ let result;
10
+ try {
11
+ result = parseInt(value);
12
+ } catch (e) {
13
+ return undefined;
14
+ }
15
+ return isNaN(result) ? undefined : result;
16
+ };
17
+
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ const convertPersistentChatHistoryMessageToActivity = message => {
20
+ var _from$user, _from$application;
21
+ const {
22
+ additionalData,
23
+ attachments,
24
+ content,
25
+ created,
26
+ from,
27
+ transcriptOriginalMessageId
28
+ } = message;
29
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
+ const activity = {
31
+ ...botActivity,
32
+ channelData: {
33
+ tags: [Constants.persistentChatHistoryMessageTag]
34
+ }
35
+ };
36
+ let webchatSequenceId;
37
+ let timestamp;
38
+ if (transcriptOriginalMessageId) {
39
+ const id = convertStringValueToInt(transcriptOriginalMessageId); // Id used to determine the sequence of messages which is the same as the 'live' messages
40
+ if (id) {
41
+ webchatSequenceId = id;
42
+ timestamp = new Date(id) || created;
43
+ activity.channelData = {
44
+ ...activity.channelData,
45
+ "webchat:sequence-id": webchatSequenceId
46
+ };
47
+ }
48
+ }
49
+ if (additionalData !== null && additionalData !== void 0 && additionalData.tags) {
50
+ const {
51
+ tags,
52
+ ConversationId
53
+ } = additionalData;
54
+ if (ConversationId) {
55
+ activity.channelData.conversationId = ConversationId;
56
+ }
57
+ if (tags) {
58
+ const formattedTags = additionalData.tags.split(",");
59
+ activity.channelData.tags = [...activity.channelData.tags, ...formattedTags];
60
+ }
61
+ }
62
+ if (from !== null && from !== void 0 && (_from$user = from.user) !== null && _from$user !== void 0 && _from$user.displayName) {
63
+ activity.from.name = from.user.displayName;
64
+ }
65
+ if ((from === null || from === void 0 ? void 0 : (_from$application = from.application) === null || _from$application === void 0 ? void 0 : _from$application.displayName) === "Customer") {
66
+ activity.from = {
67
+ role: "user",
68
+ name: from.application.displayName
69
+ };
70
+ }
71
+ if (content) {
72
+ return {
73
+ ...activity,
74
+ text: content,
75
+ timestamp
76
+ };
77
+ }
78
+ if (attachments && attachments.length > 0) {
79
+ const fileName = attachments[0].name || "Unknown";
80
+ const text = `The following attachment was uploaded during the conversation: ${fileName}`;
81
+ return {
82
+ ...activity,
83
+ text,
84
+ timestamp
85
+ };
86
+ }
87
+ // If neither content nor attachments are present, return null to indicate no activity could be created.
88
+ return null;
89
+ };
90
+ export default convertPersistentChatHistoryMessageToActivity;
@@ -28,5 +28,6 @@ export const defaultMiddlewareLocalizedTexts = {
28
28
  THIRD_PARTY_COOKIES_BLOCKED_ALERT_MESSAGE: "Allow sites to save/read cookies in browser settings. Reloading page starts a new chat.",
29
29
  MIDDLEWARE_BANNER_FILE_IS_MALICIOUS: "{0} has been blocked because the file may contain a malware.",
30
30
  MIDDLEWARE_BANNER_FILE_EMAIL_ADDRESS_RECORDED_SUCCESS: "Email will be sent after chat ends!",
31
- MIDDLEWARE_BANNER_FILE_EMAIL_ADDRESS_RECORDED_ERROR: "Email {0} could not be saved, try again later."
31
+ MIDDLEWARE_BANNER_FILE_EMAIL_ADDRESS_RECORDED_ERROR: "Email {0} could not be saved, try again later.",
32
+ PREVIOUS_MESSAGES_LOADING: "Loading previous messages..."
32
33
  };
@@ -1,9 +1,9 @@
1
- import { activityStatusMiddleware } from "../../webchatcontroller/middlewares/renderingmiddlewares/activityStatusMiddleware";
1
+ import { createActivityStatusMiddleware } from "../../webchatcontroller/middlewares/renderingmiddlewares/activityStatusMiddleware";
2
2
  import { groupActivitiesMiddleware } from "../../webchatcontroller/middlewares/renderingmiddlewares/groupActivitiesMiddleware";
3
3
  import { typingIndicatorMiddleware } from "../../webchatcontroller/middlewares/renderingmiddlewares/typingIndicatorMiddleware";
4
4
  export const defaultWebChatStatefulProps = {
5
5
  // activityMiddleware: activityMiddleware, - this is implemented elsewhere and can be customized
6
- activityStatusMiddleware: activityStatusMiddleware,
6
+ activityStatusMiddleware: createActivityStatusMiddleware(),
7
7
  // avatarMiddleware: avatarMiddleware, - this is implemented elsewhere and can be customized
8
8
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
9
  groupActivitiesMiddleware: groupActivitiesMiddleware,
@@ -0,0 +1,51 @@
1
+ import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
2
+ import { useEffect, useRef } from "react";
3
+ import ChatWidgetEvents from "../../livechatwidget/common/ChatWidgetEvents";
4
+ import PersistentConversationHandler from "../../livechatwidget/common/PersistentConversationHandler";
5
+ import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
6
+ import dispatchCustomEvent from "../../../common/utils/dispatchCustomEvent";
7
+ import SecureEventBus from "../../../common/utils/SecureEventBus";
8
+ const usePersistentChatHistory = (facadeChatSDK, props) => {
9
+ const handlerRef = useRef(null);
10
+ useEffect(() => {
11
+ if (!facadeChatSDK) {
12
+ return;
13
+ }
14
+ TelemetryHelper.logLoadingEventToAllTelemetry(LogLevel.INFO, {
15
+ Event: TelemetryEvent.UXLCWPersistentChatHistoryInitialized,
16
+ Description: "Persistent chat history hook initialized"
17
+ });
18
+ handlerRef.current = new PersistentConversationHandler(facadeChatSDK, props);
19
+ const handler = async () => {
20
+ TelemetryHelper.logActionEventToAllTelemetry(LogLevel.INFO, {
21
+ Event: TelemetryEvent.LCWPersistentChatHistoryFetchStarted,
22
+ Description: "Persistent chat history fetch started"
23
+ });
24
+ try {
25
+ var _handlerRef$current;
26
+ await ((_handlerRef$current = handlerRef.current) === null || _handlerRef$current === void 0 ? void 0 : _handlerRef$current.pullHistory());
27
+ dispatchCustomEvent(ChatWidgetEvents.HIDE_LOADING_BANNER);
28
+ TelemetryHelper.logActionEventToAllTelemetry(LogLevel.INFO, {
29
+ Event: TelemetryEvent.LCWPersistentChatHistoryFetchCompleted,
30
+ Description: "Persistent chat history fetch completed successfully"
31
+ });
32
+ } catch (error) {
33
+ TelemetryHelper.logActionEventToAllTelemetry(LogLevel.ERROR, {
34
+ Event: TelemetryEvent.LCWPersistentChatHistoryFetchFailed,
35
+ Description: "Persistent chat history fetch failed",
36
+ ExceptionDetails: error
37
+ });
38
+ }
39
+ };
40
+
41
+ // Subscribe to the secure event bus instead of global window events
42
+ const eventBus = SecureEventBus.getInstance();
43
+ const unsubscribe = eventBus.subscribe(ChatWidgetEvents.FETCH_PERSISTENT_CHAT_HISTORY, handler);
44
+ return () => {
45
+ var _handlerRef$current2;
46
+ unsubscribe();
47
+ (_handlerRef$current2 = handlerRef.current) === null || _handlerRef$current2 === void 0 ? void 0 : _handlerRef$current2.destroy(); // Call destroy instead of reset to properly clean up
48
+ };
49
+ }, [facadeChatSDK]);
50
+ };
51
+ export default usePersistentChatHistory;
@@ -0,0 +1,115 @@
1
+ import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
2
+ import { useEffect, useState } from "react";
3
+ import ChatWidgetEvents from "../../livechatwidget/common/ChatWidgetEvents";
4
+ import { Constants } from "../../../common/Constants";
5
+ import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
6
+ import { WebChatStoreLoader } from "./WebChatStoreLoader";
7
+ import { createTimer } from "../../../common/utils";
8
+ import dispatchCustomEvent from "../../../common/utils/dispatchCustomEvent";
9
+
10
+ /**
11
+ * Component to handle persistent chat history events.
12
+ * Uses WebChatStoreLoader instead of hooks to avoid context issues.
13
+ */
14
+ const WebChatEventSubscribers = props => {
15
+ const [isConnected, setIsConnected] = useState(false);
16
+ const [storeReady, setStoreReady] = useState(false);
17
+ const storeWaitTimer = createTimer();
18
+ useEffect(() => {
19
+ if (!props.persistentChatHistoryEnabled) {
20
+ return;
21
+ }
22
+ TelemetryHelper.logActionEventToAllTelemetry(LogLevel.INFO, {
23
+ Event: TelemetryEvent.LCWWebChatStorePollingStarted,
24
+ Description: "WebChat store polling started"
25
+ });
26
+
27
+ // Wait for WebChat store to be available
28
+ const waitForStore = () => {
29
+ if (WebChatStoreLoader.store) {
30
+ setStoreReady(true);
31
+ TelemetryHelper.logActionEventToAllTelemetry(LogLevel.INFO, {
32
+ Event: TelemetryEvent.LCWWebChatStoreReady,
33
+ Description: "WebChat store ready",
34
+ ElapsedTimeInMilliseconds: storeWaitTimer.milliSecondsElapsed
35
+ });
36
+ return true;
37
+ }
38
+ return false;
39
+ };
40
+
41
+ // Check if store is already available
42
+ if (!waitForStore()) {
43
+ // Poll for store availability
44
+ const storeCheckInterval = setInterval(() => {
45
+ if (waitForStore()) {
46
+ clearInterval(storeCheckInterval);
47
+ }
48
+ }, 100);
49
+ return () => {
50
+ clearInterval(storeCheckInterval);
51
+ };
52
+ }
53
+ }, [props.persistentChatHistoryEnabled]);
54
+ useEffect(() => {
55
+ if (!props.persistentChatHistoryEnabled || !storeReady) {
56
+ return;
57
+ }
58
+ const checkConnectionStatus = () => {
59
+ try {
60
+ if (WebChatStoreLoader.store) {
61
+ const state = WebChatStoreLoader.store.getState();
62
+ const connectivityStatus = state === null || state === void 0 ? void 0 : state.connectivityStatus;
63
+ const newIsConnected = connectivityStatus === "connected";
64
+ if (newIsConnected && !isConnected) {
65
+ setIsConnected(true);
66
+ TelemetryHelper.logActionEventToAllTelemetry(LogLevel.INFO, {
67
+ Event: TelemetryEvent.LCWWebChatConnected,
68
+ Description: "WebChat connection established, dispatching events"
69
+ });
70
+
71
+ // Dispatch events when connection is established
72
+ setTimeout(() => {
73
+ dispatchCustomEvent(ChatWidgetEvents.FETCH_PERSISTENT_CHAT_HISTORY);
74
+ dispatchCustomEvent(ChatWidgetEvents.ADD_ACTIVITY, {
75
+ activity: {
76
+ from: {
77
+ role: "bot"
78
+ },
79
+ timestamp: 0,
80
+ type: "message",
81
+ channelData: {
82
+ tags: [Constants.persistentChatHistoryMessagePullTriggerTag]
83
+ }
84
+ }
85
+ });
86
+ }, 2000);
87
+ } else if (!newIsConnected && isConnected) {
88
+ setIsConnected(false);
89
+ TelemetryHelper.logActionEventToAllTelemetry(LogLevel.WARN, {
90
+ Event: TelemetryEvent.LCWWebChatDisconnected,
91
+ Description: "WebChat connection lost"
92
+ });
93
+ }
94
+ }
95
+ } catch (error) {
96
+ TelemetryHelper.logActionEventToAllTelemetry(LogLevel.ERROR, {
97
+ Event: TelemetryEvent.LCWWebChatConnectionCheckFailed,
98
+ Description: "WebChat connection status check failed",
99
+ ExceptionDetails: error
100
+ });
101
+ }
102
+ };
103
+
104
+ // Check immediately
105
+ checkConnectionStatus();
106
+
107
+ // Set up interval to check connection status
108
+ const interval = setInterval(checkConnectionStatus, 1000);
109
+ return () => {
110
+ clearInterval(interval);
111
+ };
112
+ }, [isConnected, props.persistentChatHistoryEnabled, storeReady]);
113
+ return null;
114
+ };
115
+ export default WebChatEventSubscribers;
@@ -0,0 +1,3 @@
1
+ export const LazyLoadActivityConstants = {
2
+ SCROLL_ID: ".webchat__basic-transcript__scrollable"
3
+ };
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { defaultPersistentChatHistoryProps } from "../../../../../livechatwidget/common/defaultProps/defaultPersistentChatHistoryProps";
3
+ import { mergeStyles } from "@fluentui/react";
4
+ const ConversationDividerActivity = props => {
5
+ const styleApplied = mergeStyles(defaultPersistentChatHistoryProps.dividerActivityStyle, props.dividerActivityStyle);
6
+ return /*#__PURE__*/React.createElement("div", {
7
+ className: styleApplied
8
+ });
9
+ };
10
+ export default ConversationDividerActivity;