@microsoft/omnichannel-chat-widget 1.8.2-main.fc93d3d → 1.8.3-main.1381896
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/README.md +46 -1
- package/lib/cjs/common/Constants.js +10 -2
- package/lib/cjs/common/telemetry/TelemetryConstants.js +6 -0
- package/lib/cjs/common/telemetry/TelemetryHelper.js +7 -5
- package/lib/cjs/common/utils.js +27 -2
- package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +4 -4
- package/lib/cjs/components/citationpanestateful/CitationDim.js +29 -0
- package/lib/cjs/components/citationpanestateful/CitationPaneStateful.js +199 -0
- package/lib/cjs/components/citationpanestateful/common/defaultProps/defaultCitationPaneProps.js +70 -0
- package/lib/cjs/components/confirmationpanestateful/interfaces/IConfirmationPaneLocalizedTexts.js +1 -0
- package/lib/cjs/components/livechatwidget/LiveChatWidget.js +4 -4
- package/lib/cjs/components/livechatwidget/common/ActivitySubscriber/BotAuthActivitySubscriber.js +4 -5
- package/lib/cjs/components/livechatwidget/common/createInternetConnectionChangeHandler.js +22 -9
- package/lib/cjs/components/livechatwidget/common/createMarkdown.js +54 -1
- package/lib/cjs/components/livechatwidget/common/customEventHandler.js +53 -0
- package/lib/cjs/components/livechatwidget/common/endChat.js +34 -4
- package/lib/cjs/components/livechatwidget/common/getMockChatSDKIfApplicable.js +4 -3
- package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +12 -5
- package/lib/cjs/components/livechatwidget/common/overridePropsOnMockIfApplicable.js +2 -1
- package/lib/cjs/components/livechatwidget/common/renderSurveyHelpers.js +23 -0
- package/lib/cjs/components/livechatwidget/common/startChat.js +8 -6
- package/lib/cjs/components/livechatwidget/interfaces/IMockProps.js +8 -2
- package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +45 -11
- package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +114 -13
- package/lib/cjs/components/webchatcontainerstateful/common/DesignerChatAdapter.js +43 -12
- package/lib/cjs/components/webchatcontainerstateful/common/DesignerChatSDK.js +6 -1
- package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +1 -1
- package/lib/cjs/components/webchatcontainerstateful/common/utils/chatAdapterUtils.js +62 -3
- package/lib/cjs/components/webchatcontainerstateful/common/utils/fontUtils.js +28 -0
- package/lib/cjs/components/webchatcontainerstateful/interfaces/ICitation.js +1 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultAvatarTextStyles.js +1 -1
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSystemMessageStyles.js +1 -1
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.js +42 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.js +139 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +41 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +54 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +45 -0
- package/lib/cjs/contexts/common/CustomEventType.js +1 -0
- package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +46 -45
- package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +2 -0
- package/lib/cjs/contexts/createReducer.js +15 -0
- package/lib/cjs/firstresponselatency/FirstMessageTrackerFromBot.js +101 -36
- package/lib/cjs/firstresponselatency/FirstResponseLatencyTracker.js +39 -21
- package/lib/cjs/firstresponselatency/util.js +24 -10
- package/lib/cjs/index.js +9 -1
- package/lib/cjs/plugins/createChatTranscript.js +13 -0
- package/lib/cjs/plugins/newMessageEventHandler.js +2 -2
- package/lib/esm/common/Constants.js +10 -2
- package/lib/esm/common/telemetry/TelemetryConstants.js +6 -0
- package/lib/esm/common/telemetry/TelemetryHelper.js +7 -5
- package/lib/esm/common/utils.js +21 -0
- package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +4 -4
- package/lib/esm/components/citationpanestateful/CitationDim.js +20 -0
- package/lib/esm/components/citationpanestateful/CitationPaneStateful.js +188 -0
- package/lib/esm/components/citationpanestateful/common/defaultProps/defaultCitationPaneProps.js +61 -0
- package/lib/esm/components/confirmationpanestateful/interfaces/IConfirmationPaneLocalizedTexts.js +1 -0
- package/lib/esm/components/livechatwidget/LiveChatWidget.js +4 -4
- package/lib/esm/components/livechatwidget/common/ActivitySubscriber/BotAuthActivitySubscriber.js +4 -5
- package/lib/esm/components/livechatwidget/common/createInternetConnectionChangeHandler.js +22 -9
- package/lib/esm/components/livechatwidget/common/createMarkdown.js +54 -1
- package/lib/esm/components/livechatwidget/common/customEventHandler.js +45 -0
- package/lib/esm/components/livechatwidget/common/endChat.js +35 -5
- package/lib/esm/components/livechatwidget/common/getMockChatSDKIfApplicable.js +4 -3
- package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +13 -6
- package/lib/esm/components/livechatwidget/common/overridePropsOnMockIfApplicable.js +2 -1
- package/lib/esm/components/livechatwidget/common/renderSurveyHelpers.js +23 -0
- package/lib/esm/components/livechatwidget/common/startChat.js +8 -6
- package/lib/esm/components/livechatwidget/interfaces/IMockProps.js +3 -3
- package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +45 -11
- package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +114 -14
- package/lib/esm/components/webchatcontainerstateful/common/DesignerChatAdapter.js +43 -12
- package/lib/esm/components/webchatcontainerstateful/common/DesignerChatSDK.js +6 -1
- package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +1 -1
- package/lib/esm/components/webchatcontainerstateful/common/utils/chatAdapterUtils.js +55 -0
- package/lib/esm/components/webchatcontainerstateful/common/utils/fontUtils.js +21 -0
- package/lib/esm/components/webchatcontainerstateful/interfaces/ICitation.js +1 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultAvatarTextStyles.js +1 -1
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSystemMessageStyles.js +1 -1
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.js +36 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.js +133 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +33 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +46 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +38 -0
- package/lib/esm/contexts/common/CustomEventType.js +1 -0
- package/lib/esm/contexts/common/LiveChatWidgetActionType.js +46 -45
- package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +2 -0
- package/lib/esm/contexts/createReducer.js +15 -0
- package/lib/esm/firstresponselatency/FirstMessageTrackerFromBot.js +101 -36
- package/lib/esm/firstresponselatency/FirstResponseLatencyTracker.js +39 -21
- package/lib/esm/firstresponselatency/util.js +21 -8
- package/lib/esm/index.js +1 -0
- package/lib/esm/plugins/createChatTranscript.js +13 -0
- package/lib/esm/plugins/newMessageEventHandler.js +3 -3
- package/lib/types/common/Constants.d.ts +10 -2
- package/lib/types/common/telemetry/TelemetryConstants.d.ts +6 -0
- package/lib/types/common/utils.d.ts +8 -0
- package/lib/types/components/citationpanestateful/CitationDim.d.ts +5 -0
- package/lib/types/components/citationpanestateful/CitationPaneStateful.d.ts +4 -0
- package/lib/types/components/citationpanestateful/common/defaultProps/defaultCitationPaneProps.d.ts +11 -0
- package/lib/types/components/citationpanestateful/interfaces/ICitationPaneStatefulProps.d.ts +19 -0
- package/lib/types/components/confirmationpanestateful/common/defaultProps/defaultConfirmationPaneLocalizedTexts.d.ts +1 -1
- package/lib/types/components/confirmationpanestateful/interfaces/IConfirmationPaneStatefulProps.d.ts +1 -1
- package/lib/types/components/livechatwidget/common/customEventHandler.d.ts +4 -0
- package/lib/types/components/livechatwidget/common/getMockChatSDKIfApplicable.d.ts +2 -1
- package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetProps.d.ts +3 -1
- package/lib/types/components/livechatwidget/interfaces/IMockProps.d.ts +5 -3
- package/lib/types/components/webchatcontainerstateful/common/DesignerChatAdapter.d.ts +4 -2
- package/lib/types/components/webchatcontainerstateful/common/DesignerChatSDK.d.ts +5 -0
- package/lib/types/components/webchatcontainerstateful/common/utils/chatAdapterUtils.d.ts +8 -1
- package/lib/types/components/webchatcontainerstateful/common/utils/fontUtils.d.ts +10 -0
- package/lib/types/components/webchatcontainerstateful/interfaces/ICitation.d.ts +12 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.d.ts +8 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.d.ts +4 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.d.ts +22 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.d.ts +5 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.d.ts +5 -0
- package/lib/types/contexts/common/CustomEventType.d.ts +6 -0
- package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +1 -0
- package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +46 -45
- package/lib/types/firstresponselatency/FirstResponseLatencyTracker.d.ts +2 -2
- package/lib/types/firstresponselatency/util.d.ts +1 -0
- package/lib/types/index.d.ts +1 -0
- package/package.json +5 -4
- /package/lib/cjs/components/{confirmationpanestateful/interfaces/IConfirmationPaneLocalizedText.js → citationpanestateful/interfaces/ICitationPaneStatefulProps.js} +0 -0
- /package/lib/esm/components/{confirmationpanestateful/interfaces/IConfirmationPaneLocalizedText.js → citationpanestateful/interfaces/ICitationPaneStatefulProps.js} +0 -0
- /package/lib/types/components/confirmationpanestateful/interfaces/{IConfirmationPaneLocalizedText.d.ts → IConfirmationPaneLocalizedTexts.d.ts} +0 -0
|
@@ -65,7 +65,6 @@ export const ChatButtonStateful = props => {
|
|
|
65
65
|
};
|
|
66
66
|
const outOfOfficeStyleProps = Object.assign({}, defaultOutOfOfficeChatButtonStyleProps, outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.styleProps);
|
|
67
67
|
const controlProps = {
|
|
68
|
-
...(buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.controlProps),
|
|
69
68
|
id: "oc-lcw-chat-button",
|
|
70
69
|
dir: state.domainStates.globalDir,
|
|
71
70
|
titleText: "Let's Chat!",
|
|
@@ -74,7 +73,8 @@ export const ChatButtonStateful = props => {
|
|
|
74
73
|
unreadMessageCount: state.appStates.unreadMessageCount ? state.appStates.unreadMessageCount > Constants.maximumUnreadMessageCount ? (_props$buttonProps = props.buttonProps) === null || _props$buttonProps === void 0 ? void 0 : (_props$buttonProps$co = _props$buttonProps.controlProps) === null || _props$buttonProps$co === void 0 ? void 0 : _props$buttonProps$co.largeUnreadMessageString : state.appStates.unreadMessageCount.toString() : "0",
|
|
75
74
|
unreadMessageString: (_props$buttonProps2 = props.buttonProps) === null || _props$buttonProps2 === void 0 ? void 0 : (_props$buttonProps2$c = _props$buttonProps2.controlProps) === null || _props$buttonProps2$c === void 0 ? void 0 : _props$buttonProps2$c.unreadMessageString,
|
|
76
75
|
// Regular chat button onClick - this will always take precedence
|
|
77
|
-
onClick: () => ref.current()
|
|
76
|
+
onClick: () => ref.current(),
|
|
77
|
+
...(buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.controlProps)
|
|
78
78
|
};
|
|
79
79
|
const outOfOfficeControlProps = {
|
|
80
80
|
// Only take specific properties from outOfOfficeButtonProps, never onClick
|
|
@@ -83,7 +83,6 @@ export const ChatButtonStateful = props => {
|
|
|
83
83
|
titleText: (outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : (_outOfOfficeButtonPro = outOfOfficeButtonProps.controlProps) === null || _outOfOfficeButtonPro === void 0 ? void 0 : _outOfOfficeButtonPro.titleText) || "We're Offline",
|
|
84
84
|
subtitleText: (outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : (_outOfOfficeButtonPro2 = outOfOfficeButtonProps.controlProps) === null || _outOfOfficeButtonPro2 === void 0 ? void 0 : _outOfOfficeButtonPro2.subtitleText) || "No agents available",
|
|
85
85
|
unreadMessageString: (_props$buttonProps3 = props.buttonProps) === null || _props$buttonProps3 === void 0 ? void 0 : (_props$buttonProps3$c = _props$buttonProps3.controlProps) === null || _props$buttonProps3$c === void 0 ? void 0 : _props$buttonProps3$c.unreadMessageString,
|
|
86
|
-
...(outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.controlProps),
|
|
87
86
|
// Out-of-office specific onClick - this will ALWAYS take precedence
|
|
88
87
|
onClick: () => {
|
|
89
88
|
if (state.appStates.isMinimized) {
|
|
@@ -96,7 +95,8 @@ export const ChatButtonStateful = props => {
|
|
|
96
95
|
type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
|
|
97
96
|
payload: ConversationState.OutOfOffice
|
|
98
97
|
});
|
|
99
|
-
}
|
|
98
|
+
},
|
|
99
|
+
...(outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.controlProps)
|
|
100
100
|
};
|
|
101
101
|
useEffect(() => {
|
|
102
102
|
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import ReactDOM from "react-dom";
|
|
3
|
+
import { DimLayer } from "../dimlayer/DimLayer";
|
|
4
|
+
const CONTAINER_SELECTOR = ".webchat__stacked-layout_container";
|
|
5
|
+
export const CitationDim = _ref => {
|
|
6
|
+
let {
|
|
7
|
+
brightness = "0.2"
|
|
8
|
+
} = _ref;
|
|
9
|
+
const container = document.querySelector(CONTAINER_SELECTOR);
|
|
10
|
+
if (!container) return null;
|
|
11
|
+
return /*#__PURE__*/ReactDOM.createPortal( /*#__PURE__*/React.createElement("div", {
|
|
12
|
+
style: {
|
|
13
|
+
position: "absolute",
|
|
14
|
+
inset: 0
|
|
15
|
+
}
|
|
16
|
+
}, /*#__PURE__*/React.createElement(DimLayer, {
|
|
17
|
+
brightness: brightness
|
|
18
|
+
})), container);
|
|
19
|
+
};
|
|
20
|
+
export default CitationDim;
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
|
|
2
|
+
import React, { useEffect, useState } from "react";
|
|
3
|
+
import { createTimer, findAllFocusableElement, findParentFocusableElementsWithoutChildContainer, preventFocusToMoveOutOfElement, setTabIndices } from "../../common/utils";
|
|
4
|
+
import CitationDim from "./CitationDim";
|
|
5
|
+
import { CitationPane } from "@microsoft/omnichannel-chat-components";
|
|
6
|
+
import { HtmlAttributeNames } from "../../common/Constants";
|
|
7
|
+
import { LiveChatWidgetActionType } from "../../contexts/common/LiveChatWidgetActionType";
|
|
8
|
+
import { TelemetryHelper } from "../../common/telemetry/TelemetryHelper";
|
|
9
|
+
import { defaultCitationPaneStyles } from "./common/defaultProps/defaultCitationPaneProps";
|
|
10
|
+
import useChatContextStore from "../../hooks/useChatContextStore";
|
|
11
|
+
let uiTimer;
|
|
12
|
+
export const CitationPaneStateful = props => {
|
|
13
|
+
var _props$styleProps3;
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
uiTimer = createTimer();
|
|
16
|
+
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
17
|
+
Event: TelemetryEvent.UXCitationPaneStart
|
|
18
|
+
});
|
|
19
|
+
}, []);
|
|
20
|
+
const initialTabIndexMap = new Map();
|
|
21
|
+
let elements = [];
|
|
22
|
+
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
24
|
+
const [state, dispatch] = useChatContextStore();
|
|
25
|
+
|
|
26
|
+
// Use props.id if provided, otherwise fall back to default
|
|
27
|
+
const controlId = props.id || HtmlAttributeNames.ocwCitationPaneClassName;
|
|
28
|
+
|
|
29
|
+
// Pane style computed to match the webchat widget container bounds so the pane
|
|
30
|
+
// stays within the widget and scrolls only vertically. We also track an
|
|
31
|
+
// "isReady" flag so we don't render the pane contents until the style is
|
|
32
|
+
// computed — this prevents a transient render that can appear as a flicker.
|
|
33
|
+
const [paneStyle, setPaneStyle] = useState(null);
|
|
34
|
+
const [isReady, setIsReady] = useState(false);
|
|
35
|
+
|
|
36
|
+
// Move focus to the container
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
preventFocusToMoveOutOfElement(controlId);
|
|
39
|
+
const focusableElements = findAllFocusableElement(`#${controlId}`);
|
|
40
|
+
requestAnimationFrame(() => {
|
|
41
|
+
if (focusableElements && focusableElements.length > 0 && focusableElements[0]) {
|
|
42
|
+
focusableElements[0].focus({
|
|
43
|
+
preventScroll: true
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
elements = findParentFocusableElementsWithoutChildContainer(controlId);
|
|
48
|
+
setTabIndices(elements, initialTabIndexMap, false);
|
|
49
|
+
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
50
|
+
Event: TelemetryEvent.CitationPaneLoaded
|
|
51
|
+
});
|
|
52
|
+
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
53
|
+
Event: TelemetryEvent.UXCitationPaneCompleted,
|
|
54
|
+
ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
|
|
55
|
+
});
|
|
56
|
+
}, []);
|
|
57
|
+
|
|
58
|
+
// Compute the widget bounds and set pane style accordingly (95% of widget size
|
|
59
|
+
// and centered inside the widget). If the widget container can't be found,
|
|
60
|
+
// fall back to the default pane styles from defaultCitationPaneProps.
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
const compute = () => {
|
|
63
|
+
var _props$styleProps2;
|
|
64
|
+
try {
|
|
65
|
+
const container = document.querySelector(".webchat__stacked-layout_container");
|
|
66
|
+
if (container) {
|
|
67
|
+
var _props$styleProps;
|
|
68
|
+
const rect = container.getBoundingClientRect();
|
|
69
|
+
const widthPx = Math.round(rect.width * 0.95);
|
|
70
|
+
const heightPx = Math.round(rect.height * 0.95);
|
|
71
|
+
const leftPx = Math.round(rect.left + (rect.width - widthPx) / 2);
|
|
72
|
+
const topPx = Math.round(rect.top + (rect.height - heightPx) / 2);
|
|
73
|
+
// Clone defaults and remove transform so explicit left/top pixel
|
|
74
|
+
// coordinates are respected and the pane stays within the
|
|
75
|
+
// widget bounds.
|
|
76
|
+
const base = Object.assign({}, defaultCitationPaneStyles.pane);
|
|
77
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
78
|
+
if (base && base.transform) {
|
|
79
|
+
// remove centering transform when we compute exact pixel coords
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
81
|
+
delete base.transform;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Merge user styles first, then computed positioning to ensure proper positioning
|
|
85
|
+
const computedStyle = {
|
|
86
|
+
left: `${leftPx}px`,
|
|
87
|
+
top: `${topPx}px`,
|
|
88
|
+
width: `${widthPx}px`,
|
|
89
|
+
height: `${heightPx}px`
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// Apply user styles first, then override with computed positioning
|
|
93
|
+
const generalProps = (_props$styleProps = props.styleProps) === null || _props$styleProps === void 0 ? void 0 : _props$styleProps.generalStyleProps;
|
|
94
|
+
const userStyles = generalProps && typeof generalProps === "object" ? Object.assign({}, generalProps) : {};
|
|
95
|
+
// Remove positioning properties from user styles that would interfere
|
|
96
|
+
delete userStyles.position;
|
|
97
|
+
delete userStyles.left;
|
|
98
|
+
delete userStyles.top;
|
|
99
|
+
delete userStyles.width;
|
|
100
|
+
delete userStyles.height;
|
|
101
|
+
setPaneStyle(Object.assign({}, base, userStyles, computedStyle));
|
|
102
|
+
// Make the pane visible after the next paint to avoid layout
|
|
103
|
+
// flashes on initial mount.
|
|
104
|
+
requestAnimationFrame(() => setIsReady(true));
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
} catch (e) {
|
|
108
|
+
// ignore
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// fallback - merge defaults with user-provided styles but preserve positioning
|
|
112
|
+
const generalProps = (_props$styleProps2 = props.styleProps) === null || _props$styleProps2 === void 0 ? void 0 : _props$styleProps2.generalStyleProps;
|
|
113
|
+
const userStyles = generalProps && typeof generalProps === "object" ? Object.assign({}, generalProps) : {};
|
|
114
|
+
// Remove positioning properties from user styles for fallback
|
|
115
|
+
delete userStyles.position;
|
|
116
|
+
delete userStyles.left;
|
|
117
|
+
delete userStyles.top;
|
|
118
|
+
delete userStyles.width;
|
|
119
|
+
delete userStyles.height;
|
|
120
|
+
const fallbackStyle = Object.assign({}, defaultCitationPaneStyles.pane, userStyles);
|
|
121
|
+
setPaneStyle(fallbackStyle);
|
|
122
|
+
requestAnimationFrame(() => setIsReady(true));
|
|
123
|
+
};
|
|
124
|
+
compute();
|
|
125
|
+
window.addEventListener("resize", compute);
|
|
126
|
+
return () => window.removeEventListener("resize", compute);
|
|
127
|
+
}, [(_props$styleProps3 = props.styleProps) === null || _props$styleProps3 === void 0 ? void 0 : _props$styleProps3.generalStyleProps]);
|
|
128
|
+
const handleClose = () => {
|
|
129
|
+
if (props.onClose) props.onClose();
|
|
130
|
+
dispatch({
|
|
131
|
+
type: LiveChatWidgetActionType.SET_PREVIOUS_FOCUSED_ELEMENT_ID,
|
|
132
|
+
payload: null
|
|
133
|
+
});
|
|
134
|
+
setTabIndices(elements, initialTabIndexMap, true);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// Merge a safe style object for the container and cast to CSSProperties to satisfy TS
|
|
138
|
+
const baseStyle = Object.assign({
|
|
139
|
+
position: "relative"
|
|
140
|
+
}, paneStyle ?? {
|
|
141
|
+
position: "fixed"
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// If paneStyle hasn't been computed yet, render the DimLayer so clicks
|
|
145
|
+
// still close overlays but hide the pane itself to avoid flashes.
|
|
146
|
+
const hiddenStyle = {
|
|
147
|
+
visibility: isReady ? "visible" : "hidden",
|
|
148
|
+
pointerEvents: isReady ? "auto" : "none"
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// Default wrapper styles - these control the positioning container
|
|
152
|
+
const defaultWrapperStyles = {
|
|
153
|
+
display: "flex",
|
|
154
|
+
flexDirection: "column",
|
|
155
|
+
zIndex: 10001
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// Wrapper styles for the positioning container
|
|
159
|
+
const wrapperStyles = Object.assign({}, baseStyle, hiddenStyle, defaultWrapperStyles);
|
|
160
|
+
|
|
161
|
+
// Merge the computed positioning styles with user's generalStyleProps for the CitationPane
|
|
162
|
+
const mergedStyleProps = props.styleProps ? {
|
|
163
|
+
...props.styleProps,
|
|
164
|
+
generalStyleProps: Object.assign({}, props.styleProps.generalStyleProps)
|
|
165
|
+
} : undefined;
|
|
166
|
+
const controlProps = {
|
|
167
|
+
id: controlId,
|
|
168
|
+
dir: state.domainStates.globalDir,
|
|
169
|
+
titleText: props.title,
|
|
170
|
+
contentHtml: props.contentHtml,
|
|
171
|
+
brightnessValueOnDim: "0.2",
|
|
172
|
+
// Default brightness
|
|
173
|
+
onClose: handleClose,
|
|
174
|
+
...(props === null || props === void 0 ? void 0 : props.controlProps) // User props override defaults
|
|
175
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(CitationDim, {
|
|
179
|
+
brightness: controlProps.brightnessValueOnDim
|
|
180
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
181
|
+
style: wrapperStyles
|
|
182
|
+
}, /*#__PURE__*/React.createElement(CitationPane, {
|
|
183
|
+
componentOverrides: props === null || props === void 0 ? void 0 : props.componentOverrides,
|
|
184
|
+
controlProps: controlProps,
|
|
185
|
+
styleProps: mergedStyleProps
|
|
186
|
+
})));
|
|
187
|
+
};
|
|
188
|
+
export default CitationPaneStateful;
|
package/lib/esm/components/citationpanestateful/common/defaultProps/defaultCitationPaneProps.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export const defaultCitationPaneStyles = {
|
|
2
|
+
pane: {
|
|
3
|
+
position: "fixed",
|
|
4
|
+
left: "50%",
|
|
5
|
+
top: "18%",
|
|
6
|
+
transform: "translateX(-50%)",
|
|
7
|
+
background: "#fff",
|
|
8
|
+
width: "85%",
|
|
9
|
+
height: "85%",
|
|
10
|
+
overflowY: "auto",
|
|
11
|
+
overflowX: "hidden",
|
|
12
|
+
padding: 16,
|
|
13
|
+
borderRadius: 6,
|
|
14
|
+
zIndex: 10001,
|
|
15
|
+
boxSizing: "border-box"
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
export const defaultCitationContentCSS = controlId => `
|
|
19
|
+
#${controlId} .citation-content {
|
|
20
|
+
flex: 1;
|
|
21
|
+
min-height: 0; /* allow flex child to scroll */
|
|
22
|
+
overflow-y: auto;
|
|
23
|
+
overflow-x: auto;
|
|
24
|
+
margin-bottom: 12px;
|
|
25
|
+
white-space: normal; /* wrap normal text */
|
|
26
|
+
word-break: break-word;
|
|
27
|
+
-webkit-overflow-scrolling: touch;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
#${controlId} .citation-content pre,
|
|
31
|
+
#${controlId} .citation-content code {
|
|
32
|
+
white-space: pre; /* preserve formatting */
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
#${controlId} .citation-content table {
|
|
36
|
+
width: 100%;
|
|
37
|
+
border-collapse: collapse;
|
|
38
|
+
margin-bottom: 12px;
|
|
39
|
+
table-layout: auto;
|
|
40
|
+
overflow-x: auto;
|
|
41
|
+
display: block;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
#${controlId} .citation-content table th,
|
|
45
|
+
#${controlId} .citation-content table td {
|
|
46
|
+
padding: 8px 12px;
|
|
47
|
+
border: 1px solid rgba(0,0,0,0.08);
|
|
48
|
+
text-align: left;
|
|
49
|
+
vertical-align: top;
|
|
50
|
+
word-break: break-word;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
#${controlId} .citation-content img {
|
|
54
|
+
max-width: 100%;
|
|
55
|
+
height: auto;
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
58
|
+
export default {
|
|
59
|
+
defaultCitationPaneStyles,
|
|
60
|
+
defaultCitationContentCSS
|
|
61
|
+
};
|
package/lib/esm/components/confirmationpanestateful/interfaces/IConfirmationPaneLocalizedTexts.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -13,13 +13,13 @@ import { isPersistentChatEnabled } from "./common/liveChatConfigUtils";
|
|
|
13
13
|
import overridePropsOnMockIfApplicable from "./common/overridePropsOnMockIfApplicable";
|
|
14
14
|
import { registerTelemetryLoggers } from "./common/registerTelemetryLoggers";
|
|
15
15
|
export const LiveChatWidget = props => {
|
|
16
|
-
var _props$
|
|
16
|
+
var _props$featureConfigP, _props$chatConfig, _props$chatConfig$Liv, _props$chatConfig2, _props$chatConfig2$Li;
|
|
17
17
|
const reducer = createReducer();
|
|
18
18
|
const [state, dispatch] = useReducer(reducer, getLiveChatWidgetContextInitialState(props));
|
|
19
19
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
20
|
const [adapter, setAdapter] = useState(undefined);
|
|
21
21
|
const [facadeChatSDK, setFacadeChatSDK] = useState(undefined);
|
|
22
|
-
const chatSDK = getMockChatSDKIfApplicable(props.chatSDK, props === null || props === void 0 ? void 0 :
|
|
22
|
+
const chatSDK = getMockChatSDKIfApplicable(props.chatSDK, props === null || props === void 0 ? void 0 : props.mock);
|
|
23
23
|
const disableReauthentication = ((_props$featureConfigP = props.featureConfigProps) === null || _props$featureConfigP === void 0 ? void 0 : _props$featureConfigP.disableReauthentication) === true;
|
|
24
24
|
overridePropsOnMockIfApplicable(props);
|
|
25
25
|
if (!props.chatConfig) {
|
|
@@ -29,14 +29,14 @@ export const LiveChatWidget = props => {
|
|
|
29
29
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
30
|
const isAuthenticatedChat = !!((_props$chatConfig = props.chatConfig) !== null && _props$chatConfig !== void 0 && (_props$chatConfig$Liv = _props$chatConfig.LiveChatConfigAuthSettings) !== null && _props$chatConfig$Liv !== void 0 && _props$chatConfig$Liv.msdyn_javascriptclientfunction) || isPersistentChatEnabled((_props$chatConfig2 = props.chatConfig) === null || _props$chatConfig2 === void 0 ? void 0 : (_props$chatConfig2$Li = _props$chatConfig2.LiveWSAndLiveChatEngJoin) === null || _props$chatConfig2$Li === void 0 ? void 0 : _props$chatConfig2$Li.msdyn_conversationmode);
|
|
31
31
|
if (!facadeChatSDK) {
|
|
32
|
-
var _props$
|
|
32
|
+
var _props$mock;
|
|
33
33
|
setFacadeChatSDK(new FacadeChatSDK({
|
|
34
34
|
"chatSDK": chatSDK,
|
|
35
35
|
"chatConfig": props.chatConfig,
|
|
36
36
|
"isAuthenticated": isAuthenticatedChat,
|
|
37
37
|
"getAuthToken": props === null || props === void 0 ? void 0 : props.getAuthToken,
|
|
38
38
|
//when type is not undefined, it means the SDK is mocked
|
|
39
|
-
"isSDKMocked": !isNullOrUndefined(props === null || props === void 0 ? void 0 : (_props$
|
|
39
|
+
"isSDKMocked": !isNullOrUndefined(props === null || props === void 0 ? void 0 : (_props$mock = props.mock) === null || _props$mock === void 0 ? void 0 : _props$mock.type)
|
|
40
40
|
}, disableReauthentication));
|
|
41
41
|
}
|
|
42
42
|
useEffect(() => {
|
package/lib/esm/components/livechatwidget/common/ActivitySubscriber/BotAuthActivitySubscriber.js
CHANGED
|
@@ -13,7 +13,6 @@ import { TelemetryManager } from "../../../../common/telemetry/TelemetryManager"
|
|
|
13
13
|
const supportedSignInCardContentTypes = ["application/vnd.microsoft.card.signin", "application/vnd.microsoft.card.oauth"];
|
|
14
14
|
const botOauthUrlRegex = /[\S]+.botframework.com\/api\/oauth\/signin\?signin=([\S]+)/;
|
|
15
15
|
const delay = t => new Promise(resolve => setTimeout(resolve, t));
|
|
16
|
-
let response;
|
|
17
16
|
const extractSignInId = signInUrl => {
|
|
18
17
|
const result = botOauthUrlRegex.exec(signInUrl);
|
|
19
18
|
if (result && result[1]) {
|
|
@@ -49,20 +48,20 @@ const fetchBotAuthConfig = async (retries, interval) => {
|
|
|
49
48
|
eventName: BroadcastEvent.BotAuthConfigRequest
|
|
50
49
|
};
|
|
51
50
|
BroadcastService.postMessage(botAuthConfigRequestEvent);
|
|
51
|
+
let response;
|
|
52
52
|
const listener = BroadcastService.getMessageByEventName(BroadcastEvent.BotAuthConfigResponse).subscribe(data => {
|
|
53
53
|
var _data$payload, _data$payload2;
|
|
54
54
|
response = ((_data$payload = data.payload) === null || _data$payload === void 0 ? void 0 : _data$payload.response) !== undefined ? (_data$payload2 = data.payload) === null || _data$payload2 === void 0 ? void 0 : _data$payload2.response : response;
|
|
55
55
|
listener.unsubscribe();
|
|
56
56
|
});
|
|
57
|
-
if (response !== undefined) {
|
|
58
|
-
//return response;
|
|
59
|
-
return response;
|
|
60
|
-
}
|
|
61
57
|
if (retries === 1) {
|
|
62
58
|
// Base Case
|
|
63
59
|
throw new Error();
|
|
64
60
|
}
|
|
65
61
|
await delay(interval);
|
|
62
|
+
if (response !== undefined) {
|
|
63
|
+
return response;
|
|
64
|
+
}
|
|
66
65
|
return await fetchBotAuthConfig(--retries, interval);
|
|
67
66
|
};
|
|
68
67
|
export let BotAuthActivitySubscriber = /*#__PURE__*/function () {
|
|
@@ -7,34 +7,47 @@ import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
|
|
|
7
7
|
import { defaultMiddlewareLocalizedTexts } from "../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts";
|
|
8
8
|
import { executeReducer } from "../../../contexts/createReducer";
|
|
9
9
|
import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
|
|
10
|
-
const
|
|
10
|
+
const getRegionBasedInternetTestUrl = widgetSnippet => {
|
|
11
|
+
var _widgetSnippet$match;
|
|
12
|
+
if (!widgetSnippet) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const widgetSnippetSourceRegex = new RegExp("src=\"(https:\\/\\/[\\w-.]+)[\\w-.\\/]+\"");
|
|
16
|
+
const baseCdnUrl = (_widgetSnippet$match = widgetSnippet.match(widgetSnippetSourceRegex)) === null || _widgetSnippet$match === void 0 ? void 0 : _widgetSnippet$match[1];
|
|
17
|
+
return baseCdnUrl ? `${baseCdnUrl}${Constants.internetConnectionTestPath}` : null;
|
|
18
|
+
};
|
|
19
|
+
const isInternetConnected = async testUrl => {
|
|
11
20
|
try {
|
|
12
|
-
const response = await fetch(
|
|
13
|
-
|
|
14
|
-
|
|
21
|
+
const response = await fetch(testUrl, {
|
|
22
|
+
method: "GET",
|
|
23
|
+
cache: "no-cache"
|
|
24
|
+
});
|
|
25
|
+
return response.ok;
|
|
15
26
|
} catch {
|
|
16
27
|
return false;
|
|
17
28
|
}
|
|
18
29
|
};
|
|
19
30
|
export const createInternetConnectionChangeHandler = async state => {
|
|
20
31
|
const handler = async () => {
|
|
21
|
-
|
|
32
|
+
var _inMemoryState$domain, _inMemoryState$domain2;
|
|
22
33
|
const inMemoryState = executeReducer(state, {
|
|
23
34
|
type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
|
|
24
35
|
payload: null
|
|
25
36
|
});
|
|
37
|
+
const testUrl = getRegionBasedInternetTestUrl((_inMemoryState$domain = inMemoryState.domainStates.liveChatConfig) === null || _inMemoryState$domain === void 0 ? void 0 : (_inMemoryState$domain2 = _inMemoryState$domain.LiveWSAndLiveChatEngJoin) === null || _inMemoryState$domain2 === void 0 ? void 0 : _inMemoryState$domain2.msdyn_widgetsnippet);
|
|
38
|
+
const connected = testUrl ? await isInternetConnected(testUrl) : false;
|
|
26
39
|
if (!connected) {
|
|
27
|
-
var _inMemoryState$
|
|
40
|
+
var _inMemoryState$domain3, _inMemoryState$domain4;
|
|
28
41
|
TelemetryHelper.logActionEvent(LogLevel.WARN, {
|
|
29
42
|
Event: TelemetryEvent.NetworkDisconnected
|
|
30
43
|
});
|
|
31
|
-
NotificationHandler.notifyError(NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$
|
|
44
|
+
NotificationHandler.notifyError(NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain3 = inMemoryState.domainStates) === null || _inMemoryState$domain3 === void 0 ? void 0 : (_inMemoryState$domain4 = _inMemoryState$domain3.middlewareLocalizedTexts) === null || _inMemoryState$domain4 === void 0 ? void 0 : _inMemoryState$domain4.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION);
|
|
32
45
|
} else {
|
|
33
|
-
var _inMemoryState$
|
|
46
|
+
var _inMemoryState$domain5, _inMemoryState$domain6;
|
|
34
47
|
TelemetryHelper.logActionEvent(LogLevel.WARN, {
|
|
35
48
|
Event: TelemetryEvent.NetworkReconnected
|
|
36
49
|
});
|
|
37
|
-
NotificationHandler.notifySuccess(NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$
|
|
50
|
+
NotificationHandler.notifySuccess(NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain5 = inMemoryState.domainStates) === null || _inMemoryState$domain5 === void 0 ? void 0 : (_inMemoryState$domain6 = _inMemoryState$domain5.middlewareLocalizedTexts) === null || _inMemoryState$domain6 === void 0 ? void 0 : _inMemoryState$domain6.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE);
|
|
38
51
|
BroadcastService.postMessage({
|
|
39
52
|
eventName: BroadcastEvent.NetworkReconnected
|
|
40
53
|
});
|
|
@@ -28,12 +28,65 @@ export const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineM
|
|
|
28
28
|
// Rule to process html blocks and paragraphs
|
|
29
29
|
"html_inline",
|
|
30
30
|
// Rule to process html tags
|
|
31
|
-
"newline"
|
|
31
|
+
"newline",
|
|
32
|
+
// Rule to proceess '\n'
|
|
33
|
+
"list" // Enable list parsing rule
|
|
32
34
|
]);
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
markdown.disable(["strikethrough"]);
|
|
36
38
|
|
|
39
|
+
// Custom plugin to fix numbered list continuity
|
|
40
|
+
markdown.use(function (md) {
|
|
41
|
+
const originalRender = md.render.bind(md);
|
|
42
|
+
const originalRenderInline = md.renderInline.bind(md);
|
|
43
|
+
function preprocessText(text) {
|
|
44
|
+
// Handle numbered lists that come with double line breaks (knowledge article format)
|
|
45
|
+
// This ensures proper continuous numbering instead of separate lists
|
|
46
|
+
|
|
47
|
+
let result = text;
|
|
48
|
+
|
|
49
|
+
// Only process if the text contains the double line break pattern
|
|
50
|
+
// But exclude simple numbered lists (where content after \n\n starts with another number)
|
|
51
|
+
if (!/\d+\.\s+.*?\n\n(?!\d+\.\s)[\s\S]*?(?:\n\n\d+\.|\s*$)/.test(text)) {
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Convert "1. Item\n\nContent\n\n2. Item" to proper markdown list format
|
|
56
|
+
// Use improved pattern with negative lookahead to exclude cases where content starts with numbered list
|
|
57
|
+
const listPattern = /(\d+\.\s+[^\n]+)(\n\n(?!\d+\.\s)[\s\S]*?)(?=\n\n\d+\.|\s*$)/g;
|
|
58
|
+
if (listPattern.test(result)) {
|
|
59
|
+
// Reset regex state for actual replacement
|
|
60
|
+
listPattern.lastIndex = 0;
|
|
61
|
+
result = result.replace(listPattern, (match, listItem, content) => {
|
|
62
|
+
if (!content) {
|
|
63
|
+
return match;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Format content with proper indentation
|
|
67
|
+
const cleanContent = content.substring(2); // Remove leading \n\n
|
|
68
|
+
const lines = cleanContent.split("\n");
|
|
69
|
+
const indentedContent = lines.map(line => line.trim() ? `${Constants.MARKDOWN_LIST_INDENTATION}${line}` : "").join("\n");
|
|
70
|
+
const lineBreak = disableNewLineMarkdownSupport ? "\n" : "\n\n";
|
|
71
|
+
return `${listItem}${lineBreak}${indentedContent}`;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
78
|
+
md.render = function (text, env) {
|
|
79
|
+
const processedText = preprocessText(text);
|
|
80
|
+
return originalRender(processedText, env);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
84
|
+
md.renderInline = function (text, env) {
|
|
85
|
+
const processedText = preprocessText(text);
|
|
86
|
+
return originalRenderInline(processedText, env);
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
|
|
37
90
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
91
|
markdown.use(MarkdownItForInline, "url_new_win", "link_open", function (tokens, idx, env) {
|
|
39
92
|
const targetAttrIndex = tokens[idx].attrIndex(Constants.Target);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Constants } from "../../../common/Constants";
|
|
2
|
+
import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
|
|
3
|
+
import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
|
|
4
|
+
import { getCustomEventValue, isValidCustomEvent } from "../../../common/utils";
|
|
5
|
+
export const customEventCallback = facadeChatSDK => event => {
|
|
6
|
+
if (!(Constants.payload in event)) return;
|
|
7
|
+
if (isValidCustomEvent(event.payload)) {
|
|
8
|
+
const customEventPayload = event.payload;
|
|
9
|
+
try {
|
|
10
|
+
const customEventValueStr = getCustomEventValue(customEventPayload);
|
|
11
|
+
const customEventName = customEventPayload.customEventName;
|
|
12
|
+
const messageMeta = {
|
|
13
|
+
customEvent: Constants.true,
|
|
14
|
+
customEventName: customEventName,
|
|
15
|
+
customEventValue: customEventValueStr
|
|
16
|
+
};
|
|
17
|
+
const messagePayload = {
|
|
18
|
+
content: "",
|
|
19
|
+
tags: [Constants.Hidden],
|
|
20
|
+
metadata: messageMeta,
|
|
21
|
+
timestamp: new Date()
|
|
22
|
+
};
|
|
23
|
+
facadeChatSDK.sendMessage(messagePayload);
|
|
24
|
+
TelemetryHelper.logActionEventToAllTelemetry(LogLevel.DEBUG, {
|
|
25
|
+
Event: TelemetryEvent.CustomEventAction,
|
|
26
|
+
Description: "Sent customEvent.",
|
|
27
|
+
CustomProperties: {
|
|
28
|
+
customEventName,
|
|
29
|
+
lengthCustomEventValue: customEventValueStr.length
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
} catch (error) {
|
|
33
|
+
TelemetryHelper.logActionEventToAllTelemetry(LogLevel.ERROR, {
|
|
34
|
+
Event: TelemetryEvent.CustomEventAction,
|
|
35
|
+
Description: "Failed to process CustomEvent.",
|
|
36
|
+
ExceptionDetails: {
|
|
37
|
+
error
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
export const subscribeToSendCustomEvent = (broadcastService, facadeChatSDK, customEventCallback) => {
|
|
44
|
+
broadcastService.getMessageByEventName(Constants.sendCustomEvent).subscribe(customEventCallback(facadeChatSDK));
|
|
45
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BroadcastEvent, LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
|
|
2
|
-
import { ConfirmationState, Constants, ConversationEndEntity, ParticipantType, PrepareEndChatDescriptionConstants } from "../../../common/Constants";
|
|
2
|
+
import { ConfirmationState, Constants, ConversationEndEntity, LiveWorkItemState, ParticipantType, PrepareEndChatDescriptionConstants } from "../../../common/Constants";
|
|
3
3
|
import { getConversationDetailsCall, getWidgetEndChatEventName } from "../../../common/utils";
|
|
4
4
|
import { getPostChatContext, initiatePostChat } from "./renderSurveyHelpers";
|
|
5
5
|
import { BroadcastService } from "@microsoft/omnichannel-chat-components";
|
|
@@ -35,10 +35,11 @@ const prepareEndChat = async (props, facadeChatSDK, state, dispatch, setAdapter,
|
|
|
35
35
|
Description: PrepareEndChatDescriptionConstants.ConversationEndedByCustomerWithoutPostChat
|
|
36
36
|
});
|
|
37
37
|
await endChat(props, facadeChatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, false, true);
|
|
38
|
+
return;
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
// Use Case: If ended by Agent, stay chat in InActive state
|
|
41
|
-
|
|
42
|
+
const isConversationalSurveyEnabled = state.appStates.isConversationalSurveyEnabled;
|
|
42
43
|
if (isConversationalSurveyEnabled && ((state === null || state === void 0 ? void 0 : (_state$appStates2 = state.appStates) === null || _state$appStates2 === void 0 ? void 0 : _state$appStates2.conversationEndedBy) === ConversationEndEntity.Agent || (state === null || state === void 0 ? void 0 : (_state$appStates3 = state.appStates) === null || _state$appStates3 === void 0 ? void 0 : _state$appStates3.conversationEndedBy) === ConversationEndEntity.Bot)) {
|
|
43
44
|
dispatch({
|
|
44
45
|
type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
|
|
@@ -146,8 +147,23 @@ const endChat = async (props, facadeChatSDK, state, dispatch, setAdapter, setWeb
|
|
|
146
147
|
type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
|
|
147
148
|
payload: null
|
|
148
149
|
});
|
|
150
|
+
let isSessionEnded = inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta = inMemoryState.appStates) === null || _inMemoryState$appSta === void 0 ? void 0 : _inMemoryState$appSta.chatDisconnectEventReceived;
|
|
151
|
+
if (!isSessionEnded) {
|
|
152
|
+
// double check by fetching the latest conversation details
|
|
153
|
+
const conversationDetails = await getConversationDetailsCall(facadeChatSDK);
|
|
154
|
+
if ((conversationDetails === null || conversationDetails === void 0 ? void 0 : conversationDetails.state) === LiveWorkItemState.WrapUp || (conversationDetails === null || conversationDetails === void 0 ? void 0 : conversationDetails.state) === LiveWorkItemState.Closed) {
|
|
155
|
+
TelemetryHelper.logActionEvent(LogLevel.INFO, {
|
|
156
|
+
Event: TelemetryEvent.ChatDisconnectThreadEventReceived,
|
|
157
|
+
Description: "Checking conversation details upon endChat. Chat disconnected.",
|
|
158
|
+
CustomProperties: {
|
|
159
|
+
conversationDetails
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
isSessionEnded = true;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
149
165
|
const endChatOptionalParameters = {
|
|
150
|
-
isSessionEnded
|
|
166
|
+
isSessionEnded
|
|
151
167
|
};
|
|
152
168
|
try {
|
|
153
169
|
TelemetryHelper.logSDKEvent(LogLevel.INFO, {
|
|
@@ -210,7 +226,7 @@ const endChat = async (props, facadeChatSDK, state, dispatch, setAdapter, setWeb
|
|
|
210
226
|
payload: undefined
|
|
211
227
|
});
|
|
212
228
|
// Always allow to close the chat for embedded mode irrespective of end chat errors
|
|
213
|
-
closeChatWidget(dispatch);
|
|
229
|
+
closeChatWidget(dispatch, setWebChatStyles, props);
|
|
214
230
|
facadeChatSDK.destroy();
|
|
215
231
|
}
|
|
216
232
|
}
|
|
@@ -295,6 +311,10 @@ export const closeChatStateCleanUp = dispatch => {
|
|
|
295
311
|
proactiveChatInNewWindow: false
|
|
296
312
|
}
|
|
297
313
|
});
|
|
314
|
+
dispatch({
|
|
315
|
+
type: LiveChatWidgetActionType.SET_CITATIONS,
|
|
316
|
+
payload: {}
|
|
317
|
+
});
|
|
298
318
|
|
|
299
319
|
// Clear live chat context only if chat widget is fully closed to support transcript calls after sessionclose is called
|
|
300
320
|
dispatch({
|
|
@@ -338,12 +358,22 @@ export const endVoiceVideoCallIfOngoing = async (facadeChatSDK, dispatch) => {
|
|
|
338
358
|
}, callId);
|
|
339
359
|
}
|
|
340
360
|
};
|
|
341
|
-
|
|
361
|
+
|
|
362
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
363
|
+
const closeChatWidget = (dispatch, setWebChatStyles, props) => {
|
|
364
|
+
var _props$webChatContain2, _props$webChatContain3;
|
|
342
365
|
// Embedded chat
|
|
343
366
|
dispatch({
|
|
344
367
|
type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
|
|
345
368
|
payload: ConversationState.Closed
|
|
346
369
|
});
|
|
370
|
+
|
|
371
|
+
// if customer is setting the hideSendbox, we should not alter its value
|
|
372
|
+
if ((props === null || props === void 0 ? void 0 : (_props$webChatContain2 = props.webChatContainerProps) === null || _props$webChatContain2 === void 0 ? void 0 : (_props$webChatContain3 = _props$webChatContain2.webChatStyles) === null || _props$webChatContain3 === void 0 ? void 0 : _props$webChatContain3.hideSendBox) === true) return;
|
|
373
|
+
setWebChatStyles(styles => ({
|
|
374
|
+
...styles,
|
|
375
|
+
hideSendBox: false
|
|
376
|
+
}));
|
|
347
377
|
};
|
|
348
378
|
|
|
349
379
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -3,14 +3,15 @@ import { DesignerChatSDK } from "../../webchatcontainerstateful/common/DesignerC
|
|
|
3
3
|
import { MockChatSDK } from "../../webchatcontainerstateful/common/mockchatsdk";
|
|
4
4
|
|
|
5
5
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
|
-
export const getMockChatSDKIfApplicable = (chatSDK,
|
|
7
|
-
if (type) {
|
|
8
|
-
switch (type.toLowerCase()) {
|
|
6
|
+
export const getMockChatSDKIfApplicable = (chatSDK, mockProps) => {
|
|
7
|
+
if (mockProps !== null && mockProps !== void 0 && mockProps.type) {
|
|
8
|
+
switch (mockProps.type.toLowerCase()) {
|
|
9
9
|
case "demo":
|
|
10
10
|
chatSDK = new DemoChatSDK();
|
|
11
11
|
break;
|
|
12
12
|
case "designer":
|
|
13
13
|
chatSDK = new DesignerChatSDK();
|
|
14
|
+
chatSDK.mockMessages = mockProps === null || mockProps === void 0 ? void 0 : mockProps.mockMessages;
|
|
14
15
|
break;
|
|
15
16
|
default:
|
|
16
17
|
chatSDK = new MockChatSDK();
|