@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.
Files changed (126) hide show
  1. package/README.md +46 -1
  2. package/lib/cjs/common/Constants.js +10 -2
  3. package/lib/cjs/common/telemetry/TelemetryConstants.js +6 -0
  4. package/lib/cjs/common/telemetry/TelemetryHelper.js +7 -5
  5. package/lib/cjs/common/utils.js +27 -2
  6. package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +4 -4
  7. package/lib/cjs/components/citationpanestateful/CitationDim.js +29 -0
  8. package/lib/cjs/components/citationpanestateful/CitationPaneStateful.js +199 -0
  9. package/lib/cjs/components/citationpanestateful/common/defaultProps/defaultCitationPaneProps.js +70 -0
  10. package/lib/cjs/components/confirmationpanestateful/interfaces/IConfirmationPaneLocalizedTexts.js +1 -0
  11. package/lib/cjs/components/livechatwidget/LiveChatWidget.js +4 -4
  12. package/lib/cjs/components/livechatwidget/common/ActivitySubscriber/BotAuthActivitySubscriber.js +4 -5
  13. package/lib/cjs/components/livechatwidget/common/createInternetConnectionChangeHandler.js +22 -9
  14. package/lib/cjs/components/livechatwidget/common/createMarkdown.js +54 -1
  15. package/lib/cjs/components/livechatwidget/common/customEventHandler.js +53 -0
  16. package/lib/cjs/components/livechatwidget/common/endChat.js +34 -4
  17. package/lib/cjs/components/livechatwidget/common/getMockChatSDKIfApplicable.js +4 -3
  18. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +12 -5
  19. package/lib/cjs/components/livechatwidget/common/overridePropsOnMockIfApplicable.js +2 -1
  20. package/lib/cjs/components/livechatwidget/common/renderSurveyHelpers.js +23 -0
  21. package/lib/cjs/components/livechatwidget/common/startChat.js +8 -6
  22. package/lib/cjs/components/livechatwidget/interfaces/IMockProps.js +8 -2
  23. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +45 -11
  24. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +114 -13
  25. package/lib/cjs/components/webchatcontainerstateful/common/DesignerChatAdapter.js +43 -12
  26. package/lib/cjs/components/webchatcontainerstateful/common/DesignerChatSDK.js +6 -1
  27. package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +1 -1
  28. package/lib/cjs/components/webchatcontainerstateful/common/utils/chatAdapterUtils.js +62 -3
  29. package/lib/cjs/components/webchatcontainerstateful/common/utils/fontUtils.js +28 -0
  30. package/lib/cjs/components/webchatcontainerstateful/interfaces/ICitation.js +1 -0
  31. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultAvatarTextStyles.js +1 -1
  32. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSystemMessageStyles.js +1 -1
  33. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.js +42 -0
  34. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.js +139 -0
  35. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +41 -0
  36. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +54 -0
  37. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +45 -0
  38. package/lib/cjs/contexts/common/CustomEventType.js +1 -0
  39. package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +46 -45
  40. package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +2 -0
  41. package/lib/cjs/contexts/createReducer.js +15 -0
  42. package/lib/cjs/firstresponselatency/FirstMessageTrackerFromBot.js +101 -36
  43. package/lib/cjs/firstresponselatency/FirstResponseLatencyTracker.js +39 -21
  44. package/lib/cjs/firstresponselatency/util.js +24 -10
  45. package/lib/cjs/index.js +9 -1
  46. package/lib/cjs/plugins/createChatTranscript.js +13 -0
  47. package/lib/cjs/plugins/newMessageEventHandler.js +2 -2
  48. package/lib/esm/common/Constants.js +10 -2
  49. package/lib/esm/common/telemetry/TelemetryConstants.js +6 -0
  50. package/lib/esm/common/telemetry/TelemetryHelper.js +7 -5
  51. package/lib/esm/common/utils.js +21 -0
  52. package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +4 -4
  53. package/lib/esm/components/citationpanestateful/CitationDim.js +20 -0
  54. package/lib/esm/components/citationpanestateful/CitationPaneStateful.js +188 -0
  55. package/lib/esm/components/citationpanestateful/common/defaultProps/defaultCitationPaneProps.js +61 -0
  56. package/lib/esm/components/confirmationpanestateful/interfaces/IConfirmationPaneLocalizedTexts.js +1 -0
  57. package/lib/esm/components/livechatwidget/LiveChatWidget.js +4 -4
  58. package/lib/esm/components/livechatwidget/common/ActivitySubscriber/BotAuthActivitySubscriber.js +4 -5
  59. package/lib/esm/components/livechatwidget/common/createInternetConnectionChangeHandler.js +22 -9
  60. package/lib/esm/components/livechatwidget/common/createMarkdown.js +54 -1
  61. package/lib/esm/components/livechatwidget/common/customEventHandler.js +45 -0
  62. package/lib/esm/components/livechatwidget/common/endChat.js +35 -5
  63. package/lib/esm/components/livechatwidget/common/getMockChatSDKIfApplicable.js +4 -3
  64. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +13 -6
  65. package/lib/esm/components/livechatwidget/common/overridePropsOnMockIfApplicable.js +2 -1
  66. package/lib/esm/components/livechatwidget/common/renderSurveyHelpers.js +23 -0
  67. package/lib/esm/components/livechatwidget/common/startChat.js +8 -6
  68. package/lib/esm/components/livechatwidget/interfaces/IMockProps.js +3 -3
  69. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +45 -11
  70. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +114 -14
  71. package/lib/esm/components/webchatcontainerstateful/common/DesignerChatAdapter.js +43 -12
  72. package/lib/esm/components/webchatcontainerstateful/common/DesignerChatSDK.js +6 -1
  73. package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +1 -1
  74. package/lib/esm/components/webchatcontainerstateful/common/utils/chatAdapterUtils.js +55 -0
  75. package/lib/esm/components/webchatcontainerstateful/common/utils/fontUtils.js +21 -0
  76. package/lib/esm/components/webchatcontainerstateful/interfaces/ICitation.js +1 -0
  77. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultAvatarTextStyles.js +1 -1
  78. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSystemMessageStyles.js +1 -1
  79. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.js +36 -0
  80. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.js +133 -0
  81. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +33 -0
  82. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +46 -0
  83. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +38 -0
  84. package/lib/esm/contexts/common/CustomEventType.js +1 -0
  85. package/lib/esm/contexts/common/LiveChatWidgetActionType.js +46 -45
  86. package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +2 -0
  87. package/lib/esm/contexts/createReducer.js +15 -0
  88. package/lib/esm/firstresponselatency/FirstMessageTrackerFromBot.js +101 -36
  89. package/lib/esm/firstresponselatency/FirstResponseLatencyTracker.js +39 -21
  90. package/lib/esm/firstresponselatency/util.js +21 -8
  91. package/lib/esm/index.js +1 -0
  92. package/lib/esm/plugins/createChatTranscript.js +13 -0
  93. package/lib/esm/plugins/newMessageEventHandler.js +3 -3
  94. package/lib/types/common/Constants.d.ts +10 -2
  95. package/lib/types/common/telemetry/TelemetryConstants.d.ts +6 -0
  96. package/lib/types/common/utils.d.ts +8 -0
  97. package/lib/types/components/citationpanestateful/CitationDim.d.ts +5 -0
  98. package/lib/types/components/citationpanestateful/CitationPaneStateful.d.ts +4 -0
  99. package/lib/types/components/citationpanestateful/common/defaultProps/defaultCitationPaneProps.d.ts +11 -0
  100. package/lib/types/components/citationpanestateful/interfaces/ICitationPaneStatefulProps.d.ts +19 -0
  101. package/lib/types/components/confirmationpanestateful/common/defaultProps/defaultConfirmationPaneLocalizedTexts.d.ts +1 -1
  102. package/lib/types/components/confirmationpanestateful/interfaces/IConfirmationPaneStatefulProps.d.ts +1 -1
  103. package/lib/types/components/livechatwidget/common/customEventHandler.d.ts +4 -0
  104. package/lib/types/components/livechatwidget/common/getMockChatSDKIfApplicable.d.ts +2 -1
  105. package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetProps.d.ts +3 -1
  106. package/lib/types/components/livechatwidget/interfaces/IMockProps.d.ts +5 -3
  107. package/lib/types/components/webchatcontainerstateful/common/DesignerChatAdapter.d.ts +4 -2
  108. package/lib/types/components/webchatcontainerstateful/common/DesignerChatSDK.d.ts +5 -0
  109. package/lib/types/components/webchatcontainerstateful/common/utils/chatAdapterUtils.d.ts +8 -1
  110. package/lib/types/components/webchatcontainerstateful/common/utils/fontUtils.d.ts +10 -0
  111. package/lib/types/components/webchatcontainerstateful/interfaces/ICitation.d.ts +12 -0
  112. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.d.ts +8 -0
  113. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.d.ts +4 -0
  114. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.d.ts +22 -0
  115. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.d.ts +5 -0
  116. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.d.ts +5 -0
  117. package/lib/types/contexts/common/CustomEventType.d.ts +6 -0
  118. package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +1 -0
  119. package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +46 -45
  120. package/lib/types/firstresponselatency/FirstResponseLatencyTracker.d.ts +2 -2
  121. package/lib/types/firstresponselatency/util.d.ts +1 -0
  122. package/lib/types/index.d.ts +1 -0
  123. package/package.json +5 -4
  124. /package/lib/cjs/components/{confirmationpanestateful/interfaces/IConfirmationPaneLocalizedText.js → citationpanestateful/interfaces/ICitationPaneStatefulProps.js} +0 -0
  125. /package/lib/esm/components/{confirmationpanestateful/interfaces/IConfirmationPaneLocalizedText.js → citationpanestateful/interfaces/ICitationPaneStatefulProps.js} +0 -0
  126. /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;
@@ -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
+ };
@@ -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$mock, _props$featureConfigP, _props$chatConfig, _props$chatConfig$Liv, _props$chatConfig2, _props$chatConfig2$Li;
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 : (_props$mock = props.mock) === null || _props$mock === void 0 ? void 0 : _props$mock.type);
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$mock2;
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$mock2 = props.mock) === null || _props$mock2 === void 0 ? void 0 : _props$mock2.type)
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(() => {
@@ -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 isInternetConnected = async () => {
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(Constants.internetConnectionTestUrl);
13
- const text = await response.text();
14
- return text === Constants.internetConnectionTestUrlText;
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
- const connected = await isInternetConnected();
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$domain, _inMemoryState$domain2;
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$domain = inMemoryState.domainStates) === null || _inMemoryState$domain === void 0 ? void 0 : (_inMemoryState$domain2 = _inMemoryState$domain.middlewareLocalizedTexts) === null || _inMemoryState$domain2 === void 0 ? void 0 : _inMemoryState$domain2.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION);
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$domain3, _inMemoryState$domain4;
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$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_INTERNET_BACK_ONLINE) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE);
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" // Rule to proceess '\n'
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
- let isConversationalSurveyEnabled = state.appStates.isConversationalSurveyEnabled;
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: inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta = inMemoryState.appStates) === null || _inMemoryState$appSta === void 0 ? void 0 : _inMemoryState$appSta.chatDisconnectEventReceived
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
- const closeChatWidget = dispatch => {
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, type) => {
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();