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

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 (83) hide show
  1. package/README.md +27 -0
  2. package/lib/cjs/common/Constants.js +2 -0
  3. package/lib/cjs/common/telemetry/AppInsightsEvents.js +11 -5
  4. package/lib/cjs/common/telemetry/TelemetryConstants.js +3 -0
  5. package/lib/cjs/common/telemetry/TelemetryManager.js +10 -7
  6. package/lib/cjs/common/telemetry/loggers/appInsightsLogger.js +7 -7
  7. package/lib/cjs/common/utils.js +14 -1
  8. package/lib/cjs/components/citationpanestateful/CitationPaneStateful.js +20 -1
  9. package/lib/cjs/components/errorboundary/ErrorBoundary.js +2 -1
  10. package/lib/cjs/components/livechatwidget/common/ChatWidgetEvents.js +1 -1
  11. package/lib/cjs/components/livechatwidget/common/PersistentConversationHandler.js +26 -20
  12. package/lib/cjs/components/livechatwidget/common/defaultProps/defaultPersistentChatHistoryProps.js +1 -2
  13. package/lib/cjs/components/livechatwidget/common/endChat.js +26 -9
  14. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +9 -2
  15. package/lib/cjs/components/livechatwidget/common/liveChatConfigUtils.js +36 -4
  16. package/lib/cjs/components/livechatwidget/common/registerTelemetryLoggers.js +3 -0
  17. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +113 -26
  18. package/lib/cjs/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +8 -6
  19. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +28 -30
  20. package/lib/cjs/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +8 -2
  21. package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +2 -1
  22. package/lib/cjs/components/webchatcontainerstateful/hooks/usePersistentChatHistory.js +1 -3
  23. package/lib/cjs/components/webchatcontainerstateful/interfaces/IExtendedChatConffig.js +1 -0
  24. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.js +6 -7
  25. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/ConversationDividerActivity.js +30 -1
  26. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.js +21 -1
  27. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +7 -2
  28. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +2 -0
  29. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.js +6 -1
  30. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +29 -7
  31. package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +1 -0
  32. package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +7 -1
  33. package/lib/cjs/contexts/createReducer.js +15 -0
  34. package/lib/esm/common/Constants.js +2 -0
  35. package/lib/esm/common/telemetry/AppInsightsEvents.js +11 -5
  36. package/lib/esm/common/telemetry/TelemetryConstants.js +3 -0
  37. package/lib/esm/common/telemetry/TelemetryManager.js +10 -7
  38. package/lib/esm/common/telemetry/loggers/appInsightsLogger.js +7 -7
  39. package/lib/esm/common/utils.js +11 -0
  40. package/lib/esm/components/citationpanestateful/CitationPaneStateful.js +20 -1
  41. package/lib/esm/components/errorboundary/ErrorBoundary.js +4 -2
  42. package/lib/esm/components/livechatwidget/common/ChatWidgetEvents.js +1 -1
  43. package/lib/esm/components/livechatwidget/common/PersistentConversationHandler.js +26 -20
  44. package/lib/esm/components/livechatwidget/common/defaultProps/defaultPersistentChatHistoryProps.js +1 -2
  45. package/lib/esm/components/livechatwidget/common/endChat.js +26 -9
  46. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +9 -2
  47. package/lib/esm/components/livechatwidget/common/liveChatConfigUtils.js +33 -2
  48. package/lib/esm/components/livechatwidget/common/registerTelemetryLoggers.js +3 -0
  49. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +113 -26
  50. package/lib/esm/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +8 -6
  51. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +29 -34
  52. package/lib/esm/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +8 -2
  53. package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +2 -1
  54. package/lib/esm/components/webchatcontainerstateful/hooks/usePersistentChatHistory.js +1 -3
  55. package/lib/esm/components/webchatcontainerstateful/interfaces/IExtendedChatConffig.js +1 -0
  56. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.js +6 -7
  57. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/ConversationDividerActivity.js +30 -1
  58. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.js +21 -1
  59. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +7 -2
  60. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +2 -0
  61. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.js +1 -0
  62. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.js +6 -1
  63. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +29 -7
  64. package/lib/esm/contexts/common/LiveChatWidgetActionType.js +1 -0
  65. package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +7 -1
  66. package/lib/esm/contexts/createReducer.js +15 -0
  67. package/lib/types/common/Constants.d.ts +2 -0
  68. package/lib/types/common/telemetry/TelemetryConstants.d.ts +3 -0
  69. package/lib/types/common/telemetry/interfaces/IInternalTelemetryData.d.ts +1 -0
  70. package/lib/types/common/utils.d.ts +9 -1
  71. package/lib/types/components/errorboundary/ErrorBoundary.d.ts +1 -1
  72. package/lib/types/components/livechatwidget/common/ChatWidgetEvents.d.ts +1 -1
  73. package/lib/types/components/livechatwidget/common/liveChatConfigUtils.d.ts +11 -0
  74. package/lib/types/components/livechatwidget/interfaces/IPersistentChatHistoryProps.d.ts +5 -1
  75. package/lib/types/components/webchatcontainerstateful/interfaces/IExtendedChatConffig.d.ts +15 -0
  76. package/lib/types/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.d.ts +1 -2
  77. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.d.ts +1 -1
  78. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.d.ts +2 -1
  79. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.d.ts +1 -1
  80. package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +1 -0
  81. package/lib/types/contexts/common/ILiveChatWidgetLocalizedTexts.d.ts +5 -0
  82. package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +2 -1
  83. package/package.json +2 -2
@@ -30,7 +30,7 @@ let PersistentConversationHandler = /*#__PURE__*/function () {
30
30
  _defineProperty(this, "facadeChatSDK", void 0);
31
31
  _defineProperty(this, "lastMessage", null);
32
32
  _defineProperty(this, "count", 0);
33
- _defineProperty(this, "pageSize", 4);
33
+ _defineProperty(this, "pageSize", defaultPersistentChatHistoryProps.pageSize);
34
34
  _defineProperty(this, "isCurrentlyPulling", false);
35
35
  _defineProperty(this, "pageTokenInTransitSet", new Set());
36
36
  _defineProperty(this, "resetEventListener", BroadcastService.getMessageByEventName(BroadcastEvent.PersistentConversationReset).subscribe(() => {
@@ -42,18 +42,21 @@ let PersistentConversationHandler = /*#__PURE__*/function () {
42
42
  Event: TelemetryEvent.LCWPersistentConversationHandlerInitialized,
43
43
  Description: "PersistentConversationHandler initialized",
44
44
  CustomProperties: {
45
- pageSize: this.pageSize
45
+ pageSize: defaultPersistentChatHistoryProps.pageSize
46
46
  }
47
47
  });
48
48
  }
49
49
  _createClass(PersistentConversationHandler, [{
50
50
  key: "appliedPropsHandler",
51
51
  value: function appliedPropsHandler(props) {
52
+ var _this$appliedProps;
52
53
  this.appliedProps = {
53
54
  ...defaultPersistentChatHistoryProps,
54
55
  ...props
55
56
  };
56
- this.pageSize = this.appliedProps.pageSize || 4;
57
+
58
+ // if the props is not existent or is not a number then default to defaultPersistentChatHistoryProps.pageSize
59
+ this.pageSize = ((_this$appliedProps = this.appliedProps) === null || _this$appliedProps === void 0 ? void 0 : _this$appliedProps.pageSize) !== undefined && !isNaN(this.appliedProps.pageSize) ? this.appliedProps.pageSize : defaultPersistentChatHistoryProps.pageSize;
57
60
  }
58
61
  }, {
59
62
  key: "reset",
@@ -98,12 +101,23 @@ let PersistentConversationHandler = /*#__PURE__*/function () {
98
101
  try {
99
102
  var _ref;
100
103
  const messages = await this.fetchHistoryMessages();
101
- if (messages === null || (messages === null || messages === void 0 ? void 0 : messages.length) === 0) {
104
+
105
+ // Handle error case - null indicates an error occurred
106
+ // Don't mark as last pull to allow retry on next attempt
107
+ if (messages == null) {
108
+ TelemetryHelper.logActionEvent(LogLevel.WARN, {
109
+ Event: TelemetryEvent.LCWPersistentHistoryReturnedNull,
110
+ Description: "History pull returned null - Possible error occurred, will retry on next scroll",
111
+ ElapsedTimeInMilliseconds: pullTimer.milliSecondsElapsed
112
+ });
113
+ return;
114
+ }
115
+
116
+ // Handle legitimate end of history - empty array
117
+ if (messages.length === 0) {
102
118
  this.isLastPull = true;
103
119
  // Dispatch event to notify UI that no more history is available
104
120
  dispatchCustomEvent(ChatWidgetEvents.NO_MORE_HISTORY_AVAILABLE);
105
- // Also hide the loading banner
106
- dispatchCustomEvent(ChatWidgetEvents.HIDE_LOADING_BANNER);
107
121
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
108
122
  Event: TelemetryEvent.LCWPersistentHistoryPullCompleted,
109
123
  Description: "History pull completed - no more messages",
@@ -113,9 +127,6 @@ let PersistentConversationHandler = /*#__PURE__*/function () {
113
127
  }
114
128
  const messagesDescOrder = (_ref = [...messages]) === null || _ref === void 0 ? void 0 : _ref.reverse();
115
129
  this.processHistoryMessages(messagesDescOrder);
116
-
117
- // Dispatch event to hide the loading banner after messages are processed
118
- dispatchCustomEvent(ChatWidgetEvents.HIDE_LOADING_BANNER);
119
130
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
120
131
  Event: TelemetryEvent.LCWPersistentHistoryPullCompleted,
121
132
  Description: "History pull completed successfully",
@@ -171,7 +182,6 @@ let PersistentConversationHandler = /*#__PURE__*/function () {
171
182
  if (!this.shouldPull()) {
172
183
  // Dispatch event to ensure banner is hidden when no more pulls are needed
173
184
  dispatchCustomEvent(ChatWidgetEvents.NO_MORE_HISTORY_AVAILABLE);
174
- dispatchCustomEvent(ChatWidgetEvents.HIDE_LOADING_BANNER);
175
185
  return [];
176
186
  }
177
187
  const options = {
@@ -197,24 +207,20 @@ let PersistentConversationHandler = /*#__PURE__*/function () {
197
207
  this.isLastPull = true;
198
208
  // Dispatch event when we reach the end of available history
199
209
  dispatchCustomEvent(ChatWidgetEvents.NO_MORE_HISTORY_AVAILABLE);
200
- // Also hide the loading banner
201
- dispatchCustomEvent(ChatWidgetEvents.HIDE_LOADING_BANNER);
202
210
  return [];
203
211
  }
204
- dispatchCustomEvent(ChatWidgetEvents.HIDE_LOADING_BANNER);
205
212
  return messages;
206
213
  } catch (error) {
207
214
  TelemetryHelper.logSDKEvent(LogLevel.ERROR, {
208
215
  Event: TelemetryEvent.FetchPersistentChatHistoryFailed,
209
216
  ExceptionDetails: error
210
217
  });
211
- this.isLastPull = true;
212
- this.pageToken = null;
213
- // Dispatch event when there's an error to stop loading banner
214
- dispatchCustomEvent(ChatWidgetEvents.NO_MORE_HISTORY_AVAILABLE);
215
- // Also hide the loading banner
216
- dispatchCustomEvent(ChatWidgetEvents.HIDE_LOADING_BANNER);
217
- return [];
218
+
219
+ // On error, dispatch HISTORY_LOAD_ERROR to hide loading banner without marking conversation as ended
220
+ // This allows recovery on the next attempt (e.g., transient network errors)
221
+ // Return null to distinguish error from legitimate empty history
222
+ dispatchCustomEvent(ChatWidgetEvents.HISTORY_LOAD_ERROR);
223
+ return null;
218
224
  }
219
225
  }
220
226
  }, {
@@ -1,6 +1,5 @@
1
1
  export const defaultPersistentChatHistoryProps = {
2
- persistentChatHistoryEnabled: true,
3
- pageSize: 4,
2
+ pageSize: 10,
4
3
  dividerActivityStyle: {
5
4
  border: "1px solid rgb(96, 94, 92, 0.5)",
6
5
  margin: "10px 20%"
@@ -6,6 +6,8 @@ import { BroadcastService } from "@microsoft/omnichannel-chat-components";
6
6
  import { ConversationState } from "../../../contexts/common/ConversationState";
7
7
  import { LazyLoadHandler } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity";
8
8
  import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
9
+ import { NotificationHandler } from "../../webchatcontainerstateful/webchatcontroller/notification/NotificationHandler";
10
+ import { NotificationScenarios } from "../../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios";
9
11
  import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
10
12
  import { TelemetryManager } from "../../../common/telemetry/TelemetryManager";
11
13
  import { WebChatStoreLoader } from "../../webchatcontainerstateful/webchatcontroller/WebChatStoreLoader";
@@ -195,6 +197,18 @@ const endChat = async (props, facadeChatSDK, state, dispatch, setAdapter, setWeb
195
197
  facadeChatSDK.destroy();
196
198
  }
197
199
  }
200
+
201
+ //moving logic below to before processing skipCloseChat logic to avoid race conditions of postMessage for endChatEvent for other tabs vs postMessage for CloseChat
202
+ //TODO: clarify if this postMessageToOtherTab actually works in production.
203
+ if (postMessageToOtherTab) {
204
+ const endChatEventName = await getEndChatEventName(facadeChatSDK, props);
205
+ BroadcastService.postMessage({
206
+ eventName: endChatEventName,
207
+ payload: {
208
+ runtimeId: TelemetryManager.InternalTelemetryData.lcwRuntimeId
209
+ }
210
+ });
211
+ }
198
212
  if (!skipCloseChat) {
199
213
  try {
200
214
  var _props$webChatContain;
@@ -234,17 +248,17 @@ const endChat = async (props, facadeChatSDK, state, dispatch, setAdapter, setWeb
234
248
  });
235
249
  closeChatWidget(dispatch, setWebChatStyles, props);
236
250
  facadeChatSDK.destroy();
251
+
252
+ //always post the close chat event after chat closed and cleanup completed
253
+ BroadcastService.postMessage({
254
+ eventName: BroadcastEvent.CloseChat
255
+ });
256
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
257
+ Event: TelemetryEvent.CloseChatCall,
258
+ Description: "Broadcasted close chat event"
259
+ });
237
260
  }
238
261
  }
239
- if (postMessageToOtherTab) {
240
- const endChatEventName = await getEndChatEventName(facadeChatSDK, props);
241
- BroadcastService.postMessage({
242
- eventName: endChatEventName,
243
- payload: {
244
- runtimeId: TelemetryManager.InternalTelemetryData.lcwRuntimeId
245
- }
246
- });
247
- }
248
262
  };
249
263
  export const callingStateCleanUp = dispatch => {
250
264
  dispatch({
@@ -322,6 +336,9 @@ export const closeChatStateCleanUp = dispatch => {
322
336
  payload: {}
323
337
  });
324
338
 
339
+ // Dismiss the chat disconnect notification banner if it was shown
340
+ NotificationHandler.dismissNotification(NotificationScenarios.ChatDisconnect);
341
+
325
342
  // Clear live chat context only if chat widget is fully closed to support transcript calls after sessionclose is called
326
343
  dispatch({
327
344
  type: LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
@@ -120,7 +120,14 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
120
120
  };
121
121
  webChatStore = createStore({},
122
122
  //initial state
123
- preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), createCustomEventMiddleware(BroadcastService), createQueueOverflowMiddleware(state, dispatch), channelDataMiddleware(addConversationalSurveyTagsCallback), createConversationEndMiddleware(conversationEndCallback, startConversationalSurveyCallback, endConversationalSurveyCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, createMessageSequenceIdOverrideMiddleware, createCitationsMiddleware(state, dispatch), gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware(honorsTargetInHTMLLinks), createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware, createCallActionMiddleware(), localizedStringsBotInitialsMiddleware(),
123
+ preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), createCustomEventMiddleware(BroadcastService), createQueueOverflowMiddleware(state, dispatch), channelDataMiddleware(addConversationalSurveyTagsCallback), createConversationEndMiddleware(conversationEndCallback, startConversationalSurveyCallback, endConversationalSurveyCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, createMessageSequenceIdOverrideMiddleware, createCitationsMiddleware(state, dispatch), gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware(honorsTargetInHTMLLinks), createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware, createCallActionMiddleware(),
124
+ // Pass a callback so middleware can push initials into React context for reactivity
125
+ localizedStringsBotInitialsMiddleware(initials => {
126
+ dispatch({
127
+ type: LiveChatWidgetActionType.SET_BOT_AVATAR_INITIALS,
128
+ payload: initials
129
+ });
130
+ }),
124
131
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
125
132
  ...(((_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.storeMiddlewares) ?? []));
126
133
  WebChatStoreLoader.store = webChatStore;
@@ -163,7 +170,7 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
163
170
  dir: state.domainStates.globalDir,
164
171
  locale: changeLanguageCodeFormatForWebChat(getLocaleStringFromId((_state$domainStates$l4 = state.domainStates.liveChatConfig) === null || _state$domainStates$l4 === void 0 ? void 0 : (_state$domainStates$l5 = _state$domainStates$l4.ChatWidgetLanguage) === null || _state$domainStates$l5 === void 0 ? void 0 : _state$domainStates$l5.msdyn_localeid)),
165
172
  store: webChatStore,
166
- activityMiddleware: (_props$webChatContain11 = props.webChatContainerProps) !== null && _props$webChatContain11 !== void 0 && (_props$webChatContain12 = _props$webChatContain11.renderingMiddlewareProps) !== null && _props$webChatContain12 !== void 0 && _props$webChatContain12.disableActivityMiddleware ? undefined : createActivityMiddleware(renderMarkdown, (_state$domainStates$r = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r === void 0 ? void 0 : _state$domainStates$r.systemMessageStyleProps, (_state$domainStates$r2 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r2 === void 0 ? void 0 : _state$domainStates$r2.userMessageStyleProps),
173
+ activityMiddleware: (_props$webChatContain11 = props.webChatContainerProps) !== null && _props$webChatContain11 !== void 0 && (_props$webChatContain12 = _props$webChatContain11.renderingMiddlewareProps) !== null && _props$webChatContain12 !== void 0 && _props$webChatContain12.disableActivityMiddleware ? undefined : createActivityMiddleware(renderMarkdown, (_state$domainStates$r = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r === void 0 ? void 0 : _state$domainStates$r.systemMessageStyleProps, (_state$domainStates$r2 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r2 === void 0 ? void 0 : _state$domainStates$r2.userMessageStyleProps, localizedTexts),
167
174
  attachmentMiddleware: (_props$webChatContain13 = props.webChatContainerProps) !== null && _props$webChatContain13 !== void 0 && (_props$webChatContain14 = _props$webChatContain13.renderingMiddlewareProps) !== null && _props$webChatContain14 !== void 0 && _props$webChatContain14.disableAttachmentMiddleware ? undefined : createAttachmentMiddleware(((_state$domainStates$r3 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r3 === void 0 ? void 0 : (_state$domainStates$r4 = _state$domainStates$r3.attachmentProps) === null || _state$domainStates$r4 === void 0 ? void 0 : _state$domainStates$r4.enableInlinePlaying) ?? defaultAttachmentProps.enableInlinePlaying),
168
175
  activityStatusMiddleware: (_props$webChatContain15 = props.webChatContainerProps) !== null && _props$webChatContain15 !== void 0 && (_props$webChatContain16 = _props$webChatContain15.renderingMiddlewareProps) !== null && _props$webChatContain16 !== void 0 && _props$webChatContain16.disableActivityStatusMiddleware ? undefined : createActivityStatusMiddleware(getLocaleStringFromId((_state$domainStates$l6 = state.domainStates.liveChatConfig) === null || _state$domainStates$l6 === void 0 ? void 0 : (_state$domainStates$l7 = _state$domainStates$l6.ChatWidgetLanguage) === null || _state$domainStates$l7 === void 0 ? void 0 : _state$domainStates$l7.msdyn_localeid)),
169
176
  toastMiddleware: (_props$webChatContain17 = props.webChatContainerProps) !== null && _props$webChatContain17 !== void 0 && (_props$webChatContain18 = _props$webChatContain17.renderingMiddlewareProps) !== null && _props$webChatContain18 !== void 0 && _props$webChatContain18.disableToastMiddleware ? undefined : createToastMiddleware(props.notificationPaneProps, endChat),
@@ -1,11 +1,13 @@
1
+ import { isNullOrUndefined, parseBooleanFromConfig } from "../../../common/utils";
1
2
  import { ConversationMode } from "../../../common/Constants";
2
- import { isNullOrUndefined } from "../../../common/utils";
3
3
  export const isPostChatSurveyEnabled = async facadeChatSDK => {
4
4
  var _chatConfig$LiveWSAnd;
5
5
  const chatConfig = await facadeChatSDK.getLiveChatConfig();
6
6
  const postChatEnabled = (_chatConfig$LiveWSAnd = chatConfig.LiveWSAndLiveChatEngJoin) === null || _chatConfig$LiveWSAnd === void 0 ? void 0 : _chatConfig$LiveWSAnd.msdyn_postconversationsurveyenable.toString().toLowerCase();
7
7
  return postChatEnabled === "true";
8
8
  };
9
+
10
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
11
  export const getPostChatSurveyConfig = async facadeChatSDK => {
10
12
  var _chatConfig$LiveWSAnd2, _chatConfig$LiveWSAnd3, _chatConfig$LiveWSAnd4, _chatConfig$LiveWSAnd5, _chatConfig$LiveWSAnd6, _chatConfig$LiveWSAnd7, _chatConfig$LiveWSAnd8, _chatConfig$LiveWSAnd9, _chatConfig$LiveWSAnd10;
11
13
  const chatConfig = await facadeChatSDK.getLiveChatConfig();
@@ -26,5 +28,34 @@ export const isPersistentChatEnabled = conversationMode => {
26
28
  if (isNullOrUndefined(conversationMode)) {
27
29
  return false;
28
30
  }
29
- return (conversationMode === null || conversationMode === void 0 ? void 0 : conversationMode.toString().toLowerCase()) === ConversationMode.Persistent;
31
+ return (conversationMode === null || conversationMode === void 0 ? void 0 : conversationMode.toString()) === ConversationMode.Persistent;
32
+ };
33
+
34
+ /**
35
+ * Determines if persistent chat history should be loaded based on all required conditions.
36
+ *
37
+ * @param extendedChatConfig - The extended chat configuration object
38
+ * @returns true if ALL conditions are met:
39
+ * 1. Conversation mode must be Persistent ("192350001")
40
+ * 2. History is enabled in admin config (msdyn_enablepersistentchatpreviousconversations)
41
+ * 3. History is enabled via feature flag (lcwPersistentChatHistoryEnabled)
42
+ */
43
+ export const shouldLoadPersistentChatHistory = extendedChatConfig => {
44
+ var _extendedChatConfig$L, _extendedChatConfig$L2, _extendedChatConfig$L3;
45
+ // CRITICAL: First check if conversation mode is persistent
46
+ // Only persistent mode ("192350001") should allow history loading
47
+ const isPersistentChatEnabledForWidget = isPersistentChatEnabled(extendedChatConfig === null || extendedChatConfig === void 0 ? void 0 : (_extendedChatConfig$L = extendedChatConfig.LiveWSAndLiveChatEngJoin) === null || _extendedChatConfig$L === void 0 ? void 0 : _extendedChatConfig$L.msdyn_conversationmode);
48
+ if (!isPersistentChatEnabledForWidget) {
49
+ return false;
50
+ }
51
+
52
+ // Check if history is enabled in admin config (handles both boolean and string "true"/"false")
53
+ const isHistoryEnabledInConfig = parseBooleanFromConfig(extendedChatConfig === null || extendedChatConfig === void 0 ? void 0 : (_extendedChatConfig$L2 = extendedChatConfig.LiveWSAndLiveChatEngJoin) === null || _extendedChatConfig$L2 === void 0 ? void 0 : _extendedChatConfig$L2.msdyn_enablepersistentchatpreviousconversations);
54
+ if (!isHistoryEnabledInConfig) {
55
+ return false;
56
+ }
57
+
58
+ // Check if history is enabled via feature flag (handles both boolean and string "true"/"false")
59
+ const isHistoryEnabledViaFCB = parseBooleanFromConfig(extendedChatConfig === null || extendedChatConfig === void 0 ? void 0 : (_extendedChatConfig$L3 = extendedChatConfig.LcwFcbConfiguration) === null || _extendedChatConfig$L3 === void 0 ? void 0 : _extendedChatConfig$L3.lcwPersistentChatHistoryEnabled);
60
+ return isHistoryEnabledViaFCB;
30
61
  };
@@ -24,7 +24,10 @@ export const registerTelemetryLoggers = (props, dispatch) => {
24
24
  appInsightsConfig: Object.assign({}, defaultAppInsightsConfig, props.appInsightsConfig)
25
25
  };
26
26
  if (props.chatConfig) {
27
+ var _props$chatConfig$Liv;
27
28
  telemetryData = TelemetryHelper.addChatConfigDataToTelemetry(props === null || props === void 0 ? void 0 : props.chatConfig, telemetryData);
29
+ //store AppInsights instrumentation key from chatConfig if present
30
+ telemetryData.chatConfigAppInsightsKey = (_props$chatConfig$Liv = props.chatConfig.LiveWSAndLiveChatEngJoin) === null || _props$chatConfig$Liv === void 0 ? void 0 : _props$chatConfig$Liv.AppInsightsInstrumentationKey;
28
31
  }
29
32
  if (!((_props$chatSDK = props.chatSDK) !== null && _props$chatSDK !== void 0 && (_props$chatSDK$omnich = _props$chatSDK.omnichannelConfig) !== null && _props$chatSDK$omnich !== void 0 && _props$chatSDK$omnich.orgId) || ((_props$chatSDK2 = props.chatSDK) === null || _props$chatSDK2 === void 0 ? void 0 : (_props$chatSDK2$omnic = _props$chatSDK2.omnichannelConfig) === null || _props$chatSDK2$omnic === void 0 ? void 0 : _props$chatSDK2$omnic.orgId.trim().length) === 0) {
30
33
  throw new Error("orgId is undefined in ChatSDK");
@@ -54,9 +54,10 @@ import { startProactiveChat } from "../common/startProactiveChat";
54
54
  import useChatAdapterStore from "../../../hooks/useChatAdapterStore";
55
55
  import useChatContextStore from "../../../hooks/useChatContextStore";
56
56
  import useFacadeSDKStore from "../../../hooks/useFacadeChatSDKStore";
57
+ import { getPostChatContext, initiatePostChat } from "../common/renderSurveyHelpers";
57
58
  let uiTimer;
58
59
  export const LiveChatWidgetStateful = props => {
59
- var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _props$webChatContain5, _props$webChatContain6, _props$webChatContain7, _props$webChatContain8, _props$webChatContain9, _props$styleProps, _props$webChatContain10, _props$webChatContain11, _props$controlProps, _props$controlProps3, _state$appStates7, _props$webChatContain15, _state$appStates14, _props$webChatContain17, _props$webChatContain18, _props$controlProps12, _props$draggableChatW, _props$draggableChatW2, _props$draggableChatW3, _props$draggableChatW4, _props$draggableChatW5, _livechatProps$webCha, _livechatProps$styleP, _livechatProps$contro, _livechatProps$contro2, _livechatProps$compon, _livechatProps$contro3, _livechatProps$compon2, _livechatProps$contro4, _livechatProps$compon3, _livechatProps$contro5, _livechatProps$compon4, _livechatProps$contro6, _livechatProps$compon5, _livechatProps$contro7, _livechatProps$compon6, _livechatProps$contro8, _livechatProps$compon7, _livechatProps$contro9, _livechatProps$compon8, _livechatProps$contro10, _livechatProps$contro11, _livechatProps$compon9, _livechatProps$contro12, _livechatProps$compon10, _livechatProps$contro13, _livechatProps$compon11, _livechatProps$compon12, _livechatProps$compon13;
60
+ var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _props$webChatContain5, _props$webChatContain6, _props$webChatContain7, _props$webChatContain8, _props$webChatContain9, _props$styleProps, _props$webChatContain10, _props$webChatContain11, _props$controlProps, _props$controlProps3, _state$appStates7, _props$webChatContain15, _state$appStates8, _props$webChatContain17, _props$webChatContain18, _props$controlProps12, _props$draggableChatW, _props$draggableChatW2, _props$draggableChatW3, _props$draggableChatW4, _props$draggableChatW5, _livechatProps$webCha, _livechatProps$styleP, _livechatProps$contro, _livechatProps$contro2, _livechatProps$compon, _livechatProps$contro3, _livechatProps$compon2, _livechatProps$contro4, _livechatProps$compon3, _livechatProps$contro5, _livechatProps$compon4, _livechatProps$contro6, _livechatProps$compon5, _livechatProps$contro7, _livechatProps$compon6, _livechatProps$contro8, _livechatProps$compon7, _livechatProps$contro9, _livechatProps$compon8, _livechatProps$contro10, _livechatProps$contro11, _livechatProps$compon9, _livechatProps$contro12, _livechatProps$compon10, _livechatProps$contro13, _livechatProps$compon11, _livechatProps$compon12, _livechatProps$compon13;
60
61
  useEffect(() => {
61
62
  uiTimer = createTimer();
62
63
  TelemetryHelper.logLoadingEventToAllTelemetry(LogLevel.INFO, {
@@ -317,7 +318,7 @@ export const LiveChatWidgetStateful = props => {
317
318
  });
318
319
  });
319
320
  BroadcastService.getMessageByEventName(BroadcastEvent.StartProactiveChat).subscribe(msg => {
320
- TelemetryHelper.logActionEventToAllTelemetry(LogLevel.INFO, {
321
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
321
322
  Event: TelemetryEvent.StartProactiveChatEventReceived,
322
323
  Description: "Start proactive chat event received."
323
324
  });
@@ -443,7 +444,7 @@ export const LiveChatWidgetStateful = props => {
443
444
  payload: msg === null || msg === void 0 ? void 0 : (_msg$payload8 = msg.payload) === null || _msg$payload8 === void 0 ? void 0 : _msg$payload8.customContext
444
445
  });
445
446
  }
446
- TelemetryHelper.logActionEventToAllTelemetry(LogLevel.INFO, {
447
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
447
448
  Event: TelemetryEvent.StartChatEventReceived,
448
449
  Description: "Start chat event received."
449
450
  });
@@ -490,21 +491,91 @@ export const LiveChatWidgetStateful = props => {
490
491
  return;
491
492
  }
492
493
  });
494
+ const handleInitiateEndChatForPersistentChat = async (msg, conversationDetails) => {
495
+ var _msg$payload10, _msg$payload11, _msg$payload12;
496
+ //If the payload does NOT include the skipSessionCloseForPersistentChat flag, default is false. Upon receiving the customer event, always ending session from C2.
497
+ const skipSessionCloseForPersistentChat = typeof (msg === null || msg === void 0 ? void 0 : (_msg$payload10 = msg.payload) === null || _msg$payload10 === void 0 ? void 0 : _msg$payload10[Constants.SkipSessionCloseForPersistentChatFlag]) === Constants.String && (msg === null || msg === void 0 ? void 0 : (_msg$payload11 = msg.payload) === null || _msg$payload11 === void 0 ? void 0 : _msg$payload11[Constants.SkipSessionCloseForPersistentChatFlag]).toLowerCase() === Constants.true || (msg === null || msg === void 0 ? void 0 : (_msg$payload12 = msg.payload) === null || _msg$payload12 === void 0 ? void 0 : _msg$payload12[Constants.SkipSessionCloseForPersistentChatFlag]) === true;
498
+ TelemetryHelper.logSDKEventToAllTelemetry(LogLevel.INFO, {
499
+ Event: TelemetryEvent.EndChatEventReceived,
500
+ Description: "Processing initiateEndChat for persistent chat",
501
+ CustomProperties: {
502
+ conversationDetails
503
+ }
504
+ });
505
+ const conversationState = conversationDetails === null || conversationDetails === void 0 ? void 0 : conversationDetails.state;
506
+ if (conversationState !== LiveWorkItemState.Closed && conversationState !== LiveWorkItemState.WrapUp) {
507
+ if (skipSessionCloseForPersistentChat) {
508
+ var _conversationDetails$;
509
+ if (((_conversationDetails$ = conversationDetails.canRenderPostChat) === null || _conversationDetails$ === void 0 ? void 0 : _conversationDetails$.toLowerCase()) === "true") {
510
+ var _state$domainStates3;
511
+ TelemetryHelper.logSDKEventToAllTelemetry(LogLevel.INFO, {
512
+ Event: TelemetryEvent.EndChatEventReceived,
513
+ Description: "Processing initiateEndChat, fetching postChatContext"
514
+ });
515
+ const postchatContext = (await getPostChatContext(facadeChatSDK, state, dispatch)) ?? (state === null || state === void 0 ? void 0 : (_state$domainStates3 = state.domainStates) === null || _state$domainStates3 === void 0 ? void 0 : _state$domainStates3.postChatContext);
516
+ if (postchatContext) {
517
+ TelemetryHelper.logSDKEventToAllTelemetry(LogLevel.INFO, {
518
+ Event: TelemetryEvent.EndChatEventReceived,
519
+ Description: "Processing initiateEndChat, initiatePostChat",
520
+ CustomProperties: {
521
+ postchatContext
522
+ }
523
+ });
524
+ await initiatePostChat(props, conversationDetails, state, dispatch, postchatContext);
525
+ }
526
+ }
527
+ } else {
528
+ const skipEndChatSDK = false;
529
+ const skipCloseChat = false;
530
+ TelemetryHelper.logSDKEventToAllTelemetry(LogLevel.INFO, {
531
+ Event: TelemetryEvent.EndChatEventReceived,
532
+ Description: "Processing initiateEndChat, trigger endChat"
533
+ });
534
+ await endChat(props, facadeChatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, skipEndChatSDK, skipCloseChat);
535
+ }
536
+ }
537
+ //if conversation already closed, it is safe to unmount it upon receiving the closeChat event
538
+ else {
539
+ BroadcastService.postMessage({
540
+ eventName: BroadcastEvent.CloseChat
541
+ });
542
+ }
543
+ };
493
544
 
494
545
  // End chat
495
- BroadcastService.getMessageByEventName(BroadcastEvent.InitiateEndChat).subscribe(async () => {
546
+ BroadcastService.getMessageByEventName(BroadcastEvent.InitiateEndChat).subscribe(async msg => {
496
547
  TelemetryHelper.logSDKEventToAllTelemetry(LogLevel.INFO, {
497
548
  Event: TelemetryEvent.EndChatEventReceived,
498
549
  Description: "Received InitiateEndChat BroadcastEvent.",
499
550
  CustomProperties: {
500
- ConversationStage: ConversationStage.ConversationEnd
551
+ ConversationStage: ConversationStage.ConversationEnd,
552
+ payload: msg === null || msg === void 0 ? void 0 : msg.payload
501
553
  }
502
554
  });
503
-
504
- // This is to ensure to get latest state from cache in multitab
555
+ const conversationDetails = await getConversationDetailsCall(facadeChatSDK);
556
+ const {
557
+ chatConfig
558
+ } = props;
559
+ const isPersistent = isPersistentEnabled(chatConfig);
560
+ TelemetryHelper.logSDKEventToAllTelemetry(LogLevel.INFO, {
561
+ Event: TelemetryEvent.EndChatEventReceived,
562
+ Description: "Processing initiateEndChat, fetched conversation details",
563
+ CustomProperties: {
564
+ conversationDetails,
565
+ isPersistent
566
+ }
567
+ });
568
+ if (isPersistent && conversationDetails) {
569
+ await handleInitiateEndChatForPersistentChat(msg, conversationDetails);
570
+ return;
571
+ }
505
572
  const persistedState = getStateFromCache(getWidgetCacheIdfromProps(props));
506
573
  if (persistedState && persistedState.appStates.conversationState === ConversationState.Active) {
507
- // We need to simulate states for closing chat, in order to messup with close confirmation pane.
574
+ TelemetryHelper.logSDKEvent(LogLevel.INFO, {
575
+ Event: TelemetryEvent.PrepareEndChat,
576
+ Description: PrepareEndChatDescriptionConstants.InitiateEndChatReceivedActiveChat
577
+ });
578
+ //We need to simulate states for closing chat, in order to messup with close confirmation pane.
508
579
  dispatch({
509
580
  type: LiveChatWidgetActionType.SET_CONFIRMATION_STATE,
510
581
  payload: ConfirmationState.Ok
@@ -524,11 +595,8 @@ export const LiveChatWidgetStateful = props => {
524
595
  Event: TelemetryEvent.PrepareEndChat,
525
596
  Description: PrepareEndChatDescriptionConstants.InitiateEndChatReceived
526
597
  });
527
- endChat(props, facadeChatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, skipEndChatSDK, skipCloseChat);
598
+ await endChat(props, facadeChatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, skipEndChatSDK, skipCloseChat);
528
599
  }
529
- BroadcastService.postMessage({
530
- eventName: BroadcastEvent.CloseChat
531
- });
532
600
  });
533
601
 
534
602
  // End chat on browser unload
@@ -539,8 +607,8 @@ export const LiveChatWidgetStateful = props => {
539
607
  // Listen to end chat event from other tabs
540
608
  const endChatEventName = getWidgetEndChatEventName((_facadeChatSDK$getCha3 = facadeChatSDK.getChatSDK()) === null || _facadeChatSDK$getCha3 === void 0 ? void 0 : (_facadeChatSDK$getCha4 = _facadeChatSDK$getCha3.omnichannelConfig) === null || _facadeChatSDK$getCha4 === void 0 ? void 0 : _facadeChatSDK$getCha4.orgId, (_facadeChatSDK$getCha5 = facadeChatSDK.getChatSDK()) === null || _facadeChatSDK$getCha5 === void 0 ? void 0 : (_facadeChatSDK$getCha6 = _facadeChatSDK$getCha5.omnichannelConfig) === null || _facadeChatSDK$getCha6 === void 0 ? void 0 : _facadeChatSDK$getCha6.widgetId, ((_props$controlProps11 = props.controlProps) === null || _props$controlProps11 === void 0 ? void 0 : _props$controlProps11.widgetInstanceId) ?? "");
541
609
  BroadcastService.getMessageByEventName(endChatEventName).subscribe(msg => {
542
- var _msg$payload10;
543
- if ((msg === null || msg === void 0 ? void 0 : (_msg$payload10 = msg.payload) === null || _msg$payload10 === void 0 ? void 0 : _msg$payload10.runtimeId) !== TelemetryManager.InternalTelemetryData.lcwRuntimeId) {
610
+ var _msg$payload13;
611
+ if ((msg === null || msg === void 0 ? void 0 : (_msg$payload13 = msg.payload) === null || _msg$payload13 === void 0 ? void 0 : _msg$payload13.runtimeId) !== TelemetryManager.InternalTelemetryData.lcwRuntimeId) {
544
612
  TelemetryHelper.logSDKEvent(LogLevel.INFO, {
545
613
  Event: TelemetryEvent.PrepareEndChat,
546
614
  Description: "Received EndChat BroadcastEvent from other tabs. Closing this chat."
@@ -582,8 +650,8 @@ export const LiveChatWidgetStateful = props => {
582
650
 
583
651
  // Retrieve convId
584
652
  BroadcastService.getMessageByEventName(BroadcastEvent.UpdateConversationDataForTelemetry).subscribe(msg => {
585
- var _msg$payload11, _msg$payload11$liveWo;
586
- if ((_msg$payload11 = msg.payload) !== null && _msg$payload11 !== void 0 && (_msg$payload11$liveWo = _msg$payload11.liveWorkItem) !== null && _msg$payload11$liveWo !== void 0 && _msg$payload11$liveWo.conversationId) {
653
+ var _msg$payload14, _msg$payload14$liveWo;
654
+ if ((_msg$payload14 = msg.payload) !== null && _msg$payload14 !== void 0 && (_msg$payload14$liveWo = _msg$payload14.liveWorkItem) !== null && _msg$payload14$liveWo !== void 0 && _msg$payload14$liveWo.conversationId) {
587
655
  setConversationId(msg.payload.liveWorkItem.conversationId);
588
656
  }
589
657
  });
@@ -701,14 +769,22 @@ export const LiveChatWidgetStateful = props => {
701
769
  }
702
770
  }, [state.domainStates.confirmationState]);
703
771
  useEffect(() => {
704
- var _state$appStates8, _state$appStates9, _state$appStates10, _state$appStates11, _state$appStates12, _state$appStates13;
772
+ var _inMemoryState$appSta7, _inMemoryState$appSta8, _inMemoryState$appSta9, _inMemoryState$appSta10, _inMemoryState$appSta11, _inMemoryState$appSta12, _inMemoryState$appSta13;
773
+ const inMemoryState = executeReducer(state, {
774
+ type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
775
+ payload: null
776
+ });
705
777
  // Do not process anything during initialization
706
- if ((state === null || state === void 0 ? void 0 : (_state$appStates8 = state.appStates) === null || _state$appStates8 === void 0 ? void 0 : _state$appStates8.conversationEndedBy) === ConversationEndEntity.NotSet) {
778
+ if ((inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta7 = inMemoryState.appStates) === null || _inMemoryState$appSta7 === void 0 ? void 0 : _inMemoryState$appSta7.conversationEndedBy) === ConversationEndEntity.NotSet) {
779
+ TelemetryHelper.logSDKEvent(LogLevel.INFO, {
780
+ Event: TelemetryEvent.PrepareEndChat,
781
+ Description: "conversationEndedBy is not set"
782
+ });
707
783
  return;
708
784
  }
709
785
 
710
786
  // If start chat failed, and C2 is trying to close chat widget
711
- if (state !== null && state !== void 0 && (_state$appStates9 = state.appStates) !== null && _state$appStates9 !== void 0 && _state$appStates9.startChatFailed || (state === null || state === void 0 ? void 0 : (_state$appStates10 = state.appStates) === null || _state$appStates10 === void 0 ? void 0 : _state$appStates10.conversationState) === ConversationState.Postchat) {
787
+ if (inMemoryState !== null && inMemoryState !== void 0 && (_inMemoryState$appSta8 = inMemoryState.appStates) !== null && _inMemoryState$appSta8 !== void 0 && _inMemoryState$appSta8.startChatFailed || (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta9 = inMemoryState.appStates) === null || _inMemoryState$appSta9 === void 0 ? void 0 : _inMemoryState$appSta9.conversationState) === ConversationState.Postchat) {
712
788
  TelemetryHelper.logSDKEvent(LogLevel.INFO, {
713
789
  Event: TelemetryEvent.PrepareEndChat,
714
790
  Description: PrepareEndChatDescriptionConstants.CustomerCloseChatOnFailureOrPostChat
@@ -718,7 +794,7 @@ export const LiveChatWidgetStateful = props => {
718
794
  }
719
795
 
720
796
  // Scenario -> Chat was InActive and closing the chat (Refresh scenario on post chat)
721
- if ((state === null || state === void 0 ? void 0 : (_state$appStates11 = state.appStates) === null || _state$appStates11 === void 0 ? void 0 : _state$appStates11.conversationState) === ConversationState.InActive) {
797
+ if ((inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta10 = inMemoryState.appStates) === null || _inMemoryState$appSta10 === void 0 ? void 0 : _inMemoryState$appSta10.conversationState) === ConversationState.InActive) {
722
798
  TelemetryHelper.logSDKEvent(LogLevel.INFO, {
723
799
  Event: TelemetryEvent.PrepareEndChat,
724
800
  Description: PrepareEndChatDescriptionConstants.CustomerCloseInactiveChat
@@ -726,11 +802,11 @@ export const LiveChatWidgetStateful = props => {
726
802
  endChat(props, facadeChatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, false, true);
727
803
  return;
728
804
  }
729
- const isConversationalSurveyEnabled = state.appStates.isConversationalSurveyEnabled;
805
+ const isConversationalSurveyEnabled = inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta11 = inMemoryState.appStates) === null || _inMemoryState$appSta11 === void 0 ? void 0 : _inMemoryState$appSta11.isConversationalSurveyEnabled;
730
806
 
731
807
  // In conversational survey, we need to check post chat survey logics before we set ConversationState to InActive
732
808
  // Hence setting ConversationState to InActive will be done later in the post chat flows
733
- if (!isConversationalSurveyEnabled && ((state === null || state === void 0 ? void 0 : (_state$appStates12 = state.appStates) === null || _state$appStates12 === void 0 ? void 0 : _state$appStates12.conversationEndedBy) === ConversationEndEntity.Agent || (state === null || state === void 0 ? void 0 : (_state$appStates13 = state.appStates) === null || _state$appStates13 === void 0 ? void 0 : _state$appStates13.conversationEndedBy) === ConversationEndEntity.Bot)) {
809
+ if (!isConversationalSurveyEnabled && ((inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta12 = inMemoryState.appStates) === null || _inMemoryState$appSta12 === void 0 ? void 0 : _inMemoryState$appSta12.conversationEndedBy) === ConversationEndEntity.Agent || (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta13 = inMemoryState.appStates) === null || _inMemoryState$appSta13 === void 0 ? void 0 : _inMemoryState$appSta13.conversationEndedBy) === ConversationEndEntity.Bot)) {
734
810
  dispatch({
735
811
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
736
812
  payload: ConversationState.InActive
@@ -738,8 +814,8 @@ export const LiveChatWidgetStateful = props => {
738
814
  }
739
815
 
740
816
  // All other cases
741
- prepareEndChat(props, facadeChatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter);
742
- }, [state === null || state === void 0 ? void 0 : (_state$appStates14 = state.appStates) === null || _state$appStates14 === void 0 ? void 0 : _state$appStates14.conversationEndedBy]);
817
+ prepareEndChat(props, facadeChatSDK, inMemoryState, dispatch, setAdapter, setWebChatStyles, adapter);
818
+ }, [state === null || state === void 0 ? void 0 : (_state$appStates8 = state.appStates) === null || _state$appStates8 === void 0 ? void 0 : _state$appStates8.conversationEndedBy]);
743
819
 
744
820
  // Publish chat widget state
745
821
  useEffect(() => {
@@ -771,13 +847,13 @@ export const LiveChatWidgetStateful = props => {
771
847
 
772
848
  // Handle Chat disconnect cases
773
849
  useEffect(() => {
774
- var _inMemoryState$appSta7;
850
+ var _inMemoryState$appSta14;
775
851
  const inMemoryState = executeReducer(state, {
776
852
  type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
777
853
  payload: null
778
854
  });
779
855
  handleChatDisconnect(props, inMemoryState, setWebChatStyles);
780
- const chatDisconnectState = inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta7 = inMemoryState.appStates) === null || _inMemoryState$appSta7 === void 0 ? void 0 : _inMemoryState$appSta7.chatDisconnectEventReceived;
856
+ const chatDisconnectState = inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta14 = inMemoryState.appStates) === null || _inMemoryState$appSta14 === void 0 ? void 0 : _inMemoryState$appSta14.chatDisconnectEventReceived;
781
857
  if (chatDisconnectState && adapter) {
782
858
  try {
783
859
  adapter.end();
@@ -876,6 +952,17 @@ export const LiveChatWidgetStateful = props => {
876
952
  bubbleTextColor
877
953
  }), [webChatStyles, bubbleBackground, bubbleTextColor]);
878
954
 
955
+ // React to dynamic bot avatar initials updates from context
956
+ useEffect(() => {
957
+ if (state.domainStates.botAvatarInitials && state.domainStates.botAvatarInitials !== webChatStyles.botAvatarInitials) {
958
+ /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
959
+ setWebChatStyles(styles => ({
960
+ ...styles,
961
+ botAvatarInitials: state.domainStates.botAvatarInitials
962
+ }));
963
+ }
964
+ }, [state.domainStates.botAvatarInitials]);
965
+
879
966
  // WebChat's Composer can only be rendered if a directLine object is defined
880
967
  return directLine && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("style", null, `
881
968
  #oc-lcw .webchat__basic-transcript__scrollable::-webkit-scrollbar {
@@ -22,7 +22,7 @@ const generateSurveyInviteLink = function (surveyInviteLink, isEmbed, locale, co
22
22
  return `${surveyInviteLink}&${surveyLinkParams.toString()}`;
23
23
  };
24
24
  export const PostChatSurveyPaneStateful = props => {
25
- var _props$styleProps, _state$appStates, _props$controlProps;
25
+ var _props$styleProps, _state$appStates, _state$domainStates$p, _props$controlProps;
26
26
  useEffect(() => {
27
27
  uiTimer = createTimer();
28
28
  TelemetryHelper.logLoadingEventToAllTelemetry(LogLevel.INFO, {
@@ -39,13 +39,15 @@ export const PostChatSurveyPaneStateful = props => {
39
39
  });
40
40
  let surveyInviteLink = "";
41
41
  const surveyMode = (state === null || state === void 0 ? void 0 : (_state$appStates = state.appStates) === null || _state$appStates === void 0 ? void 0 : _state$appStates.selectedSurveyMode) === PostChatSurveyMode.Embed;
42
- if (state.domainStates.postChatContext.botSurveyInviteLink &&
42
+ if ((_state$domainStates$p = state.domainStates.postChatContext) !== null && _state$domainStates$p !== void 0 && _state$domainStates$p.botSurveyInviteLink &&
43
43
  // Bot survey enabled
44
44
  state.appStates.postChatParticipantType === ParticipantType.Bot) {
45
+ var _state$domainStates$p2, _state$domainStates$p3;
45
46
  // Only Bot has engaged
46
- surveyInviteLink = generateSurveyInviteLink(state.domainStates.postChatContext.botSurveyInviteLink, surveyMode, state.domainStates.postChatContext.botFormsProLocale, props.isCustomerVoiceSurveyCompact ?? true, props.customerVoiceSurveyCorrelationId || "");
47
+ surveyInviteLink = generateSurveyInviteLink((_state$domainStates$p2 = state.domainStates.postChatContext) === null || _state$domainStates$p2 === void 0 ? void 0 : _state$domainStates$p2.botSurveyInviteLink, surveyMode, (_state$domainStates$p3 = state.domainStates.postChatContext) === null || _state$domainStates$p3 === void 0 ? void 0 : _state$domainStates$p3.botFormsProLocale, props.isCustomerVoiceSurveyCompact ?? true, props.customerVoiceSurveyCorrelationId || "");
47
48
  } else {
48
- surveyInviteLink = generateSurveyInviteLink(state.domainStates.postChatContext.surveyInviteLink, surveyMode, state.domainStates.postChatContext.formsProLocale, props.isCustomerVoiceSurveyCompact ?? true, props.customerVoiceSurveyCorrelationId || "");
49
+ var _state$domainStates$p4, _state$domainStates$p5;
50
+ surveyInviteLink = generateSurveyInviteLink((_state$domainStates$p4 = state.domainStates.postChatContext) === null || _state$domainStates$p4 === void 0 ? void 0 : _state$domainStates$p4.surveyInviteLink, surveyMode, (_state$domainStates$p5 = state.domainStates.postChatContext) === null || _state$domainStates$p5 === void 0 ? void 0 : _state$domainStates$p5.formsProLocale, props.isCustomerVoiceSurveyCompact ?? true, props.customerVoiceSurveyCorrelationId || "");
49
51
  }
50
52
  if (props.copilotSurveyContext) {
51
53
  surveyInviteLink = `${surveyInviteLink}&mcs_additionalcontext=${JSON.stringify(props.copilotSurveyContext)}`;
@@ -103,7 +105,7 @@ export const PostChatSurveyPaneStateful = props => {
103
105
  Event: TelemetryEvent.CustomerVoiceResponsePageLoaded
104
106
  });
105
107
  } else if (data === CustomerVoiceEvents.FormResponseSubmitted) {
106
- TelemetryHelper.logActionEventToAllTelemetry(LogLevel.INFO, {
108
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
107
109
  Event: TelemetryEvent.CustomerVoiceFormResponseSubmitted,
108
110
  Description: "Customer Voice form response submitted.",
109
111
  CustomProperties: {
@@ -111,7 +113,7 @@ export const PostChatSurveyPaneStateful = props => {
111
113
  }
112
114
  });
113
115
  } else if (data === CustomerVoiceEvents.FormResponseError) {
114
- TelemetryHelper.logActionEventToAllTelemetry(LogLevel.ERROR, {
116
+ TelemetryHelper.logActionEvent(LogLevel.ERROR, {
115
117
  Event: TelemetryEvent.CustomerVoiceFormResponseError,
116
118
  Description: "Customer Voice form response error.",
117
119
  ExceptionDetails: {