@microsoft/omnichannel-chat-widget 1.8.3-main.4743fdc → 1.8.3-main.6e2c76b

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.
@@ -19,6 +19,7 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
19
19
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
20
20
  let uiTimer;
21
21
  const CitationPaneStateful = props => {
22
+ var _props$styleProps3;
22
23
  (0, _react.useEffect)(() => {
23
24
  uiTimer = (0, _utils.createTimer)();
24
25
  _TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
@@ -30,7 +31,9 @@ const CitationPaneStateful = props => {
30
31
 
31
32
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
32
33
  const [state, dispatch] = (0, _useChatContextStore.default)();
33
- const controlId = _Constants.HtmlAttributeNames.ocwCitationPaneClassName;
34
+
35
+ // Use props.id if provided, otherwise fall back to default
36
+ const controlId = props.id || _Constants.HtmlAttributeNames.ocwCitationPaneClassName;
34
37
 
35
38
  // Pane style computed to match the webchat widget container bounds so the pane
36
39
  // stays within the widget and scrolls only vertically. We also track an
@@ -66,9 +69,11 @@ const CitationPaneStateful = props => {
66
69
  // fall back to the default pane styles from defaultCitationPaneProps.
67
70
  (0, _react.useEffect)(() => {
68
71
  const compute = () => {
72
+ var _props$styleProps2;
69
73
  try {
70
74
  const container = document.querySelector(".webchat__stacked-layout_container");
71
75
  if (container) {
76
+ var _props$styleProps;
72
77
  const rect = container.getBoundingClientRect();
73
78
  const widthPx = Math.round(rect.width * 0.95);
74
79
  const heightPx = Math.round(rect.height * 0.95);
@@ -84,12 +89,25 @@ const CitationPaneStateful = props => {
84
89
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
85
90
  delete base.transform;
86
91
  }
87
- setPaneStyle(Object.assign({}, base, {
92
+
93
+ // Merge user styles first, then computed positioning to ensure proper positioning
94
+ const computedStyle = {
88
95
  left: `${leftPx}px`,
89
96
  top: `${topPx}px`,
90
97
  width: `${widthPx}px`,
91
98
  height: `${heightPx}px`
92
- }));
99
+ };
100
+
101
+ // Apply user styles first, then override with computed positioning
102
+ const generalProps = (_props$styleProps = props.styleProps) === null || _props$styleProps === void 0 ? void 0 : _props$styleProps.generalStyleProps;
103
+ const userStyles = generalProps && typeof generalProps === "object" ? Object.assign({}, generalProps) : {};
104
+ // Remove positioning properties from user styles that would interfere
105
+ delete userStyles.position;
106
+ delete userStyles.left;
107
+ delete userStyles.top;
108
+ delete userStyles.width;
109
+ delete userStyles.height;
110
+ setPaneStyle(Object.assign({}, base, userStyles, computedStyle));
93
111
  // Make the pane visible after the next paint to avoid layout
94
112
  // flashes on initial mount.
95
113
  requestAnimationFrame(() => setIsReady(true));
@@ -99,14 +117,23 @@ const CitationPaneStateful = props => {
99
117
  // ignore
100
118
  }
101
119
 
102
- // fallback
103
- setPaneStyle(_defaultCitationPaneProps.defaultCitationPaneStyles.pane);
120
+ // fallback - merge defaults with user-provided styles but preserve positioning
121
+ const generalProps = (_props$styleProps2 = props.styleProps) === null || _props$styleProps2 === void 0 ? void 0 : _props$styleProps2.generalStyleProps;
122
+ const userStyles = generalProps && typeof generalProps === "object" ? Object.assign({}, generalProps) : {};
123
+ // Remove positioning properties from user styles for fallback
124
+ delete userStyles.position;
125
+ delete userStyles.left;
126
+ delete userStyles.top;
127
+ delete userStyles.width;
128
+ delete userStyles.height;
129
+ const fallbackStyle = Object.assign({}, _defaultCitationPaneProps.defaultCitationPaneStyles.pane, userStyles);
130
+ setPaneStyle(fallbackStyle);
104
131
  requestAnimationFrame(() => setIsReady(true));
105
132
  };
106
133
  compute();
107
134
  window.addEventListener("resize", compute);
108
135
  return () => window.removeEventListener("resize", compute);
109
- }, []);
136
+ }, [(_props$styleProps3 = props.styleProps) === null || _props$styleProps3 === void 0 ? void 0 : _props$styleProps3.generalStyleProps]);
110
137
  const handleClose = () => {
111
138
  if (props.onClose) props.onClose();
112
139
  dispatch({
@@ -117,7 +144,7 @@ const CitationPaneStateful = props => {
117
144
  };
118
145
 
119
146
  // Merge a safe style object for the container and cast to CSSProperties to satisfy TS
120
- const mergedStyle = Object.assign({
147
+ const baseStyle = Object.assign({
121
148
  position: "relative"
122
149
  }, paneStyle ?? {
123
150
  position: "fixed"
@@ -129,28 +156,41 @@ const CitationPaneStateful = props => {
129
156
  visibility: isReady ? "visible" : "hidden",
130
157
  pointerEvents: isReady ? "auto" : "none"
131
158
  };
159
+
160
+ // Default wrapper styles - these control the positioning container
161
+ const defaultWrapperStyles = {
162
+ display: "flex",
163
+ flexDirection: "column",
164
+ zIndex: 10001
165
+ };
166
+
167
+ // Wrapper styles for the positioning container
168
+ const wrapperStyles = Object.assign({}, baseStyle, hiddenStyle, defaultWrapperStyles);
169
+
170
+ // Merge the computed positioning styles with user's generalStyleProps for the CitationPane
171
+ const mergedStyleProps = props.styleProps ? {
172
+ ...props.styleProps,
173
+ generalStyleProps: Object.assign({}, props.styleProps.generalStyleProps)
174
+ } : undefined;
132
175
  const controlProps = {
133
176
  id: controlId,
134
177
  dir: state.domainStates.globalDir,
135
178
  titleText: props.title,
136
179
  contentHtml: props.contentHtml,
137
180
  brightnessValueOnDim: "0.2",
181
+ // Default brightness
138
182
  onClose: handleClose,
139
- ...(props === null || props === void 0 ? void 0 : props.controlProps)
183
+ ...(props === null || props === void 0 ? void 0 : props.controlProps) // User props override defaults
140
184
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
141
185
  };
142
186
 
143
187
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_CitationDim.default, {
144
- brightness: "0.2"
188
+ brightness: controlProps.brightnessValueOnDim
145
189
  }), /*#__PURE__*/_react.default.createElement("div", {
146
- style: Object.assign({}, mergedStyle, hiddenStyle, {
147
- display: "flex",
148
- flexDirection: "column",
149
- zIndex: 10001
150
- })
190
+ style: wrapperStyles
151
191
  }, /*#__PURE__*/_react.default.createElement(_omnichannelChatComponents.CitationPane, {
152
192
  controlProps: controlProps,
153
- styleProps: props === null || props === void 0 ? void 0 : props.styleProps
193
+ styleProps: mergedStyleProps
154
194
  })));
155
195
  };
156
196
  exports.CitationPaneStateful = CitationPaneStateful;
@@ -17,7 +17,6 @@ function _toPrimitive(input, hint) { if (typeof input !== "object" || input ===
17
17
  const supportedSignInCardContentTypes = ["application/vnd.microsoft.card.signin", "application/vnd.microsoft.card.oauth"];
18
18
  const botOauthUrlRegex = /[\S]+.botframework.com\/api\/oauth\/signin\?signin=([\S]+)/;
19
19
  const delay = t => new Promise(resolve => setTimeout(resolve, t));
20
- let response;
21
20
  const extractSignInId = signInUrl => {
22
21
  const result = botOauthUrlRegex.exec(signInUrl);
23
22
  if (result && result[1]) {
@@ -53,20 +52,20 @@ const fetchBotAuthConfig = async (retries, interval) => {
53
52
  eventName: _TelemetryConstants.BroadcastEvent.BotAuthConfigRequest
54
53
  };
55
54
  _omnichannelChatComponents.BroadcastService.postMessage(botAuthConfigRequestEvent);
55
+ let response;
56
56
  const listener = _omnichannelChatComponents.BroadcastService.getMessageByEventName(_TelemetryConstants.BroadcastEvent.BotAuthConfigResponse).subscribe(data => {
57
57
  var _data$payload, _data$payload2;
58
58
  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;
59
59
  listener.unsubscribe();
60
60
  });
61
- if (response !== undefined) {
62
- //return response;
63
- return response;
64
- }
65
61
  if (retries === 1) {
66
62
  // Base Case
67
63
  throw new Error();
68
64
  }
69
65
  await delay(interval);
66
+ if (response !== undefined) {
67
+ return response;
68
+ }
70
69
  return await fetchBotAuthConfig(--retries, interval);
71
70
  };
72
71
  let BotAuthActivitySubscriber = /*#__PURE__*/function () {
@@ -153,8 +153,27 @@ const endChat = async (props, facadeChatSDK, state, dispatch, setAdapter, setWeb
153
153
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
154
154
  payload: null
155
155
  });
156
+ let isSessionEnded = inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta = inMemoryState.appStates) === null || _inMemoryState$appSta === void 0 ? void 0 : _inMemoryState$appSta.chatDisconnectEventReceived;
157
+ if (!isSessionEnded) {
158
+ // double check by fetching the latest conversation details
159
+ const conversationDetails = await (0, _utils.getConversationDetailsCall)(facadeChatSDK);
160
+ if ((conversationDetails === null || conversationDetails === void 0 ? void 0 : conversationDetails.state) === _Constants.LiveWorkItemState.WrapUp || (conversationDetails === null || conversationDetails === void 0 ? void 0 : conversationDetails.state) === _Constants.LiveWorkItemState.Closed) {
161
+ dispatch({
162
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CHAT_DISCONNECT_EVENT_RECEIVED,
163
+ payload: true
164
+ });
165
+ _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
166
+ Event: _TelemetryConstants.TelemetryEvent.ChatDisconnectThreadEventReceived,
167
+ Description: "Checking conversation details upon endChat. Chat disconnected.",
168
+ CustomProperties: {
169
+ conversationDetails
170
+ }
171
+ });
172
+ isSessionEnded = true;
173
+ }
174
+ }
156
175
  const endChatOptionalParameters = {
157
- isSessionEnded: inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta = inMemoryState.appStates) === null || _inMemoryState$appSta === void 0 ? void 0 : _inMemoryState$appSta.chatDisconnectEventReceived
176
+ isSessionEnded
158
177
  };
159
178
  try {
160
179
  _TelemetryHelper.TelemetryHelper.logSDKEvent(_TelemetryConstants.LogLevel.INFO, {
@@ -105,7 +105,7 @@ const setPreChatAndInitiateChat = async (facadeChatSDK, dispatch, setAdapter, is
105
105
 
106
106
  // If minimized, maximize the chat, if the state is missing, consider it as minimized
107
107
  if ((state === null || state === void 0 ? void 0 : state.appStates.isMinimized) === undefined || (state === null || state === void 0 ? void 0 : (_state$appStates = state.appStates) === null || _state$appStates === void 0 ? void 0 : _state$appStates.isMinimized) === true) {
108
- var _state$domainStates3, _state$domainStates3$, _state$domainStates4, _state$domainStates4$;
108
+ var _state$domainStates3, _state$domainStates3$, _state$domainStates4, _state$domainStates4$, _TelemetryManager$Int;
109
109
  dispatch({
110
110
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_MINIMIZED,
111
111
  payload: false
@@ -116,7 +116,8 @@ const setPreChatAndInitiateChat = async (facadeChatSDK, dispatch, setAdapter, is
116
116
  eventName: _TelemetryConstants.BroadcastEvent.MaximizeChat,
117
117
  payload: {
118
118
  height: state === null || state === void 0 ? void 0 : (_state$domainStates3 = state.domainStates) === null || _state$domainStates3 === void 0 ? void 0 : (_state$domainStates3$ = _state$domainStates3.widgetSize) === null || _state$domainStates3$ === void 0 ? void 0 : _state$domainStates3$.height,
119
- width: state === null || state === void 0 ? void 0 : (_state$domainStates4 = state.domainStates) === null || _state$domainStates4 === void 0 ? void 0 : (_state$domainStates4$ = _state$domainStates4.widgetSize) === null || _state$domainStates4$ === void 0 ? void 0 : _state$domainStates4$.width
119
+ width: state === null || state === void 0 ? void 0 : (_state$domainStates4 = state.domainStates) === null || _state$domainStates4 === void 0 ? void 0 : (_state$domainStates4$ = _state$domainStates4.widgetSize) === null || _state$domainStates4$ === void 0 ? void 0 : _state$domainStates4$.width,
120
+ runtimeId: _TelemetryManager.TelemetryManager === null || _TelemetryManager.TelemetryManager === void 0 ? void 0 : (_TelemetryManager$Int = _TelemetryManager.TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int === void 0 ? void 0 : _TelemetryManager$Int.lcwRuntimeId
120
121
  }
121
122
  });
122
123
  }
@@ -137,7 +138,7 @@ const setPreChatAndInitiateChat = async (facadeChatSDK, dispatch, setAdapter, is
137
138
  * This is because a new change to control OOH as closed event when a widget is coming from chat.
138
139
  */
139
140
  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) {
140
- var _state$domainStates5, _state$domainStates5$, _state$domainStates6, _state$domainStates6$, _TelemetryManager$Int;
141
+ var _state$domainStates5, _state$domainStates5$, _state$domainStates6, _state$domainStates6$, _TelemetryManager$Int2;
141
142
  dispatch({
142
143
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_MINIMIZED,
143
144
  payload: false
@@ -148,7 +149,7 @@ const setPreChatAndInitiateChat = async (facadeChatSDK, dispatch, setAdapter, is
148
149
  payload: {
149
150
  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,
150
151
  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,
151
- runtimeId: _TelemetryManager.TelemetryManager === null || _TelemetryManager.TelemetryManager === void 0 ? void 0 : (_TelemetryManager$Int = _TelemetryManager.TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int === void 0 ? void 0 : _TelemetryManager$Int.lcwRuntimeId
152
+ runtimeId: _TelemetryManager.TelemetryManager === null || _TelemetryManager.TelemetryManager === void 0 ? void 0 : (_TelemetryManager$Int2 = _TelemetryManager.TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int2 === void 0 ? void 0 : _TelemetryManager$Int2.lcwRuntimeId
152
153
  }
153
154
  });
154
155
  }
@@ -488,7 +488,8 @@ const LiveChatWidgetStateful = props => {
488
488
  eventName: _TelemetryConstants.BroadcastEvent.MaximizeChat,
489
489
  payload: {
490
490
  height: inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain = inMemoryState.domainStates) === null || _inMemoryState$domain === void 0 ? void 0 : (_inMemoryState$domain2 = _inMemoryState$domain.widgetSize) === null || _inMemoryState$domain2 === void 0 ? void 0 : _inMemoryState$domain2.height,
491
- width: inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain3 = inMemoryState.domainStates) === null || _inMemoryState$domain3 === void 0 ? void 0 : (_inMemoryState$domain4 = _inMemoryState$domain3.widgetSize) === null || _inMemoryState$domain4 === void 0 ? void 0 : _inMemoryState$domain4.width
491
+ width: inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain3 = inMemoryState.domainStates) === null || _inMemoryState$domain3 === void 0 ? void 0 : (_inMemoryState$domain4 = _inMemoryState$domain3.widgetSize) === null || _inMemoryState$domain4 === void 0 ? void 0 : _inMemoryState$domain4.width,
492
+ lcwRuntimeId: _TelemetryManager.TelemetryManager.InternalTelemetryData.lcwRuntimeId
492
493
  }
493
494
  });
494
495
  return;
@@ -893,6 +894,29 @@ const LiveChatWidgetStateful = props => {
893
894
  background: ${scrollbarProps.thumbHoverColor};
894
895
  }
895
896
 
897
+ /* High Contrast mode support - optimized for all variants */
898
+ @media (prefers-contrast: high), (-ms-high-contrast: active), (forced-colors: active) {
899
+ ::-webkit-scrollbar-track {
900
+ background: Canvas !important;
901
+ border: 1px solid CanvasText !important;
902
+ }
903
+
904
+ ::-webkit-scrollbar-thumb {
905
+ background: CanvasText !important;
906
+ border: 1px solid Canvas !important;
907
+ min-height: 20px !important;
908
+ }
909
+
910
+ ::-webkit-scrollbar-thumb:hover {
911
+ background: Highlight !important;
912
+ border: 1px solid CanvasText !important;
913
+ }
914
+
915
+ ::-webkit-scrollbar-corner {
916
+ background: Canvas !important;
917
+ }
918
+ }
919
+
896
920
  .webchat__basic-transcript__activity-markdown-body > :last-child {
897
921
  margin-bottom: 0px;
898
922
  }
@@ -57,7 +57,7 @@ const createMagicCodeSuccessResponse = signin => {
57
57
  };
58
58
  };
59
59
  const WebChatContainerStateful = props => {
60
- var _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _webChatContainerProp7, _webChatContainerProp8, _props$webChatContain5, _props$webChatContain6, _defaultWebChatContai, _props$webChatContain7, _props$webChatContain8, _defaultWebChatContai2, _webChatContainerProp9, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _webChatContainerProp13, _webChatContainerProp14, _webChatContainerProp15, _webChatContainerProp16, _webChatContainerProp17, _webChatContainerProp18, _webChatContainerProp19, _webChatContainerProp20, _webChatContainerProp21, _webChatContainerProp22, _webChatContainerProp23, _props$webChatContain9, _props$webChatContain10;
60
+ var _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _webChatContainerProp7, _webChatContainerProp8, _props$webChatContain5, _props$webChatContain6, _defaultWebChatContai, _props$webChatContain7, _props$webChatContain8, _defaultWebChatContai2, _webChatContainerProp9, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _webChatContainerProp13, _webChatContainerProp14, _webChatContainerProp15, _webChatContainerProp16, _webChatContainerProp17, _webChatContainerProp18, _webChatContainerProp19, _webChatContainerProp20, _webChatContainerProp21, _webChatContainerProp22, _webChatContainerProp23, _props$webChatContain9, _props$webChatContain10, _props$citationPanePr, _props$citationPanePr2, _props$citationPanePr3, _props$citationPanePr4;
61
61
  (0, _react2.useEffect)(() => {
62
62
  uiTimer = (0, _utils.createTimer)();
63
63
  _TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
@@ -377,10 +377,12 @@ const WebChatContainerStateful = props => {
377
377
  styles: containerStyles,
378
378
  className: "webchat__stacked-layout_container"
379
379
  }, /*#__PURE__*/_react2.default.createElement(BasicWebChat, null)), citationPaneOpen && /*#__PURE__*/_react2.default.createElement(_CitationPaneStateful.default, {
380
- id: _Constants.HtmlAttributeNames.ocwCitationPaneClassName,
381
- title: _Constants.HtmlAttributeNames.ocwCitationPaneTitle,
380
+ id: ((_props$citationPanePr = props.citationPaneProps) === null || _props$citationPanePr === void 0 ? void 0 : _props$citationPanePr.id) || _Constants.HtmlAttributeNames.ocwCitationPaneClassName,
381
+ title: ((_props$citationPanePr2 = props.citationPaneProps) === null || _props$citationPanePr2 === void 0 ? void 0 : _props$citationPanePr2.title) || _Constants.HtmlAttributeNames.ocwCitationPaneTitle,
382
382
  contentHtml: citationPaneText,
383
- onClose: () => setCitationPaneOpen(false)
383
+ onClose: () => setCitationPaneOpen(false),
384
+ controlProps: (_props$citationPanePr3 = props.citationPaneProps) === null || _props$citationPanePr3 === void 0 ? void 0 : _props$citationPanePr3.controlProps,
385
+ styleProps: (_props$citationPanePr4 = props.citationPaneProps) === null || _props$citationPanePr4 === void 0 ? void 0 : _props$citationPanePr4.styleProps
384
386
  }));
385
387
  };
386
388
  exports.WebChatContainerStateful = WebChatContainerStateful;
@@ -10,6 +10,7 @@ import { defaultCitationPaneStyles } from "./common/defaultProps/defaultCitation
10
10
  import useChatContextStore from "../../hooks/useChatContextStore";
11
11
  let uiTimer;
12
12
  export const CitationPaneStateful = props => {
13
+ var _props$styleProps3;
13
14
  useEffect(() => {
14
15
  uiTimer = createTimer();
15
16
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
@@ -21,7 +22,9 @@ export const CitationPaneStateful = props => {
21
22
 
22
23
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
23
24
  const [state, dispatch] = useChatContextStore();
24
- const controlId = HtmlAttributeNames.ocwCitationPaneClassName;
25
+
26
+ // Use props.id if provided, otherwise fall back to default
27
+ const controlId = props.id || HtmlAttributeNames.ocwCitationPaneClassName;
25
28
 
26
29
  // Pane style computed to match the webchat widget container bounds so the pane
27
30
  // stays within the widget and scrolls only vertically. We also track an
@@ -57,9 +60,11 @@ export const CitationPaneStateful = props => {
57
60
  // fall back to the default pane styles from defaultCitationPaneProps.
58
61
  useEffect(() => {
59
62
  const compute = () => {
63
+ var _props$styleProps2;
60
64
  try {
61
65
  const container = document.querySelector(".webchat__stacked-layout_container");
62
66
  if (container) {
67
+ var _props$styleProps;
63
68
  const rect = container.getBoundingClientRect();
64
69
  const widthPx = Math.round(rect.width * 0.95);
65
70
  const heightPx = Math.round(rect.height * 0.95);
@@ -75,12 +80,25 @@ export const CitationPaneStateful = props => {
75
80
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
76
81
  delete base.transform;
77
82
  }
78
- setPaneStyle(Object.assign({}, base, {
83
+
84
+ // Merge user styles first, then computed positioning to ensure proper positioning
85
+ const computedStyle = {
79
86
  left: `${leftPx}px`,
80
87
  top: `${topPx}px`,
81
88
  width: `${widthPx}px`,
82
89
  height: `${heightPx}px`
83
- }));
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));
84
102
  // Make the pane visible after the next paint to avoid layout
85
103
  // flashes on initial mount.
86
104
  requestAnimationFrame(() => setIsReady(true));
@@ -90,14 +108,23 @@ export const CitationPaneStateful = props => {
90
108
  // ignore
91
109
  }
92
110
 
93
- // fallback
94
- setPaneStyle(defaultCitationPaneStyles.pane);
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);
95
122
  requestAnimationFrame(() => setIsReady(true));
96
123
  };
97
124
  compute();
98
125
  window.addEventListener("resize", compute);
99
126
  return () => window.removeEventListener("resize", compute);
100
- }, []);
127
+ }, [(_props$styleProps3 = props.styleProps) === null || _props$styleProps3 === void 0 ? void 0 : _props$styleProps3.generalStyleProps]);
101
128
  const handleClose = () => {
102
129
  if (props.onClose) props.onClose();
103
130
  dispatch({
@@ -108,7 +135,7 @@ export const CitationPaneStateful = props => {
108
135
  };
109
136
 
110
137
  // Merge a safe style object for the container and cast to CSSProperties to satisfy TS
111
- const mergedStyle = Object.assign({
138
+ const baseStyle = Object.assign({
112
139
  position: "relative"
113
140
  }, paneStyle ?? {
114
141
  position: "fixed"
@@ -120,28 +147,41 @@ export const CitationPaneStateful = props => {
120
147
  visibility: isReady ? "visible" : "hidden",
121
148
  pointerEvents: isReady ? "auto" : "none"
122
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;
123
166
  const controlProps = {
124
167
  id: controlId,
125
168
  dir: state.domainStates.globalDir,
126
169
  titleText: props.title,
127
170
  contentHtml: props.contentHtml,
128
171
  brightnessValueOnDim: "0.2",
172
+ // Default brightness
129
173
  onClose: handleClose,
130
- ...(props === null || props === void 0 ? void 0 : props.controlProps)
174
+ ...(props === null || props === void 0 ? void 0 : props.controlProps) // User props override defaults
131
175
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
132
176
  };
133
177
 
134
178
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(CitationDim, {
135
- brightness: "0.2"
179
+ brightness: controlProps.brightnessValueOnDim
136
180
  }), /*#__PURE__*/React.createElement("div", {
137
- style: Object.assign({}, mergedStyle, hiddenStyle, {
138
- display: "flex",
139
- flexDirection: "column",
140
- zIndex: 10001
141
- })
181
+ style: wrapperStyles
142
182
  }, /*#__PURE__*/React.createElement(CitationPane, {
143
183
  controlProps: controlProps,
144
- styleProps: props === null || props === void 0 ? void 0 : props.styleProps
184
+ styleProps: mergedStyleProps
145
185
  })));
146
186
  };
147
187
  export default CitationPaneStateful;
@@ -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 () {
@@ -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";
@@ -147,8 +147,27 @@ const endChat = async (props, facadeChatSDK, state, dispatch, setAdapter, setWeb
147
147
  type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
148
148
  payload: null
149
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
+ dispatch({
156
+ type: LiveChatWidgetActionType.SET_CHAT_DISCONNECT_EVENT_RECEIVED,
157
+ payload: true
158
+ });
159
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
160
+ Event: TelemetryEvent.ChatDisconnectThreadEventReceived,
161
+ Description: "Checking conversation details upon endChat. Chat disconnected.",
162
+ CustomProperties: {
163
+ conversationDetails
164
+ }
165
+ });
166
+ isSessionEnded = true;
167
+ }
168
+ }
150
169
  const endChatOptionalParameters = {
151
- isSessionEnded: inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta = inMemoryState.appStates) === null || _inMemoryState$appSta === void 0 ? void 0 : _inMemoryState$appSta.chatDisconnectEventReceived
170
+ isSessionEnded
152
171
  };
153
172
  try {
154
173
  TelemetryHelper.logSDKEvent(LogLevel.INFO, {
@@ -99,7 +99,7 @@ const setPreChatAndInitiateChat = async (facadeChatSDK, dispatch, setAdapter, is
99
99
 
100
100
  // If minimized, maximize the chat, if the state is missing, consider it as minimized
101
101
  if ((state === null || state === void 0 ? void 0 : state.appStates.isMinimized) === undefined || (state === null || state === void 0 ? void 0 : (_state$appStates = state.appStates) === null || _state$appStates === void 0 ? void 0 : _state$appStates.isMinimized) === true) {
102
- var _state$domainStates3, _state$domainStates3$, _state$domainStates4, _state$domainStates4$;
102
+ var _state$domainStates3, _state$domainStates3$, _state$domainStates4, _state$domainStates4$, _TelemetryManager$Int;
103
103
  dispatch({
104
104
  type: LiveChatWidgetActionType.SET_MINIMIZED,
105
105
  payload: false
@@ -110,7 +110,8 @@ const setPreChatAndInitiateChat = async (facadeChatSDK, dispatch, setAdapter, is
110
110
  eventName: BroadcastEvent.MaximizeChat,
111
111
  payload: {
112
112
  height: state === null || state === void 0 ? void 0 : (_state$domainStates3 = state.domainStates) === null || _state$domainStates3 === void 0 ? void 0 : (_state$domainStates3$ = _state$domainStates3.widgetSize) === null || _state$domainStates3$ === void 0 ? void 0 : _state$domainStates3$.height,
113
- width: state === null || state === void 0 ? void 0 : (_state$domainStates4 = state.domainStates) === null || _state$domainStates4 === void 0 ? void 0 : (_state$domainStates4$ = _state$domainStates4.widgetSize) === null || _state$domainStates4$ === void 0 ? void 0 : _state$domainStates4$.width
113
+ width: state === null || state === void 0 ? void 0 : (_state$domainStates4 = state.domainStates) === null || _state$domainStates4 === void 0 ? void 0 : (_state$domainStates4$ = _state$domainStates4.widgetSize) === null || _state$domainStates4$ === void 0 ? void 0 : _state$domainStates4$.width,
114
+ runtimeId: TelemetryManager === null || TelemetryManager === void 0 ? void 0 : (_TelemetryManager$Int = TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int === void 0 ? void 0 : _TelemetryManager$Int.lcwRuntimeId
114
115
  }
115
116
  });
116
117
  }
@@ -131,7 +132,7 @@ const setPreChatAndInitiateChat = async (facadeChatSDK, dispatch, setAdapter, is
131
132
  * This is because a new change to control OOH as closed event when a widget is coming from chat.
132
133
  */
133
134
  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$, _TelemetryManager$Int;
135
+ var _state$domainStates5, _state$domainStates5$, _state$domainStates6, _state$domainStates6$, _TelemetryManager$Int2;
135
136
  dispatch({
136
137
  type: LiveChatWidgetActionType.SET_MINIMIZED,
137
138
  payload: false
@@ -142,7 +143,7 @@ const setPreChatAndInitiateChat = async (facadeChatSDK, dispatch, setAdapter, is
142
143
  payload: {
143
144
  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
145
  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
146
+ runtimeId: TelemetryManager === null || TelemetryManager === void 0 ? void 0 : (_TelemetryManager$Int2 = TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int2 === void 0 ? void 0 : _TelemetryManager$Int2.lcwRuntimeId
146
147
  }
147
148
  });
148
149
  }
@@ -480,7 +480,8 @@ export const LiveChatWidgetStateful = props => {
480
480
  eventName: BroadcastEvent.MaximizeChat,
481
481
  payload: {
482
482
  height: inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain = inMemoryState.domainStates) === null || _inMemoryState$domain === void 0 ? void 0 : (_inMemoryState$domain2 = _inMemoryState$domain.widgetSize) === null || _inMemoryState$domain2 === void 0 ? void 0 : _inMemoryState$domain2.height,
483
- width: inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain3 = inMemoryState.domainStates) === null || _inMemoryState$domain3 === void 0 ? void 0 : (_inMemoryState$domain4 = _inMemoryState$domain3.widgetSize) === null || _inMemoryState$domain4 === void 0 ? void 0 : _inMemoryState$domain4.width
483
+ width: inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain3 = inMemoryState.domainStates) === null || _inMemoryState$domain3 === void 0 ? void 0 : (_inMemoryState$domain4 = _inMemoryState$domain3.widgetSize) === null || _inMemoryState$domain4 === void 0 ? void 0 : _inMemoryState$domain4.width,
484
+ lcwRuntimeId: TelemetryManager.InternalTelemetryData.lcwRuntimeId
484
485
  }
485
486
  });
486
487
  return;
@@ -885,6 +886,29 @@ export const LiveChatWidgetStateful = props => {
885
886
  background: ${scrollbarProps.thumbHoverColor};
886
887
  }
887
888
 
889
+ /* High Contrast mode support - optimized for all variants */
890
+ @media (prefers-contrast: high), (-ms-high-contrast: active), (forced-colors: active) {
891
+ ::-webkit-scrollbar-track {
892
+ background: Canvas !important;
893
+ border: 1px solid CanvasText !important;
894
+ }
895
+
896
+ ::-webkit-scrollbar-thumb {
897
+ background: CanvasText !important;
898
+ border: 1px solid Canvas !important;
899
+ min-height: 20px !important;
900
+ }
901
+
902
+ ::-webkit-scrollbar-thumb:hover {
903
+ background: Highlight !important;
904
+ border: 1px solid CanvasText !important;
905
+ }
906
+
907
+ ::-webkit-scrollbar-corner {
908
+ background: Canvas !important;
909
+ }
910
+ }
911
+
888
912
  .webchat__basic-transcript__activity-markdown-body > :last-child {
889
913
  margin-bottom: 0px;
890
914
  }
@@ -48,7 +48,7 @@ const createMagicCodeSuccessResponse = signin => {
48
48
  };
49
49
  };
50
50
  export const WebChatContainerStateful = props => {
51
- var _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _webChatContainerProp7, _webChatContainerProp8, _props$webChatContain5, _props$webChatContain6, _defaultWebChatContai, _props$webChatContain7, _props$webChatContain8, _defaultWebChatContai2, _webChatContainerProp9, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _webChatContainerProp13, _webChatContainerProp14, _webChatContainerProp15, _webChatContainerProp16, _webChatContainerProp17, _webChatContainerProp18, _webChatContainerProp19, _webChatContainerProp20, _webChatContainerProp21, _webChatContainerProp22, _webChatContainerProp23, _props$webChatContain9, _props$webChatContain10;
51
+ var _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _webChatContainerProp7, _webChatContainerProp8, _props$webChatContain5, _props$webChatContain6, _defaultWebChatContai, _props$webChatContain7, _props$webChatContain8, _defaultWebChatContai2, _webChatContainerProp9, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _webChatContainerProp13, _webChatContainerProp14, _webChatContainerProp15, _webChatContainerProp16, _webChatContainerProp17, _webChatContainerProp18, _webChatContainerProp19, _webChatContainerProp20, _webChatContainerProp21, _webChatContainerProp22, _webChatContainerProp23, _props$webChatContain9, _props$webChatContain10, _props$citationPanePr, _props$citationPanePr2, _props$citationPanePr3, _props$citationPanePr4;
52
52
  useEffect(() => {
53
53
  uiTimer = createTimer();
54
54
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
@@ -368,10 +368,12 @@ export const WebChatContainerStateful = props => {
368
368
  styles: containerStyles,
369
369
  className: "webchat__stacked-layout_container"
370
370
  }, /*#__PURE__*/React.createElement(BasicWebChat, null)), citationPaneOpen && /*#__PURE__*/React.createElement(CitationPaneStateful, {
371
- id: HtmlAttributeNames.ocwCitationPaneClassName,
372
- title: HtmlAttributeNames.ocwCitationPaneTitle,
371
+ id: ((_props$citationPanePr = props.citationPaneProps) === null || _props$citationPanePr === void 0 ? void 0 : _props$citationPanePr.id) || HtmlAttributeNames.ocwCitationPaneClassName,
372
+ title: ((_props$citationPanePr2 = props.citationPaneProps) === null || _props$citationPanePr2 === void 0 ? void 0 : _props$citationPanePr2.title) || HtmlAttributeNames.ocwCitationPaneTitle,
373
373
  contentHtml: citationPaneText,
374
- onClose: () => setCitationPaneOpen(false)
374
+ onClose: () => setCitationPaneOpen(false),
375
+ controlProps: (_props$citationPanePr3 = props.citationPaneProps) === null || _props$citationPanePr3 === void 0 ? void 0 : _props$citationPanePr3.controlProps,
376
+ styleProps: (_props$citationPanePr4 = props.citationPaneProps) === null || _props$citationPanePr4 === void 0 ? void 0 : _props$citationPanePr4.styleProps
375
377
  }));
376
378
  };
377
379
  export default WebChatContainerStateful;
@@ -3,6 +3,7 @@ import { IAppInsightsConfig } from "../../../common/telemetry/interfaces/IAppIns
3
3
  import { IAudioNotificationProps } from "../../footerstateful/audionotificationstateful/interfaces/IAudioNotificationProps";
4
4
  import { ICallingContainerProps } from "@microsoft/omnichannel-chat-components/lib/types/components/callingcontainer/interfaces/ICallingContainerProps";
5
5
  import { IChatButtonProps } from "@microsoft/omnichannel-chat-components/lib/types/components/chatbutton/interfaces/IChatButtonProps";
6
+ import { ICitationPaneProps } from "@microsoft/omnichannel-chat-components/lib/types/components/citationpane/interfaces/ICitationPaneProps";
6
7
  import { ICitationPaneStatefulProps } from "../../citationpanestateful/interfaces/ICitationPaneStatefulProps";
7
8
  import { IConfirmationPaneStatefulProps } from "../../confirmationpanestateful/interfaces/IConfirmationPaneStatefulProps";
8
9
  import { IContextDataStore } from "../../../common/interfaces/IContextDataStore";
@@ -69,4 +70,5 @@ export interface ILiveChatWidgetProps {
69
70
  mock?: IMockProps;
70
71
  featureConfigProps?: IFeatureConfigProps;
71
72
  appInsightsConfig?: IAppInsightsConfig;
73
+ citationProp?: ICitationPaneProps;
72
74
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microsoft/omnichannel-chat-widget",
3
- "version": "1.8.3-main.4743fdc",
3
+ "version": "1.8.3-main.6e2c76b",
4
4
  "description": "Microsoft Omnichannel Chat Widget",
5
5
  "main": "lib/cjs/index.js",
6
6
  "types": "lib/types/index.d.ts",