@microsoft/omnichannel-chat-widget 1.8.3-main.38c88a7 → 1.8.3-main.4743fdc
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/Constants.js +2 -0
- package/lib/cjs/common/telemetry/TelemetryConstants.js +4 -0
- package/lib/cjs/common/telemetry/TelemetryHelper.js +7 -5
- package/lib/cjs/components/citationpanestateful/CitationDim.js +29 -0
- package/lib/cjs/components/citationpanestateful/CitationPaneStateful.js +158 -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/common/endChat.js +17 -3
- package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +12 -9
- package/lib/cjs/components/livechatwidget/common/startChat.js +4 -3
- package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +12 -6
- package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +86 -4
- package/lib/cjs/components/webchatcontainerstateful/interfaces/ICitation.js +1 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.js +139 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +54 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +2 -2
- 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/util.js +12 -2
- package/lib/cjs/plugins/newMessageEventHandler.js +2 -2
- package/lib/esm/common/Constants.js +2 -0
- package/lib/esm/common/telemetry/TelemetryConstants.js +4 -0
- package/lib/esm/common/telemetry/TelemetryHelper.js +7 -5
- package/lib/esm/components/citationpanestateful/CitationDim.js +20 -0
- package/lib/esm/components/citationpanestateful/CitationPaneStateful.js +147 -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/common/endChat.js +17 -3
- package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +13 -10
- package/lib/esm/components/livechatwidget/common/startChat.js +4 -3
- package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +12 -6
- package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +86 -5
- package/lib/esm/components/webchatcontainerstateful/interfaces/ICitation.js +1 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.js +133 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +46 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +2 -2
- 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/util.js +9 -0
- package/lib/esm/plugins/newMessageEventHandler.js +3 -3
- package/lib/types/common/Constants.d.ts +2 -0
- package/lib/types/common/telemetry/TelemetryConstants.d.ts +4 -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 +10 -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/interfaces/ILiveChatWidgetProps.d.ts +3 -1
- package/lib/types/components/webchatcontainerstateful/interfaces/ICitation.d.ts +12 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.d.ts +4 -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 +2 -2
- package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +1 -0
- package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +46 -45
- package/lib/types/firstresponselatency/util.d.ts +1 -0
- package/package.json +4 -3
- /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
|
@@ -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,147 @@
|
|
|
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
|
+
useEffect(() => {
|
|
14
|
+
uiTimer = createTimer();
|
|
15
|
+
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
16
|
+
Event: TelemetryEvent.UXCitationPaneStart
|
|
17
|
+
});
|
|
18
|
+
}, []);
|
|
19
|
+
const initialTabIndexMap = new Map();
|
|
20
|
+
let elements = [];
|
|
21
|
+
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
23
|
+
const [state, dispatch] = useChatContextStore();
|
|
24
|
+
const controlId = HtmlAttributeNames.ocwCitationPaneClassName;
|
|
25
|
+
|
|
26
|
+
// Pane style computed to match the webchat widget container bounds so the pane
|
|
27
|
+
// stays within the widget and scrolls only vertically. We also track an
|
|
28
|
+
// "isReady" flag so we don't render the pane contents until the style is
|
|
29
|
+
// computed — this prevents a transient render that can appear as a flicker.
|
|
30
|
+
const [paneStyle, setPaneStyle] = useState(null);
|
|
31
|
+
const [isReady, setIsReady] = useState(false);
|
|
32
|
+
|
|
33
|
+
// Move focus to the container
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
preventFocusToMoveOutOfElement(controlId);
|
|
36
|
+
const focusableElements = findAllFocusableElement(`#${controlId}`);
|
|
37
|
+
requestAnimationFrame(() => {
|
|
38
|
+
if (focusableElements && focusableElements.length > 0 && focusableElements[0]) {
|
|
39
|
+
focusableElements[0].focus({
|
|
40
|
+
preventScroll: true
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
elements = findParentFocusableElementsWithoutChildContainer(controlId);
|
|
45
|
+
setTabIndices(elements, initialTabIndexMap, false);
|
|
46
|
+
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
47
|
+
Event: TelemetryEvent.CitationPaneLoaded
|
|
48
|
+
});
|
|
49
|
+
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
50
|
+
Event: TelemetryEvent.UXCitationPaneCompleted,
|
|
51
|
+
ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
|
|
52
|
+
});
|
|
53
|
+
}, []);
|
|
54
|
+
|
|
55
|
+
// Compute the widget bounds and set pane style accordingly (95% of widget size
|
|
56
|
+
// and centered inside the widget). If the widget container can't be found,
|
|
57
|
+
// fall back to the default pane styles from defaultCitationPaneProps.
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
const compute = () => {
|
|
60
|
+
try {
|
|
61
|
+
const container = document.querySelector(".webchat__stacked-layout_container");
|
|
62
|
+
if (container) {
|
|
63
|
+
const rect = container.getBoundingClientRect();
|
|
64
|
+
const widthPx = Math.round(rect.width * 0.95);
|
|
65
|
+
const heightPx = Math.round(rect.height * 0.95);
|
|
66
|
+
const leftPx = Math.round(rect.left + (rect.width - widthPx) / 2);
|
|
67
|
+
const topPx = Math.round(rect.top + (rect.height - heightPx) / 2);
|
|
68
|
+
// Clone defaults and remove transform so explicit left/top pixel
|
|
69
|
+
// coordinates are respected and the pane stays within the
|
|
70
|
+
// widget bounds.
|
|
71
|
+
const base = Object.assign({}, defaultCitationPaneStyles.pane);
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
73
|
+
if (base && base.transform) {
|
|
74
|
+
// remove centering transform when we compute exact pixel coords
|
|
75
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
76
|
+
delete base.transform;
|
|
77
|
+
}
|
|
78
|
+
setPaneStyle(Object.assign({}, base, {
|
|
79
|
+
left: `${leftPx}px`,
|
|
80
|
+
top: `${topPx}px`,
|
|
81
|
+
width: `${widthPx}px`,
|
|
82
|
+
height: `${heightPx}px`
|
|
83
|
+
}));
|
|
84
|
+
// Make the pane visible after the next paint to avoid layout
|
|
85
|
+
// flashes on initial mount.
|
|
86
|
+
requestAnimationFrame(() => setIsReady(true));
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
} catch (e) {
|
|
90
|
+
// ignore
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// fallback
|
|
94
|
+
setPaneStyle(defaultCitationPaneStyles.pane);
|
|
95
|
+
requestAnimationFrame(() => setIsReady(true));
|
|
96
|
+
};
|
|
97
|
+
compute();
|
|
98
|
+
window.addEventListener("resize", compute);
|
|
99
|
+
return () => window.removeEventListener("resize", compute);
|
|
100
|
+
}, []);
|
|
101
|
+
const handleClose = () => {
|
|
102
|
+
if (props.onClose) props.onClose();
|
|
103
|
+
dispatch({
|
|
104
|
+
type: LiveChatWidgetActionType.SET_PREVIOUS_FOCUSED_ELEMENT_ID,
|
|
105
|
+
payload: null
|
|
106
|
+
});
|
|
107
|
+
setTabIndices(elements, initialTabIndexMap, true);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// Merge a safe style object for the container and cast to CSSProperties to satisfy TS
|
|
111
|
+
const mergedStyle = Object.assign({
|
|
112
|
+
position: "relative"
|
|
113
|
+
}, paneStyle ?? {
|
|
114
|
+
position: "fixed"
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// If paneStyle hasn't been computed yet, render the DimLayer so clicks
|
|
118
|
+
// still close overlays but hide the pane itself to avoid flashes.
|
|
119
|
+
const hiddenStyle = {
|
|
120
|
+
visibility: isReady ? "visible" : "hidden",
|
|
121
|
+
pointerEvents: isReady ? "auto" : "none"
|
|
122
|
+
};
|
|
123
|
+
const controlProps = {
|
|
124
|
+
id: controlId,
|
|
125
|
+
dir: state.domainStates.globalDir,
|
|
126
|
+
titleText: props.title,
|
|
127
|
+
contentHtml: props.contentHtml,
|
|
128
|
+
brightnessValueOnDim: "0.2",
|
|
129
|
+
onClose: handleClose,
|
|
130
|
+
...(props === null || props === void 0 ? void 0 : props.controlProps)
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(CitationDim, {
|
|
135
|
+
brightness: "0.2"
|
|
136
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
137
|
+
style: Object.assign({}, mergedStyle, hiddenStyle, {
|
|
138
|
+
display: "flex",
|
|
139
|
+
flexDirection: "column",
|
|
140
|
+
zIndex: 10001
|
|
141
|
+
})
|
|
142
|
+
}, /*#__PURE__*/React.createElement(CitationPane, {
|
|
143
|
+
controlProps: controlProps,
|
|
144
|
+
styleProps: props === null || props === void 0 ? void 0 : props.styleProps
|
|
145
|
+
})));
|
|
146
|
+
};
|
|
147
|
+
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 {};
|
|
@@ -39,7 +39,7 @@ const prepareEndChat = async (props, facadeChatSDK, state, dispatch, setAdapter,
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// Use Case: If ended by Agent, stay chat in InActive state
|
|
42
|
-
|
|
42
|
+
const isConversationalSurveyEnabled = state.appStates.isConversationalSurveyEnabled;
|
|
43
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)) {
|
|
44
44
|
dispatch({
|
|
45
45
|
type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
|
|
@@ -211,7 +211,7 @@ const endChat = async (props, facadeChatSDK, state, dispatch, setAdapter, setWeb
|
|
|
211
211
|
payload: undefined
|
|
212
212
|
});
|
|
213
213
|
// Always allow to close the chat for embedded mode irrespective of end chat errors
|
|
214
|
-
closeChatWidget(dispatch);
|
|
214
|
+
closeChatWidget(dispatch, setWebChatStyles, props);
|
|
215
215
|
facadeChatSDK.destroy();
|
|
216
216
|
}
|
|
217
217
|
}
|
|
@@ -296,6 +296,10 @@ export const closeChatStateCleanUp = dispatch => {
|
|
|
296
296
|
proactiveChatInNewWindow: false
|
|
297
297
|
}
|
|
298
298
|
});
|
|
299
|
+
dispatch({
|
|
300
|
+
type: LiveChatWidgetActionType.SET_CITATIONS,
|
|
301
|
+
payload: {}
|
|
302
|
+
});
|
|
299
303
|
|
|
300
304
|
// Clear live chat context only if chat widget is fully closed to support transcript calls after sessionclose is called
|
|
301
305
|
dispatch({
|
|
@@ -339,12 +343,22 @@ export const endVoiceVideoCallIfOngoing = async (facadeChatSDK, dispatch) => {
|
|
|
339
343
|
}, callId);
|
|
340
344
|
}
|
|
341
345
|
};
|
|
342
|
-
|
|
346
|
+
|
|
347
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
348
|
+
const closeChatWidget = (dispatch, setWebChatStyles, props) => {
|
|
349
|
+
var _props$webChatContain2, _props$webChatContain3;
|
|
343
350
|
// Embedded chat
|
|
344
351
|
dispatch({
|
|
345
352
|
type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
|
|
346
353
|
payload: ConversationState.Closed
|
|
347
354
|
});
|
|
355
|
+
|
|
356
|
+
// if customer is setting the hideSendbox, we should not alter its value
|
|
357
|
+
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;
|
|
358
|
+
setWebChatStyles(styles => ({
|
|
359
|
+
...styles,
|
|
360
|
+
hideSendBox: false
|
|
361
|
+
}));
|
|
348
362
|
};
|
|
349
363
|
|
|
350
364
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { ConversationEndEntity, ParticipantType } from "../../../common/Constants";
|
|
2
2
|
import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
|
|
3
3
|
import { changeLanguageCodeFormatForWebChat, getConversationDetailsCall } from "../../../common/utils";
|
|
4
|
+
import { BroadcastService } from "@microsoft/omnichannel-chat-components";
|
|
5
|
+
import { Constants } from "../../../common/Constants";
|
|
6
|
+
import { ConversationState } from "../../../contexts/common/ConversationState";
|
|
4
7
|
import DOMPurify from "dompurify";
|
|
5
8
|
import HyperlinkTextOverrideRenderer from "../../webchatcontainerstateful/webchatcontroller/markdownrenderers/HyperlinkTextOverrideRenderer";
|
|
6
9
|
import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
|
|
@@ -12,36 +15,35 @@ import { createActivityMiddleware } from "../../webchatcontainerstateful/webchat
|
|
|
12
15
|
import { createAttachmentMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachmentMiddleware";
|
|
13
16
|
import createAttachmentUploadValidatorMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentUploadValidatorMiddleware";
|
|
14
17
|
import { createAvatarMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/avatarMiddleware";
|
|
18
|
+
import createCallActionMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware";
|
|
15
19
|
import { createCardActionMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware";
|
|
20
|
+
import { createCitationsMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware";
|
|
16
21
|
import createConversationEndMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware";
|
|
22
|
+
import createCustomEventMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware";
|
|
17
23
|
import createDataMaskingMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/dataMaskingMiddleware";
|
|
18
24
|
import { createMarkdown } from "./createMarkdown";
|
|
19
25
|
import createMaxMessageSizeValidator from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/maxMessageSizeValidator";
|
|
20
26
|
import { createMessageSequenceIdOverrideMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware";
|
|
21
27
|
import { createMessageTimeStampMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageTimestampMiddleware";
|
|
28
|
+
import { createQueueOverflowMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware";
|
|
22
29
|
import { createStore } from "botframework-webchat";
|
|
23
30
|
import { createToastMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/toastMiddleware";
|
|
24
31
|
import { createWebChatTelemetry } from "../../webchatcontainerstateful/webchatcontroller/webchattelemetry/WebChatLogger";
|
|
25
32
|
import { defaultAttachmentProps } from "../../webchatcontainerstateful/common/defaultProps/defaultAttachmentProps";
|
|
26
33
|
import { defaultMiddlewareLocalizedTexts } from "../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts";
|
|
27
34
|
import { defaultWebChatContainerStatefulProps } from "../../webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps";
|
|
35
|
+
import { executeReducer } from "../../../contexts/createReducer";
|
|
28
36
|
import { getLocaleStringFromId } from "@microsoft/omnichannel-chat-sdk";
|
|
29
37
|
import gifUploadMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/gifUploadMiddleware";
|
|
30
38
|
import htmlPlayerMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlPlayerMiddleware";
|
|
31
39
|
import htmlTextMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware";
|
|
32
40
|
import preProcessingMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware";
|
|
33
41
|
import sanitizationMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware";
|
|
34
|
-
import {
|
|
35
|
-
import createCallActionMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware";
|
|
36
|
-
import createCustomEventMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware";
|
|
37
|
-
import { ConversationState } from "../../../contexts/common/ConversationState";
|
|
38
|
-
import { executeReducer } from "../../../contexts/createReducer";
|
|
39
|
-
import { createQueueOverflowMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware";
|
|
40
|
-
import { BroadcastService } from "@microsoft/omnichannel-chat-components";
|
|
42
|
+
import { localizedStringsBotInitialsMiddleware, getOverriddenLocalizedStrings } from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware";
|
|
41
43
|
|
|
42
44
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
45
|
export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endChat) => {
|
|
44
|
-
var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _props$webChatContain5, _props$webChatContain6, _state$domainStates$l4, _state$domainStates$l5, _props$webChatContain11, _props$webChatContain12, _state$domainStates$r, _state$domainStates$r2, _props$webChatContain13, _props$webChatContain14, _state$domainStates$r3, _state$domainStates$r4, _props$webChatContain15, _props$webChatContain16, _defaultWebChatContai, _props$webChatContain17, _props$webChatContain18, _props$webChatContain19, _props$webChatContain20, _state$domainStates$r5, _state$domainStates$r6, _props$webChatContain21, _props$webChatContain22, _defaultWebChatContai2, _props$webChatContain23, _props$webChatContain24, _defaultWebChatContai3, _props$webChatContain25, _props$webChatContain26;
|
|
46
|
+
var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _props$webChatContain5, _props$webChatContain6, _state$domainStates$l4, _state$domainStates$l5, _props$webChatContain11, _props$webChatContain12, _state$domainStates$r, _state$domainStates$r2, _props$webChatContain13, _props$webChatContain14, _state$domainStates$r3, _state$domainStates$r4, _props$webChatContain15, _props$webChatContain16, _defaultWebChatContai, _props$webChatContain17, _props$webChatContain18, _props$webChatContain19, _props$webChatContain20, _state$domainStates$r5, _state$domainStates$r6, _props$webChatContain21, _props$webChatContain22, _defaultWebChatContai2, _props$webChatContain23, _props$webChatContain24, _defaultWebChatContai3, _props$webChatContain25, _props$webChatContain26, _props$webChatContain27, _props$webChatContain28;
|
|
45
47
|
// Add a hook to make all links open a new window
|
|
46
48
|
postDomPurifyActivities();
|
|
47
49
|
const localizedTexts = {
|
|
@@ -116,7 +118,7 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
|
|
|
116
118
|
};
|
|
117
119
|
webChatStore = createStore({},
|
|
118
120
|
//initial state
|
|
119
|
-
preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), createCustomEventMiddleware(BroadcastService), createQueueOverflowMiddleware(state, dispatch), channelDataMiddleware(addConversationalSurveyTagsCallback), createConversationEndMiddleware(conversationEndCallback, startConversationalSurveyCallback, endConversationalSurveyCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, createMessageSequenceIdOverrideMiddleware, gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware(honorsTargetInHTMLLinks), createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware, createCallActionMiddleware(),
|
|
121
|
+
preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), createCustomEventMiddleware(BroadcastService), createQueueOverflowMiddleware(state, dispatch), channelDataMiddleware(addConversationalSurveyTagsCallback), createConversationEndMiddleware(conversationEndCallback, startConversationalSurveyCallback, endConversationalSurveyCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, createMessageSequenceIdOverrideMiddleware, createCitationsMiddleware(state, dispatch), gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware(honorsTargetInHTMLLinks), createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware, createCallActionMiddleware(), localizedStringsBotInitialsMiddleware(),
|
|
120
122
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
121
123
|
...(((_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.storeMiddlewares) ?? []));
|
|
122
124
|
WebChatStoreLoader.store = webChatStore;
|
|
@@ -170,7 +172,8 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
|
|
|
170
172
|
onTelemetry: createWebChatTelemetry(),
|
|
171
173
|
cardActionMiddleware: createCardActionMiddleware(((_props$webChatContain25 = props.webChatContainerProps) === null || _props$webChatContain25 === void 0 ? void 0 : _props$webChatContain25.botMagicCode) || undefined),
|
|
172
174
|
sendTypingIndicator: true,
|
|
173
|
-
|
|
175
|
+
overrideLocalizedStrings: getOverriddenLocalizedStrings((_props$webChatContain26 = props.webChatContainerProps) === null || _props$webChatContain26 === void 0 ? void 0 : (_props$webChatContain27 = _props$webChatContain26.webChatProps) === null || _props$webChatContain27 === void 0 ? void 0 : _props$webChatContain27.overrideLocalizedStrings),
|
|
176
|
+
...((_props$webChatContain28 = props.webChatContainerProps) === null || _props$webChatContain28 === void 0 ? void 0 : _props$webChatContain28.webChatProps)
|
|
174
177
|
};
|
|
175
178
|
return webChatProps;
|
|
176
179
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BroadcastEvent, LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
|
|
2
2
|
import { Constants, LiveWorkItemState, WidgetLoadTelemetryMessage } from "../../../common/Constants";
|
|
3
|
+
import { TelemetryManager, TelemetryTimers } from "../../../common/telemetry/TelemetryManager";
|
|
3
4
|
import { checkContactIdError, createTimer, getConversationDetailsCall, getStateFromCache, getWidgetCacheIdfromProps, isNullOrEmptyString, isNullOrUndefined, isUndefinedOrEmpty } from "../../../common/utils";
|
|
4
5
|
import { handleChatReconnect, isPersistentEnabled, isReconnectEnabled } from "./reconnectChatHelper";
|
|
5
6
|
import { handleStartChatError, logWidgetLoadComplete } from "./startChatErrorHandler";
|
|
@@ -8,7 +9,6 @@ import { BroadcastService } from "@microsoft/omnichannel-chat-components";
|
|
|
8
9
|
import { ConversationState } from "../../../contexts/common/ConversationState";
|
|
9
10
|
import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
|
|
10
11
|
import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
|
|
11
|
-
import { TelemetryTimers } from "../../../common/telemetry/TelemetryManager";
|
|
12
12
|
import { chatSDKStateCleanUp } from "./endChat";
|
|
13
13
|
import { createAdapter } from "./createAdapter";
|
|
14
14
|
import { createOnNewAdapterActivityHandler } from "../../../plugins/newMessageEventHandler";
|
|
@@ -131,7 +131,7 @@ const setPreChatAndInitiateChat = async (facadeChatSDK, dispatch, setAdapter, is
|
|
|
131
131
|
* This is because a new change to control OOH as closed event when a widget is coming from chat.
|
|
132
132
|
*/
|
|
133
133
|
if ((state === null || state === void 0 ? void 0 : state.appStates.isMinimized) === undefined || (state === null || state === void 0 ? void 0 : (_state$appStates2 = state.appStates) === null || _state$appStates2 === void 0 ? void 0 : _state$appStates2.isMinimized) === true) {
|
|
134
|
-
var _state$domainStates5, _state$domainStates5$, _state$domainStates6, _state$domainStates6
|
|
134
|
+
var _state$domainStates5, _state$domainStates5$, _state$domainStates6, _state$domainStates6$, _TelemetryManager$Int;
|
|
135
135
|
dispatch({
|
|
136
136
|
type: LiveChatWidgetActionType.SET_MINIMIZED,
|
|
137
137
|
payload: false
|
|
@@ -141,7 +141,8 @@ const setPreChatAndInitiateChat = async (facadeChatSDK, dispatch, setAdapter, is
|
|
|
141
141
|
eventName: BroadcastEvent.MaximizeChat,
|
|
142
142
|
payload: {
|
|
143
143
|
height: state === null || state === void 0 ? void 0 : (_state$domainStates5 = state.domainStates) === null || _state$domainStates5 === void 0 ? void 0 : (_state$domainStates5$ = _state$domainStates5.widgetSize) === null || _state$domainStates5$ === void 0 ? void 0 : _state$domainStates5$.height,
|
|
144
|
-
width: state === null || state === void 0 ? void 0 : (_state$domainStates6 = state.domainStates) === null || _state$domainStates6 === void 0 ? void 0 : (_state$domainStates6$ = _state$domainStates6.widgetSize) === null || _state$domainStates6$ === void 0 ? void 0 : _state$domainStates6$.width
|
|
144
|
+
width: state === null || state === void 0 ? void 0 : (_state$domainStates6 = state.domainStates) === null || _state$domainStates6 === void 0 ? void 0 : (_state$domainStates6$ = _state$domainStates6.widgetSize) === null || _state$domainStates6$ === void 0 ? void 0 : _state$domainStates6$.width,
|
|
145
|
+
runtimeId: TelemetryManager === null || TelemetryManager === void 0 ? void 0 : (_TelemetryManager$Int = TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int === void 0 ? void 0 : _TelemetryManager$Int.lcwRuntimeId
|
|
145
146
|
}
|
|
146
147
|
});
|
|
147
148
|
}
|
|
@@ -9,6 +9,7 @@ import { TelemetryManager, TelemetryTimers } from "../../../common/telemetry/Tel
|
|
|
9
9
|
import { chatSDKStateCleanUp, endChat, endChatStateCleanUp, prepareEndChat } from "../common/endChat";
|
|
10
10
|
import { checkIfConversationStillValid, initStartChat, prepareStartChat, setPreChatAndInitiateChat } from "../common/startChat";
|
|
11
11
|
import { createTimer, getBroadcastChannelName, getConversationDetailsCall, getLocaleDirection, getStateFromCache, getWidgetCacheIdfromProps, getWidgetEndChatEventName, isNullOrEmptyString, isNullOrUndefined, isThisSessionPopout, isUndefinedOrEmpty, setOcUserAgent } from "../../../common/utils";
|
|
12
|
+
import { customEventCallback, subscribeToSendCustomEvent } from "../common/customEventHandler";
|
|
12
13
|
import { defaultClientDataStoreProvider, isCookieAllowed } from "../../../common/storage/default/defaultClientDataStoreProvider";
|
|
13
14
|
import { handleChatReconnect, isPersistentEnabled, isReconnectEnabled } from "../common/reconnectChatHelper";
|
|
14
15
|
import { shouldShowCallingContainer, shouldShowChatButton, shouldShowConfirmationPane, shouldShowEmailTranscriptPane, shouldShowHeader, shouldShowLoadingPane, shouldShowOutOfOfficeHoursPane, shouldShowPostChatLoadingPane, shouldShowPostChatSurveyPane, shouldShowPreChatSurveyPane, shouldShowProactiveChatPane, shouldShowReconnectChatPane, shouldShowStartChatErrorPane, shouldShowWebChatContainer } from "../../../controller/componentController";
|
|
@@ -53,7 +54,6 @@ import { startProactiveChat } from "../common/startProactiveChat";
|
|
|
53
54
|
import useChatAdapterStore from "../../../hooks/useChatAdapterStore";
|
|
54
55
|
import useChatContextStore from "../../../hooks/useChatContextStore";
|
|
55
56
|
import useFacadeSDKStore from "../../../hooks/useFacadeChatSDKStore";
|
|
56
|
-
import { customEventCallback, subscribeToSendCustomEvent } from "../common/customEventHandler";
|
|
57
57
|
let uiTimer;
|
|
58
58
|
export const LiveChatWidgetStateful = props => {
|
|
59
59
|
var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _props$webChatContain5, _props$webChatContain6, _props$webChatContain7, _props$webChatContain8, _props$webChatContain9, _props$styleProps, _props$webChatContain10, _props$webChatContain11, _props$controlProps, _props$controlProps3, _state$appStates7, _props$webChatContain15, _state$appStates14, _props$webChatContain17, _props$webChatContain18, _props$controlProps12, _props$draggableChatW, _props$draggableChatW2, _props$draggableChatW3, _props$draggableChatW4, _props$draggableChatW5, _livechatProps$webCha, _livechatProps$styleP, _livechatProps$contro, _livechatProps$contro2, _livechatProps$compon, _livechatProps$contro3, _livechatProps$compon2, _livechatProps$contro4, _livechatProps$compon3, _livechatProps$contro5, _livechatProps$compon4, _livechatProps$contro6, _livechatProps$compon5, _livechatProps$contro7, _livechatProps$compon6, _livechatProps$contro8, _livechatProps$compon7, _livechatProps$contro9, _livechatProps$compon8, _livechatProps$contro10, _livechatProps$contro11, _livechatProps$compon9, _livechatProps$contro12, _livechatProps$compon10, _livechatProps$contro13, _livechatProps$compon11, _livechatProps$compon12, _livechatProps$compon13;
|
|
@@ -719,11 +719,7 @@ export const LiveChatWidgetStateful = props => {
|
|
|
719
719
|
endChat(props, facadeChatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, false, true);
|
|
720
720
|
return;
|
|
721
721
|
}
|
|
722
|
-
const
|
|
723
|
-
type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
|
|
724
|
-
payload: null
|
|
725
|
-
});
|
|
726
|
-
let isConversationalSurveyEnabled = state.appStates.isConversationalSurveyEnabled;
|
|
722
|
+
const isConversationalSurveyEnabled = state.appStates.isConversationalSurveyEnabled;
|
|
727
723
|
|
|
728
724
|
// In conversational survey, we need to check post chat survey logics before we set ConversationState to InActive
|
|
729
725
|
// Hence setting ConversationState to InActive will be done later in the post chat flows
|
|
@@ -896,11 +892,21 @@ export const LiveChatWidgetStateful = props => {
|
|
|
896
892
|
.webchat__basic-transcript__activity-markdown-body > :first-child {
|
|
897
893
|
margin-top: 0px;
|
|
898
894
|
}
|
|
895
|
+
|
|
899
896
|
.webchat__basic-transcript__activity-markdown-body img.webchat__render-markdown__external-link-icon {
|
|
900
897
|
background-image : url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIzIDMgMTggMTgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTcuMjUwMSA0LjUwMDE3SDEwLjc0OTVDMTEuMTYzNyA0LjUwMDE3IDExLjQ5OTUgNC44MzU5NiAxMS40OTk1IDUuMjUwMTdDMTEuNDk5NSA1LjYyOTg2IDExLjIxNzMgNS45NDM2NiAxMC44NTEzIDUuOTkzMzJMMTAuNzQ5NSA2LjAwMDE3SDcuMjQ5NzRDNi4wNzA3OSA1Ljk5OTYxIDUuMTAzNDkgNi45MDY1NiA1LjAwNzg2IDguMDYxMTJMNS4wMDAyOCA4LjIyMDAzTDUuMDAzMTIgMTYuNzUwN0M1LjAwMzQzIDE3Ljk0MTUgNS45Mjg4NSAxOC45MTYxIDcuMDk5NjYgMTguOTk0OUw3LjI1MzcxIDE5LjAwMDFMMTUuNzUxOCAxOC45ODg0QzE2Ljk0MTUgMTguOTg2OCAxNy45MTQ1IDE4LjA2MiAxNy45OTM1IDE2Ljg5MjNMMTcuOTk4NyAxNi43Mzg0VjEzLjIzMjFDMTcuOTk4NyAxMi44MTc5IDE4LjMzNDUgMTIuNDgyMSAxOC43NDg3IDEyLjQ4MjFDMTkuMTI4NCAxMi40ODIxIDE5LjQ0MjIgMTIuNzY0MyAxOS40OTE4IDEzLjEzMDNMMTkuNDk4NyAxMy4yMzIxVjE2LjczODRDMTkuNDk4NyAxOC43NDA3IDE3LjkyOTMgMjAuMzc2OSAxNS45NTI4IDIwLjQ4MjlMMTUuNzUzOCAyMC40ODg0TDcuMjU4MjcgMjAuNTAwMUw3LjA1NDk1IDIwLjQ5NDlDNS4xNDIzOSAyMC4zOTU0IDMuNjA4OTUgMTguODYyNyAzLjUwODM3IDE2Ljk1MDJMMy41MDMxMiAxNi43NTExTDMuNTAwODkgOC4yNTI3TDMuNTA1MjkgOC4wNTAyQzMuNjA1MzkgNi4xMzc0OSA1LjEzODY3IDQuNjA0NDkgNy4wNTA5NiA0LjUwNTI3TDcuMjUwMSA0LjUwMDE3SDEwLjc0OTVINy4yNTAxWk0xMy43NDgxIDMuMDAxNDZMMjAuMzAxOCAzLjAwMTk3TDIwLjQwMTQgMy4wMTU3NUwyMC41MDIyIDMuMDQzOTNMMjAuNTU5IDMuMDY4MDNDMjAuNjEyMiAzLjA5MTIyIDIwLjY2MzQgMy4xMjE2MyAyMC43MTExIDMuMTU4ODVMMjAuNzgwNCAzLjIyMTU2TDIwLjg2NDEgMy4zMjAxNEwyMC45MTgzIDMuNDEwMjVMMjAuOTU3IDMuNTAwNTdMMjAuOTc2MiAzLjU2NDc2TDIwLjk4OTggMy42Mjg2MkwyMC45OTkyIDMuNzIyODJMMjAuOTk5NyAxMC4yNTU0QzIwLjk5OTcgMTAuNjY5NiAyMC42NjM5IDExLjAwNTQgMjAuMjQ5NyAxMS4wMDU0QzE5Ljg3IDExLjAwNTQgMTkuNTU2MiAxMC43MjMyIDE5LjUwNjUgMTAuMzU3MUwxOS40OTk3IDEwLjI1NTRMMTkuNDk4OSA1LjU2MTQ3TDEyLjI3OTcgMTIuNzg0N0MxMi4wMTM0IDEzLjA1MSAxMS41OTY4IDEzLjA3NTMgMTEuMzAzMSAxMi44NTc1TDExLjIxOSAxMi43ODQ5QzEwLjk1MjcgMTIuNTE4NyAxMC45Mjg0IDEyLjEwMjEgMTEuMTQ2MiAxMS44MDg0TDExLjIxODggMTEuNzI0M0wxOC40MzY5IDQuNTAxNDZIMTMuNzQ4MUMxMy4zNjg0IDQuNTAxNDYgMTMuMDU0NiA0LjIxOTMxIDEzLjAwNSAzLjg1MzI0TDEyLjk5ODEgMy43NTE0NkMxMi45OTgxIDMuMzcxNzcgMTMuMjgwMyAzLjA1Nzk3IDEzLjY0NjQgMy4wMDgzMUwxMy43NDgxIDMuMDAxNDZaIiBmaWxsPSIjMjEyMTIxIiAvPjwvc3ZnPg==) !important;
|
|
901
898
|
height: .75em;
|
|
902
899
|
margin-left: .25em;
|
|
903
900
|
}
|
|
901
|
+
|
|
902
|
+
.webchat__link-definitions__header-text {
|
|
903
|
+
color: ${bubbleBackground}
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
.webchat__link-definitions__header-chevron {
|
|
907
|
+
color: ${bubbleBackground}
|
|
908
|
+
}
|
|
909
|
+
|
|
904
910
|
${(sendBoxTextArea === null || sendBoxTextArea === void 0 ? void 0 : sendBoxTextArea.minHeight) && `
|
|
905
911
|
.webchat__auto-resize-textarea.webchat__send-box-text-box__text-area {
|
|
906
912
|
min-height: ${sendBoxTextArea === null || sendBoxTextArea === void 0 ? void 0 : sendBoxTextArea.minHeight} !important;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
|
|
3
1
|
import { Constants, HtmlAttributeNames, HtmlClassNames } from "../../common/Constants";
|
|
4
2
|
import { Stack } from "@fluentui/react";
|
|
5
3
|
import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
|
|
6
|
-
import React, { useEffect } from "react";
|
|
4
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
7
5
|
import { createTimer, getDeviceType, setFocusOnSendBox } from "../../common/utils";
|
|
8
6
|
import { BotMagicCodeStore } from "./webchatcontroller/BotMagicCodeStore";
|
|
7
|
+
import CitationPaneStateful from "../citationpanestateful/CitationPaneStateful";
|
|
9
8
|
import { Components } from "botframework-webchat";
|
|
10
9
|
import { LiveChatWidgetActionType } from "../../contexts/common/LiveChatWidgetActionType";
|
|
11
10
|
import { NotificationHandler } from "./webchatcontroller/notification/NotificationHandler";
|
|
@@ -23,6 +22,7 @@ import { defaultWebChatContainerStatefulProps } from "./common/defaultProps/defa
|
|
|
23
22
|
import { useChatContextStore } from "../..";
|
|
24
23
|
let uiTimer;
|
|
25
24
|
const broadcastChannelMessageEvent = "message";
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
26
|
const postActivity = activity => {
|
|
27
27
|
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
28
28
|
return {
|
|
@@ -55,6 +55,17 @@ export const WebChatContainerStateful = props => {
|
|
|
55
55
|
Event: TelemetryEvent.UXWebchatContainerCompleted
|
|
56
56
|
});
|
|
57
57
|
}, []);
|
|
58
|
+
|
|
59
|
+
// Citation pane state
|
|
60
|
+
const [citationPaneOpen, setCitationPaneOpen] = useState(false);
|
|
61
|
+
const [citationPaneText, setCitationPaneText] = useState("");
|
|
62
|
+
|
|
63
|
+
// Guard to prevent handling multiple rapid clicks which could cause
|
|
64
|
+
// the dim layer and pane to re-render out of sync and create a flicker.
|
|
65
|
+
const citationOpeningRef = useRef(false);
|
|
66
|
+
|
|
67
|
+
// ...existing code...
|
|
68
|
+
|
|
58
69
|
const {
|
|
59
70
|
BasicWebChat
|
|
60
71
|
} = Components;
|
|
@@ -63,6 +74,53 @@ export const WebChatContainerStateful = props => {
|
|
|
63
74
|
webChatContainerProps,
|
|
64
75
|
contextDataStore
|
|
65
76
|
} = props;
|
|
77
|
+
|
|
78
|
+
// Delegated click handler for citation anchors. Placed after state is
|
|
79
|
+
// available so we can prefer reading citations from app state and fall
|
|
80
|
+
// back to the legacy window map for backward-compatibility in tests.
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
const clickHandler = ev => {
|
|
83
|
+
try {
|
|
84
|
+
if (citationOpeningRef.current) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const target = ev.target;
|
|
88
|
+
// Only consider anchors whose href starts with the citation scheme
|
|
89
|
+
const anchor = target.closest && target.closest("a[href^=\"cite:\"]");
|
|
90
|
+
if (anchor) {
|
|
91
|
+
ev.preventDefault();
|
|
92
|
+
citationOpeningRef.current = true;
|
|
93
|
+
// Rely only on the href to identify the citation key
|
|
94
|
+
let text = "";
|
|
95
|
+
try {
|
|
96
|
+
var _state$domainStates;
|
|
97
|
+
const cid = anchor.getAttribute("href");
|
|
98
|
+
// Prefer state-based citations injected by middleware
|
|
99
|
+
if (state !== null && state !== void 0 && (_state$domainStates = state.domainStates) !== null && _state$domainStates !== void 0 && _state$domainStates.citations && cid) {
|
|
100
|
+
text = state.domainStates.citations[cid] ?? "";
|
|
101
|
+
}
|
|
102
|
+
// If state lookup failed, fall back to the anchor's title or innerText
|
|
103
|
+
if (!text) {
|
|
104
|
+
text = anchor.getAttribute("title") || anchor.innerText || "";
|
|
105
|
+
}
|
|
106
|
+
} catch (e) {
|
|
107
|
+
// ignore
|
|
108
|
+
}
|
|
109
|
+
setCitationPaneOpen(true);
|
|
110
|
+
setCitationPaneText(text);
|
|
111
|
+
|
|
112
|
+
// Simple debounce - reset guard after a short delay
|
|
113
|
+
setTimeout(() => {
|
|
114
|
+
citationOpeningRef.current = false;
|
|
115
|
+
}, 100);
|
|
116
|
+
}
|
|
117
|
+
} catch (e) {
|
|
118
|
+
citationOpeningRef.current = false;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
document.addEventListener("click", clickHandler);
|
|
122
|
+
return () => document.removeEventListener("click", clickHandler);
|
|
123
|
+
}, [state]);
|
|
66
124
|
const containerStyles = {
|
|
67
125
|
root: Object.assign({}, defaultWebChatContainerStatefulProps.containerStyles, webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.containerStyles, {
|
|
68
126
|
display: state.appStates.isMinimized ? "none" : ""
|
|
@@ -97,8 +155,10 @@ export const WebChatContainerStateful = props => {
|
|
|
97
155
|
localStorage;
|
|
98
156
|
sessionStorage;
|
|
99
157
|
} catch (error) {
|
|
158
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
100
159
|
if (!window.TPCWarningShown) {
|
|
101
160
|
NotificationHandler.notifyWarning(NotificationScenarios.TPC, (localizedTexts === null || localizedTexts === void 0 ? void 0 : localizedTexts.THIRD_PARTY_COOKIES_BLOCKED_ALERT_MESSAGE) ?? "");
|
|
161
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
102
162
|
window.TPCWarningShown = true;
|
|
103
163
|
}
|
|
104
164
|
}
|
|
@@ -287,10 +347,31 @@ export const WebChatContainerStateful = props => {
|
|
|
287
347
|
overflow-y: unset;
|
|
288
348
|
}
|
|
289
349
|
|
|
290
|
-
|
|
350
|
+
/* Custom styles for carousel hero cards */
|
|
351
|
+
ul.webchat__carousel-filmstrip__attachments .ac-image {
|
|
352
|
+
width: 200px !important;
|
|
353
|
+
height: 150px !important;
|
|
354
|
+
object-fit: cover !important;
|
|
355
|
+
border-radius: 8px !important;
|
|
356
|
+
border: 1px solid #e0e0e0 !important;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.webchat__carousel-filmstrip-attachment .webchat__bubble {
|
|
360
|
+
height: 100% !important;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
.webchat__carousel-filmstrip-attachment .webchat__bubble #ms_lcw_webchat_adaptive_card {
|
|
364
|
+
height: 100% !important;
|
|
365
|
+
}
|
|
366
|
+
|
|
291
367
|
`), /*#__PURE__*/React.createElement(Stack, {
|
|
292
368
|
styles: containerStyles,
|
|
293
369
|
className: "webchat__stacked-layout_container"
|
|
294
|
-
}, /*#__PURE__*/React.createElement(BasicWebChat, null))
|
|
370
|
+
}, /*#__PURE__*/React.createElement(BasicWebChat, null)), citationPaneOpen && /*#__PURE__*/React.createElement(CitationPaneStateful, {
|
|
371
|
+
id: HtmlAttributeNames.ocwCitationPaneClassName,
|
|
372
|
+
title: HtmlAttributeNames.ocwCitationPaneTitle,
|
|
373
|
+
contentHtml: citationPaneText,
|
|
374
|
+
onClose: () => setCitationPaneOpen(false)
|
|
375
|
+
}));
|
|
295
376
|
};
|
|
296
377
|
export default WebChatContainerStateful;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|