@microsoft/omnichannel-chat-widget 1.8.4-main.9ae37a9 → 1.8.4-main.c687f88

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/lib/cjs/common/telemetry/loggers/appInsightsLogger.js +7 -7
  2. package/lib/cjs/common/utils.js +14 -1
  3. package/lib/cjs/components/errorboundary/ErrorBoundary.js +2 -1
  4. package/lib/cjs/components/livechatwidget/common/endChat.js +5 -0
  5. package/lib/cjs/components/livechatwidget/common/liveChatConfigUtils.js +36 -4
  6. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +2 -1
  7. package/lib/cjs/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +6 -4
  8. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +3 -6
  9. package/lib/cjs/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +8 -14
  10. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +2 -0
  11. package/lib/esm/common/telemetry/loggers/appInsightsLogger.js +7 -7
  12. package/lib/esm/common/utils.js +11 -0
  13. package/lib/esm/components/errorboundary/ErrorBoundary.js +4 -2
  14. package/lib/esm/components/livechatwidget/common/endChat.js +5 -0
  15. package/lib/esm/components/livechatwidget/common/liveChatConfigUtils.js +33 -2
  16. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +2 -1
  17. package/lib/esm/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +6 -4
  18. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +4 -7
  19. package/lib/esm/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +8 -14
  20. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +2 -0
  21. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.js +1 -0
  22. package/lib/types/common/utils.d.ts +9 -1
  23. package/lib/types/components/errorboundary/ErrorBoundary.d.ts +1 -1
  24. package/lib/types/components/livechatwidget/common/liveChatConfigUtils.d.ts +11 -0
  25. package/lib/types/components/webchatcontainerstateful/interfaces/IExtendedChatConffig.d.ts +1 -1
  26. package/package.json +2 -2
@@ -14,11 +14,11 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
14
14
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
15
15
  var AllowedKeys;
16
16
  (function (AllowedKeys) {
17
- AllowedKeys["OrganizationId"] = "OrganizationId";
18
- AllowedKeys["ConversationId"] = "LiveWorkItemId";
17
+ AllowedKeys["OrganizationId"] = "powerplatform.analytics.resource.organization.id";
18
+ AllowedKeys["ConversationId"] = "powerplatform.analytics.resource.id";
19
19
  AllowedKeys["ElapsedTimeInMilliseconds"] = "Duration";
20
- AllowedKeys["Description"] = "Description";
21
- AllowedKeys["ChannelId"] = "ChannelType";
20
+ AllowedKeys["Description"] = "omnichannel.description";
21
+ AllowedKeys["ChannelId"] = "omnichannel.channel.type";
22
22
  AllowedKeys["LCWRuntimeId"] = "ClientSessionId";
23
23
  })(AllowedKeys || (AllowedKeys = {}));
24
24
  let initializationPromise = null;
@@ -95,8 +95,8 @@ const appInsightsLogger = appInsightsKey => {
95
95
  if (eventName) {
96
96
  const trackingEventName = getTrackingEventName(logLevel, eventName);
97
97
  const eventProperties = setEventProperties(trackingEventName, telemetryInfo);
98
- _logger.trackEvent({
99
- name: trackingEventName,
98
+ _logger.trackTrace({
99
+ message: trackingEventName,
100
100
  properties: eventProperties
101
101
  });
102
102
  }
@@ -142,7 +142,7 @@ const appInsightsLogger = appInsightsKey => {
142
142
  // Additional properties
143
143
  eventProperties["ConversationStage"] = customProperties.ConversationStage ?? _TelemetryConstants.ConversationStage.CSREngagement;
144
144
  eventProperties["Scenario"] = "Conversation Diagnostics";
145
- eventProperties["OperationName"] = eventName.includes(": ") ? eventName.split(": ")[1] : eventName;
145
+ eventProperties["powerplatform.analytics.subscenario"] = eventName.includes(": ") ? eventName.split(": ")[1] : eventName;
146
146
  return eventProperties;
147
147
  }
148
148
  function getTrackingEventName(logLevel, eventName) {
@@ -7,7 +7,9 @@ exports.getCustomEventValue = exports.getConversationDetailsCall = exports.getBr
7
7
  exports.getDeviceType = getDeviceType;
8
8
  exports.getWidgetEndChatEventName = exports.getWidgetCacheIdfromProps = exports.getWidgetCacheId = exports.getTimestampHourMinute = exports.getStateFromCache = exports.getLocaleDirection = exports.getIconText = exports.getDomain = void 0;
9
9
  exports.isEndConversationDueToOverflowActivity = isEndConversationDueToOverflowActivity;
10
- exports.setTabIndices = exports.setOcUserAgent = exports.setFocusOnSendBox = exports.setFocusOnElement = exports.preventFocusToMoveOutOfElement = exports.parseLowerCaseString = exports.parseAdaptiveCardPayload = exports.newGuid = exports.isValidCustomEvent = exports.isUndefinedOrEmpty = exports.isThisSessionPopout = exports.isNullOrUndefined = exports.isNullOrEmptyString = void 0;
10
+ exports.parseAdaptiveCardPayload = exports.newGuid = exports.isValidCustomEvent = exports.isUndefinedOrEmpty = exports.isThisSessionPopout = exports.isNullOrUndefined = exports.isNullOrEmptyString = void 0;
11
+ exports.parseBooleanFromConfig = parseBooleanFromConfig;
12
+ exports.setTabIndices = exports.setOcUserAgent = exports.setFocusOnSendBox = exports.setFocusOnElement = exports.preventFocusToMoveOutOfElement = exports.parseLowerCaseString = void 0;
11
13
  var _Constants = require("./Constants");
12
14
  var _TelemetryConstants = require("./telemetry/TelemetryConstants");
13
15
  var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components");
@@ -519,4 +521,15 @@ exports.getCustomEventValue = getCustomEventValue;
519
521
  function isEndConversationDueToOverflowActivity(activity) {
520
522
  var _activity$channelData, _activity$channelData2;
521
523
  return (activity === null || activity === void 0 ? void 0 : (_activity$channelData = activity.channelData) === null || _activity$channelData === void 0 ? void 0 : _activity$channelData.tags) && Array.isArray(activity === null || activity === void 0 ? void 0 : (_activity$channelData2 = activity.channelData) === null || _activity$channelData2 === void 0 ? void 0 : _activity$channelData2.tags) && activity.channelData.tags.includes(_Constants.Constants.EndConversationDueToOverflow);
524
+ }
525
+
526
+ /**
527
+ * Parses a value that can be boolean or string ("true"/"false") into a boolean.
528
+ * Handles null/undefined by returning false.
529
+ *
530
+ * @param value - The value to parse (can be boolean, string, null, or undefined)
531
+ * @returns true if value is true or "true" (case-insensitive), false otherwise
532
+ */
533
+ function parseBooleanFromConfig(value) {
534
+ return value === true || (value === null || value === void 0 ? void 0 : value.toString().toLowerCase()) === "true";
522
535
  }
@@ -19,11 +19,12 @@ function _possibleConstructorReturn(self, call) { if (call && (typeof call === "
19
19
  function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
20
20
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
21
21
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
22
+ // eslint-disable-next-line @typescript-eslint/ban-types
22
23
  const RenderChildrenFunction = _ref => {
23
24
  let {
24
25
  children
25
26
  } = _ref;
26
- return typeof children === 'function' ? children() : children;
27
+ return typeof children === "function" ? children() : children;
27
28
  };
28
29
  let ErrorBoundary = /*#__PURE__*/function (_Component) {
29
30
  _inherits(ErrorBoundary, _Component);
@@ -12,6 +12,8 @@ var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components
12
12
  var _ConversationState = require("../../../contexts/common/ConversationState");
13
13
  var _LazyLoadActivity = require("../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity");
14
14
  var _LiveChatWidgetActionType = require("../../../contexts/common/LiveChatWidgetActionType");
15
+ var _NotificationHandler = require("../../webchatcontainerstateful/webchatcontroller/notification/NotificationHandler");
16
+ var _NotificationScenarios = require("../../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios");
15
17
  var _TelemetryHelper = require("../../../common/telemetry/TelemetryHelper");
16
18
  var _TelemetryManager = require("../../../common/telemetry/TelemetryManager");
17
19
  var _WebChatStoreLoader = require("../../webchatcontainerstateful/webchatcontroller/WebChatStoreLoader");
@@ -343,6 +345,9 @@ const closeChatStateCleanUp = dispatch => {
343
345
  payload: {}
344
346
  });
345
347
 
348
+ // Dismiss the chat disconnect notification banner if it was shown
349
+ _NotificationHandler.NotificationHandler.dismissNotification(_NotificationScenarios.NotificationScenarios.ChatDisconnect);
350
+
346
351
  // Clear live chat context only if chat widget is fully closed to support transcript calls after sessionclose is called
347
352
  dispatch({
348
353
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
@@ -3,15 +3,17 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.isPostChatSurveyEnabled = exports.isPersistentChatEnabled = exports.getPostChatSurveyConfig = void 0;
7
- var _Constants = require("../../../common/Constants");
6
+ exports.shouldLoadPersistentChatHistory = exports.isPostChatSurveyEnabled = exports.isPersistentChatEnabled = exports.getPostChatSurveyConfig = void 0;
8
7
  var _utils = require("../../../common/utils");
8
+ var _Constants = require("../../../common/Constants");
9
9
  const isPostChatSurveyEnabled = async facadeChatSDK => {
10
10
  var _chatConfig$LiveWSAnd;
11
11
  const chatConfig = await facadeChatSDK.getLiveChatConfig();
12
12
  const postChatEnabled = (_chatConfig$LiveWSAnd = chatConfig.LiveWSAndLiveChatEngJoin) === null || _chatConfig$LiveWSAnd === void 0 ? void 0 : _chatConfig$LiveWSAnd.msdyn_postconversationsurveyenable.toString().toLowerCase();
13
13
  return postChatEnabled === "true";
14
14
  };
15
+
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
17
  exports.isPostChatSurveyEnabled = isPostChatSurveyEnabled;
16
18
  const getPostChatSurveyConfig = async facadeChatSDK => {
17
19
  var _chatConfig$LiveWSAnd2, _chatConfig$LiveWSAnd3, _chatConfig$LiveWSAnd4, _chatConfig$LiveWSAnd5, _chatConfig$LiveWSAnd6, _chatConfig$LiveWSAnd7, _chatConfig$LiveWSAnd8, _chatConfig$LiveWSAnd9, _chatConfig$LiveWSAnd10;
@@ -34,6 +36,36 @@ const isPersistentChatEnabled = conversationMode => {
34
36
  if ((0, _utils.isNullOrUndefined)(conversationMode)) {
35
37
  return false;
36
38
  }
37
- return (conversationMode === null || conversationMode === void 0 ? void 0 : conversationMode.toString().toLowerCase()) === _Constants.ConversationMode.Persistent;
39
+ return (conversationMode === null || conversationMode === void 0 ? void 0 : conversationMode.toString()) === _Constants.ConversationMode.Persistent;
40
+ };
41
+
42
+ /**
43
+ * Determines if persistent chat history should be loaded based on all required conditions.
44
+ *
45
+ * @param extendedChatConfig - The extended chat configuration object
46
+ * @returns true if ALL conditions are met:
47
+ * 1. Conversation mode must be Persistent ("192350001")
48
+ * 2. History is enabled in admin config (msdyn_enablepersistentchatpreviousconversations)
49
+ * 3. History is enabled via feature flag (lcwPersistentChatHistoryEnabled)
50
+ */
51
+ exports.isPersistentChatEnabled = isPersistentChatEnabled;
52
+ const shouldLoadPersistentChatHistory = extendedChatConfig => {
53
+ var _extendedChatConfig$L, _extendedChatConfig$L2, _extendedChatConfig$L3;
54
+ // CRITICAL: First check if conversation mode is persistent
55
+ // Only persistent mode ("192350001") should allow history loading
56
+ 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);
57
+ if (!isPersistentChatEnabledForWidget) {
58
+ return false;
59
+ }
60
+
61
+ // Check if history is enabled in admin config (handles both boolean and string "true"/"false")
62
+ const isHistoryEnabledInConfig = (0, _utils.parseBooleanFromConfig)(extendedChatConfig === null || extendedChatConfig === void 0 ? void 0 : (_extendedChatConfig$L2 = extendedChatConfig.LiveWSAndLiveChatEngJoin) === null || _extendedChatConfig$L2 === void 0 ? void 0 : _extendedChatConfig$L2.msdyn_enablepersistentchatpreviousconversations);
63
+ if (!isHistoryEnabledInConfig) {
64
+ return false;
65
+ }
66
+
67
+ // Check if history is enabled via feature flag (handles both boolean and string "true"/"false")
68
+ const isHistoryEnabledViaFCB = (0, _utils.parseBooleanFromConfig)(extendedChatConfig === null || extendedChatConfig === void 0 ? void 0 : (_extendedChatConfig$L3 = extendedChatConfig.LcwFcbConfiguration) === null || _extendedChatConfig$L3 === void 0 ? void 0 : _extendedChatConfig$L3.lcwPersistentChatHistoryEnabled);
69
+ return isHistoryEnabledViaFCB;
38
70
  };
39
- exports.isPersistentChatEnabled = isPersistentChatEnabled;
71
+ exports.shouldLoadPersistentChatHistory = shouldLoadPersistentChatHistory;
@@ -814,7 +814,7 @@ const LiveChatWidgetStateful = props => {
814
814
 
815
815
  // In conversational survey, we need to check post chat survey logics before we set ConversationState to InActive
816
816
  // Hence setting ConversationState to InActive will be done later in the post chat flows
817
- if (!isConversationalSurveyEnabled && (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta12 = inMemoryState.appStates) === null || _inMemoryState$appSta12 === void 0 ? void 0 : _inMemoryState$appSta12.conversationEndedBy) === _Constants.ConversationEndEntity.Agent || (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta13 = inMemoryState.appStates) === null || _inMemoryState$appSta13 === void 0 ? void 0 : _inMemoryState$appSta13.conversationEndedBy) === _Constants.ConversationEndEntity.Bot) {
817
+ if (!isConversationalSurveyEnabled && ((inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta12 = inMemoryState.appStates) === null || _inMemoryState$appSta12 === void 0 ? void 0 : _inMemoryState$appSta12.conversationEndedBy) === _Constants.ConversationEndEntity.Agent || (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta13 = inMemoryState.appStates) === null || _inMemoryState$appSta13 === void 0 ? void 0 : _inMemoryState$appSta13.conversationEndedBy) === _Constants.ConversationEndEntity.Bot)) {
818
818
  dispatch({
819
819
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
820
820
  payload: _ConversationState.ConversationState.InActive
@@ -963,6 +963,7 @@ const LiveChatWidgetStateful = props => {
963
963
  // React to dynamic bot avatar initials updates from context
964
964
  (0, _react2.useEffect)(() => {
965
965
  if (state.domainStates.botAvatarInitials && state.domainStates.botAvatarInitials !== webChatStyles.botAvatarInitials) {
966
+ /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
966
967
  setWebChatStyles(styles => ({
967
968
  ...styles,
968
969
  botAvatarInitials: state.domainStates.botAvatarInitials
@@ -31,7 +31,7 @@ const generateSurveyInviteLink = function (surveyInviteLink, isEmbed, locale, co
31
31
  return `${surveyInviteLink}&${surveyLinkParams.toString()}`;
32
32
  };
33
33
  const PostChatSurveyPaneStateful = props => {
34
- var _props$styleProps, _state$appStates, _props$controlProps;
34
+ var _props$styleProps, _state$appStates, _state$domainStates$p, _props$controlProps;
35
35
  (0, _react.useEffect)(() => {
36
36
  uiTimer = (0, _utils.createTimer)();
37
37
  _TelemetryHelper.TelemetryHelper.logLoadingEventToAllTelemetry(_TelemetryConstants.LogLevel.INFO, {
@@ -48,13 +48,15 @@ const PostChatSurveyPaneStateful = props => {
48
48
  });
49
49
  let surveyInviteLink = "";
50
50
  const surveyMode = (state === null || state === void 0 ? void 0 : (_state$appStates = state.appStates) === null || _state$appStates === void 0 ? void 0 : _state$appStates.selectedSurveyMode) === _PostChatSurveyMode.PostChatSurveyMode.Embed;
51
- if (state.domainStates.postChatContext.botSurveyInviteLink &&
51
+ if ((_state$domainStates$p = state.domainStates.postChatContext) !== null && _state$domainStates$p !== void 0 && _state$domainStates$p.botSurveyInviteLink &&
52
52
  // Bot survey enabled
53
53
  state.appStates.postChatParticipantType === _Constants.ParticipantType.Bot) {
54
+ var _state$domainStates$p2, _state$domainStates$p3;
54
55
  // Only Bot has engaged
55
- surveyInviteLink = generateSurveyInviteLink(state.domainStates.postChatContext.botSurveyInviteLink, surveyMode, state.domainStates.postChatContext.botFormsProLocale, props.isCustomerVoiceSurveyCompact ?? true, props.customerVoiceSurveyCorrelationId || "");
56
+ 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 || "");
56
57
  } else {
57
- surveyInviteLink = generateSurveyInviteLink(state.domainStates.postChatContext.surveyInviteLink, surveyMode, state.domainStates.postChatContext.formsProLocale, props.isCustomerVoiceSurveyCompact ?? true, props.customerVoiceSurveyCorrelationId || "");
58
+ var _state$domainStates$p4, _state$domainStates$p5;
59
+ 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 || "");
58
60
  }
59
61
  if (props.copilotSurveyContext) {
60
62
  surveyInviteLink = `${surveyInviteLink}&mcs_additionalcontext=${JSON.stringify(props.copilotSurveyContext)}`;
@@ -62,7 +62,7 @@ const createMagicCodeSuccessResponse = signin => {
62
62
  };
63
63
  };
64
64
  const WebChatContainerStateful = props => {
65
- var _props$webChatContain, _defaultWebChatContai, _extendedChatConfig$L, _extendedChatConfig$L2, _extendedChatConfig$L3, _extendedChatConfig$L4, _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _webChatContainerProp7, _webChatContainerProp8, _webChatContainerProp9, _props$webChatContain6, _props$webChatContain7, _defaultWebChatContai2, _props$webChatContain8, _props$webChatContain9, _defaultWebChatContai3, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _webChatContainerProp13, _webChatContainerProp14, _webChatContainerProp15, _webChatContainerProp16, _webChatContainerProp17, _webChatContainerProp18, _webChatContainerProp19, _webChatContainerProp20, _webChatContainerProp21, _webChatContainerProp22, _webChatContainerProp23, _webChatContainerProp24, _props$webChatContain10, _props$webChatContain11, _webChatContainerProp25, _webChatContainerProp26, _webChatContainerProp27, _webChatContainerProp28, _props$citationPanePr, _props$citationPanePr2, _props$citationPanePr3, _props$citationPanePr4, _props$citationPanePr5;
65
+ var _props$webChatContain, _defaultWebChatContai, _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _webChatContainerProp7, _webChatContainerProp8, _webChatContainerProp9, _props$webChatContain6, _props$webChatContain7, _defaultWebChatContai2, _props$webChatContain8, _props$webChatContain9, _defaultWebChatContai3, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _webChatContainerProp13, _webChatContainerProp14, _webChatContainerProp15, _webChatContainerProp16, _webChatContainerProp17, _webChatContainerProp18, _webChatContainerProp19, _webChatContainerProp20, _webChatContainerProp21, _webChatContainerProp22, _webChatContainerProp23, _webChatContainerProp24, _props$webChatContain10, _props$webChatContain11, _webChatContainerProp25, _webChatContainerProp26, _webChatContainerProp27, _webChatContainerProp28, _props$citationPanePr, _props$citationPanePr2, _props$citationPanePr3, _props$citationPanePr4, _props$citationPanePr5;
66
66
  const [facadeChatSDK] = (0, _useFacadeChatSDKStore.default)();
67
67
 
68
68
  // Create a font family that includes emoji support, based on the primary font or default
@@ -96,12 +96,9 @@ const WebChatContainerStateful = props => {
96
96
 
97
97
  // Type the chatConfig properly to avoid 'any' usage
98
98
  const extendedChatConfig = props.chatConfig;
99
- const isHistoryEnabledInConfig = extendedChatConfig === null || extendedChatConfig === void 0 ? void 0 : (_extendedChatConfig$L = extendedChatConfig.LiveWSAndLiveChatEngJoin) === null || _extendedChatConfig$L === void 0 ? void 0 : _extendedChatConfig$L.msdyn_enablepersistentchatpreviousconversations;
100
- const isHistoryEnabledViaFCB = extendedChatConfig === null || extendedChatConfig === void 0 ? void 0 : (_extendedChatConfig$L2 = extendedChatConfig.LcwFcbConfiguration) === null || _extendedChatConfig$L2 === void 0 ? void 0 : _extendedChatConfig$L2.lcwPersistentChatHistoryEnabled;
101
- const isPersistentChatEnabledForWidget = !!(extendedChatConfig !== null && extendedChatConfig !== void 0 && (_extendedChatConfig$L3 = extendedChatConfig.LiveChatConfigAuthSettings) !== null && _extendedChatConfig$L3 !== void 0 && _extendedChatConfig$L3.msdyn_javascriptclientfunction) || (0, _liveChatConfigUtils.isPersistentChatEnabled)(extendedChatConfig === null || extendedChatConfig === void 0 ? void 0 : (_extendedChatConfig$L4 = extendedChatConfig.LiveWSAndLiveChatEngJoin) === null || _extendedChatConfig$L4 === void 0 ? void 0 : _extendedChatConfig$L4.msdyn_conversationmode);
102
99
 
103
- // Check if both persistent chat and widget support are enabled
104
- const shouldLoadPersistentHistoryMessages = isHistoryEnabledInConfig && isHistoryEnabledViaFCB && isPersistentChatEnabledForWidget;
100
+ // Determine if persistent chat history should be loaded based on all conditions
101
+ const shouldLoadPersistentHistoryMessages = (0, _liveChatConfigUtils.shouldLoadPersistentChatHistory)(extendedChatConfig);
105
102
  if (shouldLoadPersistentHistoryMessages) {
106
103
  _TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
107
104
  Event: _TelemetryConstants.TelemetryEvent.PersistentChatHistoryEnabled
@@ -53,20 +53,14 @@ const convertPersistentChatHistoryMessageToActivity = message => {
53
53
  }
54
54
  }
55
55
  if (additionalData !== null && additionalData !== void 0 && additionalData.tags) {
56
- const {
57
- tags,
58
- ConversationId
59
- } = additionalData;
60
- if (ConversationId) {
61
- activity.channelData.conversationId = ConversationId;
62
- }
63
- if (tags) {
64
- const formattedTags = additionalData.tags.split(",");
65
- activity.channelData = {
66
- ...activity.channelData,
67
- tags: [...activity.channelData.tags, ...formattedTags]
68
- };
69
- }
56
+ const formattedTags = additionalData.tags.split(",");
57
+ activity.channelData = {
58
+ ...activity.channelData,
59
+ tags: [...activity.channelData.tags, ...formattedTags]
60
+ };
61
+ }
62
+ if (additionalData !== null && additionalData !== void 0 && additionalData.ConversationId) {
63
+ activity.channelData.conversationId = additionalData.ConversationId;
70
64
  }
71
65
  if (from !== null && from !== void 0 && (_from$user = from.user) !== null && _from$user !== void 0 && _from$user.displayName) {
72
66
  activity.from = {
@@ -17,6 +17,8 @@ var _useChatContextStore = _interopRequireDefault(require("../../../../../../hoo
17
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
18
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
19
19
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
20
+ /* eslint-disable @typescript-eslint/no-explicit-any */
21
+
20
22
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
23
  const NotDeliveredTimestamp = _ref => {
22
24
  var _state$domainStates$r, _state$domainStates$r2, _state$domainStates$r3, _state$domainStates$r4, _state$domainStates$m, _state$domainStates$m2;
@@ -5,11 +5,11 @@ import { AppInsightsTelemetryMessage } from "../../Constants";
5
5
  import { AppInsightsEventMapping } from "../AppInsightsEvents";
6
6
  var AllowedKeys;
7
7
  (function (AllowedKeys) {
8
- AllowedKeys["OrganizationId"] = "OrganizationId";
9
- AllowedKeys["ConversationId"] = "LiveWorkItemId";
8
+ AllowedKeys["OrganizationId"] = "powerplatform.analytics.resource.organization.id";
9
+ AllowedKeys["ConversationId"] = "powerplatform.analytics.resource.id";
10
10
  AllowedKeys["ElapsedTimeInMilliseconds"] = "Duration";
11
- AllowedKeys["Description"] = "Description";
12
- AllowedKeys["ChannelId"] = "ChannelType";
11
+ AllowedKeys["Description"] = "omnichannel.description";
12
+ AllowedKeys["ChannelId"] = "omnichannel.channel.type";
13
13
  AllowedKeys["LCWRuntimeId"] = "ClientSessionId";
14
14
  })(AllowedKeys || (AllowedKeys = {}));
15
15
  let initializationPromise = null;
@@ -86,8 +86,8 @@ export const appInsightsLogger = appInsightsKey => {
86
86
  if (eventName) {
87
87
  const trackingEventName = getTrackingEventName(logLevel, eventName);
88
88
  const eventProperties = setEventProperties(trackingEventName, telemetryInfo);
89
- _logger.trackEvent({
90
- name: trackingEventName,
89
+ _logger.trackTrace({
90
+ message: trackingEventName,
91
91
  properties: eventProperties
92
92
  });
93
93
  }
@@ -133,7 +133,7 @@ export const appInsightsLogger = appInsightsKey => {
133
133
  // Additional properties
134
134
  eventProperties["ConversationStage"] = customProperties.ConversationStage ?? ConversationStage.CSREngagement;
135
135
  eventProperties["Scenario"] = "Conversation Diagnostics";
136
- eventProperties["OperationName"] = eventName.includes(": ") ? eventName.split(": ")[1] : eventName;
136
+ eventProperties["powerplatform.analytics.subscenario"] = eventName.includes(": ") ? eventName.split(": ")[1] : eventName;
137
137
  return eventProperties;
138
138
  }
139
139
  function getTrackingEventName(logLevel, eventName) {
@@ -474,4 +474,15 @@ export const getCustomEventValue = customEventPayload => {
474
474
  export function isEndConversationDueToOverflowActivity(activity) {
475
475
  var _activity$channelData, _activity$channelData2;
476
476
  return (activity === null || activity === void 0 ? void 0 : (_activity$channelData = activity.channelData) === null || _activity$channelData === void 0 ? void 0 : _activity$channelData.tags) && Array.isArray(activity === null || activity === void 0 ? void 0 : (_activity$channelData2 = activity.channelData) === null || _activity$channelData2 === void 0 ? void 0 : _activity$channelData2.tags) && activity.channelData.tags.includes(Constants.EndConversationDueToOverflow);
477
+ }
478
+
479
+ /**
480
+ * Parses a value that can be boolean or string ("true"/"false") into a boolean.
481
+ * Handles null/undefined by returning false.
482
+ *
483
+ * @param value - The value to parse (can be boolean, string, null, or undefined)
484
+ * @returns true if value is true or "true" (case-insensitive), false otherwise
485
+ */
486
+ export function parseBooleanFromConfig(value) {
487
+ return value === true || (value === null || value === void 0 ? void 0 : value.toString().toLowerCase()) === "true";
477
488
  }
@@ -10,12 +10,14 @@ function _possibleConstructorReturn(self, call) { if (call && (typeof call === "
10
10
  function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
11
11
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
12
12
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
13
- import React, { Component } from 'react';
13
+ import React, { Component } from "react";
14
+
15
+ // eslint-disable-next-line @typescript-eslint/ban-types
14
16
  const RenderChildrenFunction = _ref => {
15
17
  let {
16
18
  children
17
19
  } = _ref;
18
- return typeof children === 'function' ? children() : children;
20
+ return typeof children === "function" ? children() : children;
19
21
  };
20
22
  let ErrorBoundary = /*#__PURE__*/function (_Component) {
21
23
  _inherits(ErrorBoundary, _Component);
@@ -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";
@@ -334,6 +336,9 @@ export const closeChatStateCleanUp = dispatch => {
334
336
  payload: {}
335
337
  });
336
338
 
339
+ // Dismiss the chat disconnect notification banner if it was shown
340
+ NotificationHandler.dismissNotification(NotificationScenarios.ChatDisconnect);
341
+
337
342
  // Clear live chat context only if chat widget is fully closed to support transcript calls after sessionclose is called
338
343
  dispatch({
339
344
  type: LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
@@ -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
  };
@@ -806,7 +806,7 @@ export const LiveChatWidgetStateful = props => {
806
806
 
807
807
  // In conversational survey, we need to check post chat survey logics before we set ConversationState to InActive
808
808
  // Hence setting ConversationState to InActive will be done later in the post chat flows
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) {
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)) {
810
810
  dispatch({
811
811
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
812
812
  payload: ConversationState.InActive
@@ -955,6 +955,7 @@ export const LiveChatWidgetStateful = props => {
955
955
  // React to dynamic bot avatar initials updates from context
956
956
  useEffect(() => {
957
957
  if (state.domainStates.botAvatarInitials && state.domainStates.botAvatarInitials !== webChatStyles.botAvatarInitials) {
958
+ /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
958
959
  setWebChatStyles(styles => ({
959
960
  ...styles,
960
961
  botAvatarInitials: state.domainStates.botAvatarInitials
@@ -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)}`;
@@ -21,7 +21,7 @@ import { defaultSentMessageAnchorStyles } from "./webchatcontroller/middlewares/
21
21
  import { defaultSystemMessageBoxStyles } from "./webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSystemMessageBoxStyles";
22
22
  import { defaultUserMessageBoxStyles } from "./webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultUserMessageBoxStyles";
23
23
  import { defaultWebChatContainerStatefulProps } from "./common/defaultProps/defaultWebChatContainerStatefulProps";
24
- import { isPersistentChatEnabled } from "../livechatwidget/common/liveChatConfigUtils";
24
+ import { shouldLoadPersistentChatHistory } from "../livechatwidget/common/liveChatConfigUtils";
25
25
  import { useChatContextStore } from "../..";
26
26
  import useFacadeSDKStore from "../../hooks/useFacadeChatSDKStore";
27
27
  import usePersistentChatHistory from "./hooks/usePersistentChatHistory";
@@ -53,7 +53,7 @@ const createMagicCodeSuccessResponse = signin => {
53
53
  };
54
54
  };
55
55
  export const WebChatContainerStateful = props => {
56
- var _props$webChatContain, _defaultWebChatContai, _extendedChatConfig$L, _extendedChatConfig$L2, _extendedChatConfig$L3, _extendedChatConfig$L4, _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _webChatContainerProp7, _webChatContainerProp8, _webChatContainerProp9, _props$webChatContain6, _props$webChatContain7, _defaultWebChatContai2, _props$webChatContain8, _props$webChatContain9, _defaultWebChatContai3, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _webChatContainerProp13, _webChatContainerProp14, _webChatContainerProp15, _webChatContainerProp16, _webChatContainerProp17, _webChatContainerProp18, _webChatContainerProp19, _webChatContainerProp20, _webChatContainerProp21, _webChatContainerProp22, _webChatContainerProp23, _webChatContainerProp24, _props$webChatContain10, _props$webChatContain11, _webChatContainerProp25, _webChatContainerProp26, _webChatContainerProp27, _webChatContainerProp28, _props$citationPanePr, _props$citationPanePr2, _props$citationPanePr3, _props$citationPanePr4, _props$citationPanePr5;
56
+ var _props$webChatContain, _defaultWebChatContai, _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _webChatContainerProp7, _webChatContainerProp8, _webChatContainerProp9, _props$webChatContain6, _props$webChatContain7, _defaultWebChatContai2, _props$webChatContain8, _props$webChatContain9, _defaultWebChatContai3, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _webChatContainerProp13, _webChatContainerProp14, _webChatContainerProp15, _webChatContainerProp16, _webChatContainerProp17, _webChatContainerProp18, _webChatContainerProp19, _webChatContainerProp20, _webChatContainerProp21, _webChatContainerProp22, _webChatContainerProp23, _webChatContainerProp24, _props$webChatContain10, _props$webChatContain11, _webChatContainerProp25, _webChatContainerProp26, _webChatContainerProp27, _webChatContainerProp28, _props$citationPanePr, _props$citationPanePr2, _props$citationPanePr3, _props$citationPanePr4, _props$citationPanePr5;
57
57
  const [facadeChatSDK] = useFacadeSDKStore();
58
58
 
59
59
  // Create a font family that includes emoji support, based on the primary font or default
@@ -87,12 +87,9 @@ export const WebChatContainerStateful = props => {
87
87
 
88
88
  // Type the chatConfig properly to avoid 'any' usage
89
89
  const extendedChatConfig = props.chatConfig;
90
- const isHistoryEnabledInConfig = extendedChatConfig === null || extendedChatConfig === void 0 ? void 0 : (_extendedChatConfig$L = extendedChatConfig.LiveWSAndLiveChatEngJoin) === null || _extendedChatConfig$L === void 0 ? void 0 : _extendedChatConfig$L.msdyn_enablepersistentchatpreviousconversations;
91
- const isHistoryEnabledViaFCB = extendedChatConfig === null || extendedChatConfig === void 0 ? void 0 : (_extendedChatConfig$L2 = extendedChatConfig.LcwFcbConfiguration) === null || _extendedChatConfig$L2 === void 0 ? void 0 : _extendedChatConfig$L2.lcwPersistentChatHistoryEnabled;
92
- const isPersistentChatEnabledForWidget = !!(extendedChatConfig !== null && extendedChatConfig !== void 0 && (_extendedChatConfig$L3 = extendedChatConfig.LiveChatConfigAuthSettings) !== null && _extendedChatConfig$L3 !== void 0 && _extendedChatConfig$L3.msdyn_javascriptclientfunction) || isPersistentChatEnabled(extendedChatConfig === null || extendedChatConfig === void 0 ? void 0 : (_extendedChatConfig$L4 = extendedChatConfig.LiveWSAndLiveChatEngJoin) === null || _extendedChatConfig$L4 === void 0 ? void 0 : _extendedChatConfig$L4.msdyn_conversationmode);
93
90
 
94
- // Check if both persistent chat and widget support are enabled
95
- const shouldLoadPersistentHistoryMessages = isHistoryEnabledInConfig && isHistoryEnabledViaFCB && isPersistentChatEnabledForWidget;
91
+ // Determine if persistent chat history should be loaded based on all conditions
92
+ const shouldLoadPersistentHistoryMessages = shouldLoadPersistentChatHistory(extendedChatConfig);
96
93
  if (shouldLoadPersistentHistoryMessages) {
97
94
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
98
95
  Event: TelemetryEvent.PersistentChatHistoryEnabled
@@ -47,20 +47,14 @@ const convertPersistentChatHistoryMessageToActivity = message => {
47
47
  }
48
48
  }
49
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 = {
60
- ...activity.channelData,
61
- tags: [...activity.channelData.tags, ...formattedTags]
62
- };
63
- }
50
+ const formattedTags = additionalData.tags.split(",");
51
+ activity.channelData = {
52
+ ...activity.channelData,
53
+ tags: [...activity.channelData.tags, ...formattedTags]
54
+ };
55
+ }
56
+ if (additionalData !== null && additionalData !== void 0 && additionalData.ConversationId) {
57
+ activity.channelData.conversationId = additionalData.ConversationId;
64
58
  }
65
59
  if (from !== null && from !== void 0 && (_from$user = from.user) !== null && _from$user !== void 0 && _from$user.displayName) {
66
60
  activity.from = {
@@ -1,3 +1,5 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+
1
3
  import React, { useCallback, useEffect, useRef } from "react";
2
4
  import { KeyCodes } from "../../../../../../common/KeyCodes";
3
5
  import { Stack } from "@fluentui/react";
@@ -7,6 +7,7 @@
7
7
  import { Constants } from "../../../../../common/Constants";
8
8
  import { DeliveryMode } from "@microsoft/omnichannel-chat-sdk";
9
9
  import { WebChatActionType } from "../../enums/WebChatActionType";
10
+
10
11
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
11
12
  const channelDataMiddleware = addConversationalSurveyTagsCallback => _ref => {
12
13
  let {
@@ -1,6 +1,6 @@
1
+ import * as CustomEventType from "../contexts/common/CustomEventType";
1
2
  import { FacadeChatSDK } from "./facades/FacadeChatSDK";
2
3
  import { ITimer } from "./interfaces/ITimer";
3
- import * as CustomEventType from "../contexts/common/CustomEventType";
4
4
  export declare const setTabIndices: (elements: HTMLElement[] | null, tabIndexMap: Map<string, number>, shouldBeFocusable: boolean) => void;
5
5
  export declare const findParentFocusableElementsWithoutChildContainer: (elementId: string) => HTMLElement[] | null;
6
6
  export declare const findAllFocusableElement: (parent: string | HTMLElement) => any[] | null;
@@ -55,3 +55,11 @@ export declare function isEndConversationDueToOverflowActivity(activity: {
55
55
  tags?: string[];
56
56
  };
57
57
  }): boolean | undefined;
58
+ /**
59
+ * Parses a value that can be boolean or string ("true"/"false") into a boolean.
60
+ * Handles null/undefined by returning false.
61
+ *
62
+ * @param value - The value to parse (can be boolean, string, null, or undefined)
63
+ * @returns true if value is true or "true" (case-insensitive), false otherwise
64
+ */
65
+ export declare function parseBooleanFromConfig(value: boolean | string | null | undefined): boolean;
@@ -1,4 +1,4 @@
1
- import React, { Component } from 'react';
1
+ import React, { Component } from "react";
2
2
  interface ErrorBoundaryProps {
3
3
  children: React.ReactNode | (() => React.ReactNode);
4
4
  onError?: (error: Error) => void;
@@ -1,4 +1,15 @@
1
+ import { ExtendedChatConfig } from "../../webchatcontainerstateful/interfaces/IExtendedChatConffig";
1
2
  import { FacadeChatSDK } from "../../../common/facades/FacadeChatSDK";
2
3
  export declare const isPostChatSurveyEnabled: (facadeChatSDK: FacadeChatSDK) => Promise<boolean>;
3
4
  export declare const getPostChatSurveyConfig: (facadeChatSDK: FacadeChatSDK) => Promise<any>;
4
5
  export declare const isPersistentChatEnabled: (conversationMode: string | undefined) => boolean;
6
+ /**
7
+ * Determines if persistent chat history should be loaded based on all required conditions.
8
+ *
9
+ * @param extendedChatConfig - The extended chat configuration object
10
+ * @returns true if ALL conditions are met:
11
+ * 1. Conversation mode must be Persistent ("192350001")
12
+ * 2. History is enabled in admin config (msdyn_enablepersistentchatpreviousconversations)
13
+ * 3. History is enabled via feature flag (lcwPersistentChatHistoryEnabled)
14
+ */
15
+ export declare const shouldLoadPersistentChatHistory: (extendedChatConfig: ExtendedChatConfig | undefined) => boolean;
@@ -3,7 +3,7 @@ export interface ExtendedChatConfig {
3
3
  LiveChatConfigAuthSettings?: LiveChatConfigAuthSettings;
4
4
  LiveWSAndLiveChatEngJoin?: {
5
5
  msdyn_conversationmode?: string;
6
- msdyn_enablepersistentchatpreviousconversations?: boolean;
6
+ msdyn_enablepersistentchatpreviousconversations?: string;
7
7
  };
8
8
  }
9
9
  interface LcwFcbConfiguration {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microsoft/omnichannel-chat-widget",
3
- "version": "1.8.4-main.9ae37a9",
3
+ "version": "1.8.4-main.c687f88",
4
4
  "description": "Microsoft Omnichannel Chat Widget",
5
5
  "main": "lib/cjs/index.js",
6
6
  "types": "lib/types/index.d.ts",
@@ -108,7 +108,7 @@
108
108
  "compose-storybook": "start-storybook -c stories/.storybook -p 9009",
109
109
  "build-composite-storybook": "build-storybook -c stories/.storybook -o storybook-build",
110
110
  "build-storybook": "cross-env NODE_OPTIONS=--openssl-legacy-provider build-storybook",
111
- "build": "yarn clean yarn lint && yarn build:esm && yarn build:cjs && tsc",
111
+ "build": "yarn clean && yarn lint && yarn build:esm && yarn build:cjs && tsc",
112
112
  "test:unit": "jest -c jest.config.unit.cjs --env=jsdom --runInBand --force-exit",
113
113
  "test:e2e": "cd automation_tests && yarn test",
114
114
  "test:e2e:build": "yarn build-sample && cd automation_tests && yarn test",