@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.
- package/lib/cjs/common/telemetry/loggers/appInsightsLogger.js +7 -7
- package/lib/cjs/common/utils.js +14 -1
- package/lib/cjs/components/errorboundary/ErrorBoundary.js +2 -1
- package/lib/cjs/components/livechatwidget/common/endChat.js +5 -0
- package/lib/cjs/components/livechatwidget/common/liveChatConfigUtils.js +36 -4
- package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +2 -1
- package/lib/cjs/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +6 -4
- package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +3 -6
- package/lib/cjs/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +8 -14
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +2 -0
- package/lib/esm/common/telemetry/loggers/appInsightsLogger.js +7 -7
- package/lib/esm/common/utils.js +11 -0
- package/lib/esm/components/errorboundary/ErrorBoundary.js +4 -2
- package/lib/esm/components/livechatwidget/common/endChat.js +5 -0
- package/lib/esm/components/livechatwidget/common/liveChatConfigUtils.js +33 -2
- package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +2 -1
- package/lib/esm/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +6 -4
- package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +4 -7
- package/lib/esm/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +8 -14
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +2 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.js +1 -0
- package/lib/types/common/utils.d.ts +9 -1
- package/lib/types/components/errorboundary/ErrorBoundary.d.ts +1 -1
- package/lib/types/components/livechatwidget/common/liveChatConfigUtils.d.ts +11 -0
- package/lib/types/components/webchatcontainerstateful/interfaces/IExtendedChatConffig.d.ts +1 -1
- 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"] = "
|
|
18
|
-
AllowedKeys["ConversationId"] = "
|
|
17
|
+
AllowedKeys["OrganizationId"] = "powerplatform.analytics.resource.organization.id";
|
|
18
|
+
AllowedKeys["ConversationId"] = "powerplatform.analytics.resource.id";
|
|
19
19
|
AllowedKeys["ElapsedTimeInMilliseconds"] = "Duration";
|
|
20
|
-
AllowedKeys["Description"] = "
|
|
21
|
-
AllowedKeys["ChannelId"] = "
|
|
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.
|
|
99
|
-
|
|
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["
|
|
145
|
+
eventProperties["powerplatform.analytics.subscenario"] = eventName.includes(": ") ? eventName.split(": ")[1] : eventName;
|
|
146
146
|
return eventProperties;
|
|
147
147
|
}
|
|
148
148
|
function getTrackingEventName(logLevel, eventName) {
|
package/lib/cjs/common/utils.js
CHANGED
|
@@ -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.
|
|
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 ===
|
|
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()
|
|
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.
|
|
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
|
-
|
|
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,
|
|
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
|
-
//
|
|
104
|
-
const shouldLoadPersistentHistoryMessages =
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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"] = "
|
|
9
|
-
AllowedKeys["ConversationId"] = "
|
|
8
|
+
AllowedKeys["OrganizationId"] = "powerplatform.analytics.resource.organization.id";
|
|
9
|
+
AllowedKeys["ConversationId"] = "powerplatform.analytics.resource.id";
|
|
10
10
|
AllowedKeys["ElapsedTimeInMilliseconds"] = "Duration";
|
|
11
|
-
AllowedKeys["Description"] = "
|
|
12
|
-
AllowedKeys["ChannelId"] = "
|
|
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.
|
|
90
|
-
|
|
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["
|
|
136
|
+
eventProperties["powerplatform.analytics.subscenario"] = eventName.includes(": ") ? eventName.split(": ")[1] : eventName;
|
|
137
137
|
return eventProperties;
|
|
138
138
|
}
|
|
139
139
|
function getTrackingEventName(logLevel, eventName) {
|
package/lib/esm/common/utils.js
CHANGED
|
@@ -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
|
|
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 ===
|
|
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()
|
|
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
|
-
|
|
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 {
|
|
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,
|
|
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
|
-
//
|
|
95
|
-
const shouldLoadPersistentHistoryMessages =
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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 = {
|
|
@@ -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,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?:
|
|
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.
|
|
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",
|