@microsoft/omnichannel-chat-widget 1.8.3-main.3445895 → 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.
Files changed (51) hide show
  1. package/lib/cjs/common/Constants.js +2 -0
  2. package/lib/cjs/common/telemetry/TelemetryConstants.js +3 -0
  3. package/lib/cjs/components/citationpanestateful/CitationDim.js +29 -0
  4. package/lib/cjs/components/citationpanestateful/CitationPaneStateful.js +158 -0
  5. package/lib/cjs/components/citationpanestateful/common/defaultProps/defaultCitationPaneProps.js +70 -0
  6. package/lib/cjs/components/confirmationpanestateful/interfaces/IConfirmationPaneLocalizedTexts.js +1 -0
  7. package/lib/cjs/components/livechatwidget/common/endChat.js +5 -1
  8. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +5 -3
  9. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +86 -3
  10. package/lib/cjs/components/webchatcontainerstateful/interfaces/ICitation.js +1 -0
  11. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.js +97 -30
  12. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +54 -0
  13. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +2 -2
  14. package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +46 -45
  15. package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +2 -0
  16. package/lib/cjs/contexts/createReducer.js +15 -0
  17. package/lib/esm/common/Constants.js +2 -0
  18. package/lib/esm/common/telemetry/TelemetryConstants.js +3 -0
  19. package/lib/esm/components/citationpanestateful/CitationDim.js +20 -0
  20. package/lib/esm/components/citationpanestateful/CitationPaneStateful.js +147 -0
  21. package/lib/esm/components/citationpanestateful/common/defaultProps/defaultCitationPaneProps.js +61 -0
  22. package/lib/esm/components/confirmationpanestateful/interfaces/IConfirmationPaneLocalizedTexts.js +1 -0
  23. package/lib/esm/components/livechatwidget/common/endChat.js +5 -1
  24. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +5 -3
  25. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +86 -4
  26. package/lib/esm/components/webchatcontainerstateful/interfaces/ICitation.js +1 -0
  27. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.js +98 -30
  28. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +46 -0
  29. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +2 -2
  30. package/lib/esm/contexts/common/LiveChatWidgetActionType.js +46 -45
  31. package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +2 -0
  32. package/lib/esm/contexts/createReducer.js +15 -0
  33. package/lib/types/common/Constants.d.ts +2 -0
  34. package/lib/types/common/telemetry/TelemetryConstants.d.ts +3 -0
  35. package/lib/types/components/citationpanestateful/CitationDim.d.ts +5 -0
  36. package/lib/types/components/citationpanestateful/CitationPaneStateful.d.ts +4 -0
  37. package/lib/types/components/citationpanestateful/common/defaultProps/defaultCitationPaneProps.d.ts +11 -0
  38. package/lib/types/components/citationpanestateful/interfaces/ICitationPaneStatefulProps.d.ts +10 -0
  39. package/lib/types/components/confirmationpanestateful/common/defaultProps/defaultConfirmationPaneLocalizedTexts.d.ts +1 -1
  40. package/lib/types/components/confirmationpanestateful/interfaces/IConfirmationPaneStatefulProps.d.ts +1 -1
  41. package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetProps.d.ts +3 -1
  42. package/lib/types/components/webchatcontainerstateful/interfaces/ICitation.d.ts +12 -0
  43. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.d.ts +3 -4
  44. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.d.ts +5 -0
  45. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.d.ts +2 -2
  46. package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +1 -0
  47. package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +46 -45
  48. package/package.json +2 -2
  49. /package/lib/cjs/components/{confirmationpanestateful/interfaces/IConfirmationPaneLocalizedText.js → citationpanestateful/interfaces/ICitationPaneStatefulProps.js} +0 -0
  50. /package/lib/esm/components/{confirmationpanestateful/interfaces/IConfirmationPaneLocalizedText.js → citationpanestateful/interfaces/ICitationPaneStatefulProps.js} +0 -0
  51. /package/lib/types/components/confirmationpanestateful/interfaces/{IConfirmationPaneLocalizedText.d.ts → IConfirmationPaneLocalizedTexts.d.ts} +0 -0
@@ -5,59 +5,127 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.createCitationsMiddleware = void 0;
7
7
  var _TelemetryConstants = require("../../../../../common/telemetry/TelemetryConstants");
8
+ var _LiveChatWidgetActionType = require("../../../../../contexts/common/LiveChatWidgetActionType");
8
9
  var _TelemetryHelper = require("../../../../../common/telemetry/TelemetryHelper");
9
- const createCitationsMiddleware = _ref => {
10
- let {
11
- dispatch
12
- } = _ref;
13
- return next => action => {
14
- var _action$payload;
15
- if ((_action$payload = action.payload) !== null && _action$payload !== void 0 && _action$payload.activity) {
16
- if (isApplicable(action)) {
10
+ var _createReducer = require("../../../../../contexts/createReducer");
11
+ // Middleware that extracts citation metadata from incoming ACS activities and
12
+ // updates in-memory app state with a global citation map. Also rewrites
13
+ // per-message citation labels in the activity text to use a stable,
14
+ // message-scoped prefix when the producer provides a message id.
15
+
16
+ const createCitationsMiddleware = (state, dispatch) => () => next => action => {
17
+ var _action$payload;
18
+ if ((_action$payload = action.payload) !== null && _action$payload !== void 0 && _action$payload.activity) {
19
+ if (isApplicable(action)) {
20
+ try {
21
+ var _action$payload2, _action$payload2$acti, _gptFeedback$summariz, _gptFeedback$summariz2;
22
+ const inMemoryState = (0, _createReducer.executeReducer)(state, {
23
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
24
+ payload: null
25
+ });
26
+
27
+ // Use the producer-supplied messageid as a stable per-message prefix
28
+ // when present. Do not derive a prefix from activity.id or timestamps.
29
+ const messagePrefix = ((_action$payload2 = action.payload) === null || _action$payload2 === void 0 ? void 0 : (_action$payload2$acti = _action$payload2.activity) === null || _action$payload2$acti === void 0 ? void 0 : _action$payload2$acti.messageid) ?? "";
30
+ const gptFeedback = JSON.parse(action.payload.activity.channelData.metadata["pva:gpt-feedback"]);
31
+ // Extract citation objects from the model response
32
+ const citations = (_gptFeedback$summariz = gptFeedback.summarizationOpenAIResponse) === null || _gptFeedback$summariz === void 0 ? void 0 : (_gptFeedback$summariz2 = _gptFeedback$summariz.result) === null || _gptFeedback$summariz2 === void 0 ? void 0 : _gptFeedback$summariz2.textCitations;
33
+ // Rewrite inline citation labels in activity.text to match the global map keys
34
+ const updatedText = replaceCitations(action.payload.activity.text, citations, messagePrefix);
35
+ action.payload.activity.text = updatedText;
36
+ // Build a global citation map keyed by the prefixed citation id and
37
+ // dispatch it to app state so the UI container can render citations.
17
38
  try {
18
- const gptFeedback = JSON.parse(action.payload.activity.channelData.metadata["pva:gpt-feedback"]);
19
- // Replace citations in the text
20
- const updatedText = replaceCitations(action.payload.activity.text, gptFeedback.summarizationOpenAIResponse.result.textCitations);
21
- action.payload.activity.text = updatedText;
22
- } catch (error) {
23
- _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
39
+ var _inMemoryState$domain;
40
+ const citationMap = {};
41
+ if (citations && Array.isArray(citations)) {
42
+ citations.forEach(citation => {
43
+ if (citation !== null && citation !== void 0 && citation.id) {
44
+ // Preserve the 'cite:' scheme so renderer click handling remains consistent
45
+ const idWithoutScheme = citation.id.replace(/^cite:/, "");
46
+ const prefixedId = `cite:${messagePrefix}_${idWithoutScheme}`;
47
+ citationMap[prefixedId] = citation.text || citation.title || "";
48
+ }
49
+ });
50
+ }
51
+
52
+ // Read current in-memory state to merge with existing citations
53
+ //const inMemoryState = executeReducer(state, { type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE, payload: null });
54
+ const existingCitations = (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain = inMemoryState.domainStates) === null || _inMemoryState$domain === void 0 ? void 0 : _inMemoryState$domain.citations) || {};
55
+ const updatedCitations = {
56
+ ...existingCitations,
57
+ ...citationMap
58
+ };
59
+ // Always dispatch to app state
60
+ dispatch({
61
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CITATIONS,
62
+ payload: updatedCitations
63
+ });
64
+ } catch (innerErr) {
65
+ _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.WARN, {
24
66
  Event: _TelemetryConstants.TelemetryEvent.CitationMiddlewareFailed,
25
67
  ExceptionDetails: {
26
- ErrorData: "Error while converting citation labels",
27
- Exception: error
68
+ ErrorData: "Error while populating citation map",
69
+ Exception: innerErr
28
70
  }
29
71
  });
30
72
  }
73
+ } catch (error) {
74
+ _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
75
+ Event: _TelemetryConstants.TelemetryEvent.CitationMiddlewareFailed,
76
+ ExceptionDetails: {
77
+ ErrorData: "Error while converting citation labels",
78
+ Exception: error
79
+ }
80
+ });
31
81
  }
32
82
  }
33
- return next(action);
34
- };
83
+ }
84
+ return next(action);
35
85
  };
36
86
  exports.createCitationsMiddleware = createCitationsMiddleware;
37
87
  const isApplicable = action => {
38
- var _action$payload2, _action$payload2$acti, _action$payload3, _action$payload3$acti;
39
- if ((action === null || action === void 0 ? void 0 : (_action$payload2 = action.payload) === null || _action$payload2 === void 0 ? void 0 : (_action$payload2$acti = _action$payload2.activity) === null || _action$payload2$acti === void 0 ? void 0 : _action$payload2$acti.actionType) === "DIRECT_LINE/INCOMING_ACTIVITY" && (action === null || action === void 0 ? void 0 : (_action$payload3 = action.payload) === null || _action$payload3 === void 0 ? void 0 : (_action$payload3$acti = _action$payload3.activity) === null || _action$payload3$acti === void 0 ? void 0 : _action$payload3$acti.channelId) === "ACS_CHANNEL") {
40
- var _action$payload4, _action$payload4$acti, _action$payload4$acti2, _action$payload4$acti3;
41
- // Validate if pva:gpt-feedback exists and is not null
42
- if (action !== null && action !== void 0 && (_action$payload4 = action.payload) !== null && _action$payload4 !== void 0 && (_action$payload4$acti = _action$payload4.activity) !== null && _action$payload4$acti !== void 0 && (_action$payload4$acti2 = _action$payload4$acti.channelData) !== null && _action$payload4$acti2 !== void 0 && (_action$payload4$acti3 = _action$payload4$acti2.metadata) !== null && _action$payload4$acti3 !== void 0 && _action$payload4$acti3["pva:gpt-feedback"]) {
88
+ var _action$payload3, _action$payload3$acti, _action$payload4, _action$payload4$acti;
89
+ if ((action === null || action === void 0 ? void 0 : (_action$payload3 = action.payload) === null || _action$payload3 === void 0 ? void 0 : (_action$payload3$acti = _action$payload3.activity) === null || _action$payload3$acti === void 0 ? void 0 : _action$payload3$acti.actionType) === "DIRECT_LINE/INCOMING_ACTIVITY" && (action === null || action === void 0 ? void 0 : (_action$payload4 = action.payload) === null || _action$payload4 === void 0 ? void 0 : (_action$payload4$acti = _action$payload4.activity) === null || _action$payload4$acti === void 0 ? void 0 : _action$payload4$acti.channelId) === "ACS_CHANNEL") {
90
+ var _action$payload5, _action$payload5$acti, _action$payload5$acti2, _action$payload5$acti3;
91
+ // Only applicable for ACS incoming activities that include pva:gpt-feedback
92
+ if (action !== null && action !== void 0 && (_action$payload5 = action.payload) !== null && _action$payload5 !== void 0 && (_action$payload5$acti = _action$payload5.activity) !== null && _action$payload5$acti !== void 0 && (_action$payload5$acti2 = _action$payload5$acti.channelData) !== null && _action$payload5$acti2 !== void 0 && (_action$payload5$acti3 = _action$payload5$acti2.metadata) !== null && _action$payload5$acti3 !== void 0 && _action$payload5$acti3["pva:gpt-feedback"]) {
43
93
  return true;
44
94
  }
45
95
  }
46
96
  return false;
47
97
  };
48
- const replaceCitations = (text, citations) => {
98
+ const replaceCitations = (text, citations, messagePrefix) => {
49
99
  if (!citations || !Array.isArray(citations)) {
50
100
  return text;
51
101
  }
52
102
  try {
53
- return text.replace(/\[(\d+)\]:\s(cite:\d+)\s"([^"]+)"/g, (match, number, citeId) => {
54
- const citation = citations.find(c => c.id === citeId);
103
+ let updatedText = text;
104
+
105
+ // First, handle the citation reference definitions at the end (e.g., [1]: cite:1757450535119_1 "index.html")
106
+ // These should NOT be escaped as they are proper citation definitions
107
+ updatedText = updatedText.replace(/\[(\d+)\]:\s(cite:\d+)\s"([^\\"]+)"/g, (match, number, citeId) => {
108
+ // Attempt to find a citation object matching the inline cite id and
109
+ // update the displayed id/title. When a messagePrefix exists we
110
+ // rewrite the id to the prefixed form so it aligns with the
111
+ // global citation map keys.
112
+ const lookupId = citeId;
113
+ const citation = citations.find(c => c.id === lookupId);
55
114
  if (citation) {
56
- // Replace only the citation label while preserving the original format
57
- return `[${number}]: ${citeId} "${citation.title}"`;
115
+ const idWithoutScheme = citeId.replace(/^cite:/, "");
116
+ const prefixed = messagePrefix ? `cite:${messagePrefix}_${idWithoutScheme}` : citeId;
117
+ return `[${number}]: ${prefixed} "${citation.title}"`;
58
118
  }
59
- return match; // Keep the original match if no replacement is found
119
+ return match;
120
+ });
121
+
122
+ // Second, escape inline citation references that are NOT followed by a colon
123
+ // This handles cases like "[1][2]"" in the middle of text that should be escaped for markdown
124
+ updatedText = updatedText.replace(/\[(\d+)\](?!:)/g, (match, number) => {
125
+ // Escape the brackets to prevent markdown from treating them as incomplete link syntax
126
+ return `[${number}]`;
60
127
  });
128
+ return updatedText;
61
129
  } catch (error) {
62
130
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
63
131
  Event: _TelemetryConstants.TelemetryEvent.CitationMiddlewareFailed,
@@ -66,7 +134,6 @@ const replaceCitations = (text, citations) => {
66
134
  Exception: error
67
135
  }
68
136
  });
69
- // Return the original text in case of issues
70
137
  return text;
71
138
  }
72
139
  };
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.localizedStringsBotInitialsMiddleware = exports.getOverriddenLocalizedStrings = void 0;
7
+ var _Constants = require("../../../../../common/Constants");
8
+ var _utils = require("../../../../../common/utils");
9
+ var _defaultWebChatStyles = require("../../../common/defaultStyles/defaultWebChatStyles");
10
+ var _WebChatActionType = require("../../enums/WebChatActionType");
11
+ /* eslint-disable @typescript-eslint/no-explicit-any */
12
+
13
+ let currentAgentInitials = _defaultWebChatStyles.defaultWebChatStyles.botAvatarInitials;
14
+ const localizedStringsBotInitialsMiddleware = () => _ref => {
15
+ let {
16
+ dispatch
17
+ } = _ref;
18
+ return next => action => {
19
+ if (action.type === _WebChatActionType.WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY) {
20
+ var _action$payload, _activity$from;
21
+ const activity = (_action$payload = action.payload) === null || _action$payload === void 0 ? void 0 : _action$payload.activity;
22
+ if (activity !== null && activity !== void 0 && (_activity$from = activity.from) !== null && _activity$from !== void 0 && _activity$from.name && activity.from.role !== _Constants.Constants.userMessageTag && activity.from.name !== _Constants.Constants.userMessageTag) {
23
+ var _activity$channelData, _activity$channelData2, _activity$tags;
24
+ const agentName = activity.from.name.trim();
25
+ const isSystemMessage = agentName === "__agent__" || agentName.startsWith("__") || ((_activity$channelData = activity.channelData) === null || _activity$channelData === void 0 ? void 0 : (_activity$channelData2 = _activity$channelData.tags) === null || _activity$channelData2 === void 0 ? void 0 : _activity$channelData2.includes(_Constants.Constants.systemMessageTag)) || ((_activity$tags = activity.tags) === null || _activity$tags === void 0 ? void 0 : _activity$tags.includes(_Constants.Constants.systemMessageTag));
26
+ if (!isSystemMessage && agentName !== "") {
27
+ // Update initials for valid agent/bot names
28
+ const newInitials = (0, _utils.getIconText)(agentName) || currentAgentInitials;
29
+ currentAgentInitials = newInitials;
30
+ }
31
+ }
32
+ }
33
+ return next(action);
34
+ };
35
+ };
36
+ exports.localizedStringsBotInitialsMiddleware = localizedStringsBotInitialsMiddleware;
37
+ const getOverriddenLocalizedStrings = existingOverrides => {
38
+ return strings => {
39
+ const result = {
40
+ ...strings,
41
+ ...existingOverrides
42
+ };
43
+
44
+ // Apply dynamic bot initials to alt text if not already overridden through props
45
+ if (!(existingOverrides !== null && existingOverrides !== void 0 && existingOverrides.ACTIVITY_BOT_SAID_ALT)) {
46
+ result.ACTIVITY_BOT_SAID_ALT = `${currentAgentInitials} said:`;
47
+ }
48
+ if (!(existingOverrides !== null && existingOverrides !== void 0 && existingOverrides.ACTIVITY_BOT_ATTACHED_ALT)) {
49
+ result.ACTIVITY_BOT_ATTACHED_ALT = `${currentAgentInitials} attached:`;
50
+ }
51
+ return result;
52
+ };
53
+ };
54
+ exports.getOverriddenLocalizedStrings = getOverriddenLocalizedStrings;
@@ -4,10 +4,10 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.createQueueOverflowMiddleware = void 0;
7
- var _WebChatActionType = require("../../enums/WebChatActionType");
8
7
  var _TelemetryConstants = require("../../../../../common/telemetry/TelemetryConstants");
9
- var _TelemetryHelper = require("../../../../../common/telemetry/TelemetryHelper");
10
8
  var _LiveChatWidgetActionType = require("../../../../../contexts/common/LiveChatWidgetActionType");
9
+ var _TelemetryHelper = require("../../../../../common/telemetry/TelemetryHelper");
10
+ var _WebChatActionType = require("../../enums/WebChatActionType");
11
11
  var _createReducer = require("../../../../../contexts/createReducer");
12
12
  var _utils = require("../../../../../common/utils");
13
13
  const queueOverflowHandlingHelper = async (state, dispatch) => {
@@ -10,49 +10,50 @@ exports.LiveChatWidgetActionType = LiveChatWidgetActionType;
10
10
  LiveChatWidgetActionType[LiveChatWidgetActionType["SET_WIDGET_ELEMENT_ID"] = 0] = "SET_WIDGET_ELEMENT_ID";
11
11
  LiveChatWidgetActionType[LiveChatWidgetActionType["SET_RENDERING_MIDDLEWARE_PROPS"] = 1] = "SET_RENDERING_MIDDLEWARE_PROPS";
12
12
  LiveChatWidgetActionType[LiveChatWidgetActionType["SET_MIDDLEWARE_LOCALIZED_TEXTS"] = 2] = "SET_MIDDLEWARE_LOCALIZED_TEXTS";
13
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_GLOBAL_DIR"] = 3] = "SET_GLOBAL_DIR";
14
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_MINIMIZED"] = 4] = "SET_MINIMIZED";
15
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CONVERSATION_STATE"] = 5] = "SET_CONVERSATION_STATE";
16
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_PREVIOUS_FOCUSED_ELEMENT_ID"] = 6] = "SET_PREVIOUS_FOCUSED_ELEMENT_ID";
17
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_START_CHAT_FAILING"] = 7] = "SET_START_CHAT_FAILING";
18
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_START_CHAT_FAILURE_TYPE"] = 8] = "SET_START_CHAT_FAILURE_TYPE";
19
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_OUTSIDE_OPERATING_HOURS"] = 9] = "SET_OUTSIDE_OPERATING_HOURS";
20
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_PRE_CHAT_SURVEY_RESPONSE"] = 10] = "SET_PRE_CHAT_SURVEY_RESPONSE";
21
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CUSTOM_CONTEXT"] = 11] = "SET_CUSTOM_CONTEXT";
22
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_SHOW_CONFIRMATION"] = 12] = "SET_SHOW_CONFIRMATION";
23
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_SHOW_EMAIL_TRANSCRIPT_PANE"] = 13] = "SET_SHOW_EMAIL_TRANSCRIPT_PANE";
24
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_PRECHAT_RESPONSE_EMAIL"] = 14] = "SET_PRECHAT_RESPONSE_EMAIL";
25
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_AUDIO_NOTIFICATION"] = 15] = "SET_AUDIO_NOTIFICATION";
26
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_E2VV_ENABLED"] = 16] = "SET_E2VV_ENABLED";
27
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_POST_CHAT_CONTEXT"] = 17] = "SET_POST_CHAT_CONTEXT";
28
- LiveChatWidgetActionType[LiveChatWidgetActionType["SHOW_CALLING_CONTAINER"] = 18] = "SHOW_CALLING_CONTAINER";
29
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_INCOMING_CALL"] = 19] = "SET_INCOMING_CALL";
30
- LiveChatWidgetActionType[LiveChatWidgetActionType["DISABLE_VIDEO_CALL"] = 20] = "DISABLE_VIDEO_CALL";
31
- LiveChatWidgetActionType[LiveChatWidgetActionType["DISABLE_LOCAL_VIDEO"] = 21] = "DISABLE_LOCAL_VIDEO";
32
- LiveChatWidgetActionType[LiveChatWidgetActionType["DISABLE_REMOTE_VIDEO"] = 22] = "DISABLE_REMOTE_VIDEO";
33
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CHAT_TOKEN"] = 23] = "SET_CHAT_TOKEN";
34
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_START_CHAT_BUTTON_DISPLAY"] = 24] = "SET_START_CHAT_BUTTON_DISPLAY";
35
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_PROACTIVE_CHAT_PARAMS"] = 25] = "SET_PROACTIVE_CHAT_PARAMS";
36
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_TELEMETRY_DATA"] = 26] = "SET_TELEMETRY_DATA";
37
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_RECONNECT_ID"] = 27] = "SET_RECONNECT_ID";
38
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_UNREAD_MESSAGE_COUNT"] = 28] = "SET_UNREAD_MESSAGE_COUNT";
39
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_FOCUS_CHAT_BUTTON"] = 29] = "SET_FOCUS_CHAT_BUTTON";
40
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CONVERSATION_ENDED_BY_AGENT_EVENT_RECEIVED"] = 30] = "SET_CONVERSATION_ENDED_BY_AGENT_EVENT_RECEIVED";
41
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CONVERSATION_ENDED_BY"] = 31] = "SET_CONVERSATION_ENDED_BY";
42
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_WIDGET_STATE"] = 32] = "SET_WIDGET_STATE";
43
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_LIVE_CHAT_CONTEXT"] = 33] = "SET_LIVE_CHAT_CONTEXT";
44
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_BOT_OAUTH_SIGNIN_ID"] = 34] = "SET_BOT_OAUTH_SIGNIN_ID";
45
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_WIDGET_SIZE"] = 35] = "SET_WIDGET_SIZE";
46
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_WIDGET_INSTANCE_ID"] = 36] = "SET_WIDGET_INSTANCE_ID";
47
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_LIVE_CHAT_CONFIG"] = 37] = "SET_LIVE_CHAT_CONFIG";
48
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_POST_CHAT_WORKFLOW_IN_PROGRESS"] = 38] = "SET_POST_CHAT_WORKFLOW_IN_PROGRESS";
49
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_INITIAL_CHAT_SDK_REQUEST_ID"] = 39] = "SET_INITIAL_CHAT_SDK_REQUEST_ID";
50
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_SHOULD_USE_BOT_SURVEY"] = 40] = "SET_SHOULD_USE_BOT_SURVEY";
51
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CHAT_DISCONNECT_EVENT_RECEIVED"] = 41] = "SET_CHAT_DISCONNECT_EVENT_RECEIVED";
52
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_SURVEY_MODE"] = 42] = "SET_SURVEY_MODE";
53
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CONFIRMATION_STATE"] = 43] = "SET_CONFIRMATION_STATE";
54
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_POST_CHAT_PARTICIPANT_TYPE"] = 44] = "SET_POST_CHAT_PARTICIPANT_TYPE";
55
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CONVERSATIONAL_SURVEY_ENABLED"] = 45] = "SET_CONVERSATIONAL_SURVEY_ENABLED";
56
- LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CONVERSATIONAL_SURVEY_DISPLAY"] = 46] = "SET_CONVERSATIONAL_SURVEY_DISPLAY";
57
- LiveChatWidgetActionType[LiveChatWidgetActionType["GET_IN_MEMORY_STATE"] = 47] = "GET_IN_MEMORY_STATE";
13
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CITATIONS"] = 3] = "SET_CITATIONS";
14
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_GLOBAL_DIR"] = 4] = "SET_GLOBAL_DIR";
15
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_MINIMIZED"] = 5] = "SET_MINIMIZED";
16
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CONVERSATION_STATE"] = 6] = "SET_CONVERSATION_STATE";
17
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_PREVIOUS_FOCUSED_ELEMENT_ID"] = 7] = "SET_PREVIOUS_FOCUSED_ELEMENT_ID";
18
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_START_CHAT_FAILING"] = 8] = "SET_START_CHAT_FAILING";
19
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_START_CHAT_FAILURE_TYPE"] = 9] = "SET_START_CHAT_FAILURE_TYPE";
20
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_OUTSIDE_OPERATING_HOURS"] = 10] = "SET_OUTSIDE_OPERATING_HOURS";
21
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_PRE_CHAT_SURVEY_RESPONSE"] = 11] = "SET_PRE_CHAT_SURVEY_RESPONSE";
22
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CUSTOM_CONTEXT"] = 12] = "SET_CUSTOM_CONTEXT";
23
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_SHOW_CONFIRMATION"] = 13] = "SET_SHOW_CONFIRMATION";
24
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_SHOW_EMAIL_TRANSCRIPT_PANE"] = 14] = "SET_SHOW_EMAIL_TRANSCRIPT_PANE";
25
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_PRECHAT_RESPONSE_EMAIL"] = 15] = "SET_PRECHAT_RESPONSE_EMAIL";
26
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_AUDIO_NOTIFICATION"] = 16] = "SET_AUDIO_NOTIFICATION";
27
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_E2VV_ENABLED"] = 17] = "SET_E2VV_ENABLED";
28
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_POST_CHAT_CONTEXT"] = 18] = "SET_POST_CHAT_CONTEXT";
29
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SHOW_CALLING_CONTAINER"] = 19] = "SHOW_CALLING_CONTAINER";
30
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_INCOMING_CALL"] = 20] = "SET_INCOMING_CALL";
31
+ LiveChatWidgetActionType[LiveChatWidgetActionType["DISABLE_VIDEO_CALL"] = 21] = "DISABLE_VIDEO_CALL";
32
+ LiveChatWidgetActionType[LiveChatWidgetActionType["DISABLE_LOCAL_VIDEO"] = 22] = "DISABLE_LOCAL_VIDEO";
33
+ LiveChatWidgetActionType[LiveChatWidgetActionType["DISABLE_REMOTE_VIDEO"] = 23] = "DISABLE_REMOTE_VIDEO";
34
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CHAT_TOKEN"] = 24] = "SET_CHAT_TOKEN";
35
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_START_CHAT_BUTTON_DISPLAY"] = 25] = "SET_START_CHAT_BUTTON_DISPLAY";
36
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_PROACTIVE_CHAT_PARAMS"] = 26] = "SET_PROACTIVE_CHAT_PARAMS";
37
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_TELEMETRY_DATA"] = 27] = "SET_TELEMETRY_DATA";
38
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_RECONNECT_ID"] = 28] = "SET_RECONNECT_ID";
39
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_UNREAD_MESSAGE_COUNT"] = 29] = "SET_UNREAD_MESSAGE_COUNT";
40
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_FOCUS_CHAT_BUTTON"] = 30] = "SET_FOCUS_CHAT_BUTTON";
41
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CONVERSATION_ENDED_BY_AGENT_EVENT_RECEIVED"] = 31] = "SET_CONVERSATION_ENDED_BY_AGENT_EVENT_RECEIVED";
42
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CONVERSATION_ENDED_BY"] = 32] = "SET_CONVERSATION_ENDED_BY";
43
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_WIDGET_STATE"] = 33] = "SET_WIDGET_STATE";
44
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_LIVE_CHAT_CONTEXT"] = 34] = "SET_LIVE_CHAT_CONTEXT";
45
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_BOT_OAUTH_SIGNIN_ID"] = 35] = "SET_BOT_OAUTH_SIGNIN_ID";
46
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_WIDGET_SIZE"] = 36] = "SET_WIDGET_SIZE";
47
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_WIDGET_INSTANCE_ID"] = 37] = "SET_WIDGET_INSTANCE_ID";
48
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_LIVE_CHAT_CONFIG"] = 38] = "SET_LIVE_CHAT_CONFIG";
49
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_POST_CHAT_WORKFLOW_IN_PROGRESS"] = 39] = "SET_POST_CHAT_WORKFLOW_IN_PROGRESS";
50
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_INITIAL_CHAT_SDK_REQUEST_ID"] = 40] = "SET_INITIAL_CHAT_SDK_REQUEST_ID";
51
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_SHOULD_USE_BOT_SURVEY"] = 41] = "SET_SHOULD_USE_BOT_SURVEY";
52
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CHAT_DISCONNECT_EVENT_RECEIVED"] = 42] = "SET_CHAT_DISCONNECT_EVENT_RECEIVED";
53
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_SURVEY_MODE"] = 43] = "SET_SURVEY_MODE";
54
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CONFIRMATION_STATE"] = 44] = "SET_CONFIRMATION_STATE";
55
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_POST_CHAT_PARTICIPANT_TYPE"] = 45] = "SET_POST_CHAT_PARTICIPANT_TYPE";
56
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CONVERSATIONAL_SURVEY_ENABLED"] = 46] = "SET_CONVERSATIONAL_SURVEY_ENABLED";
57
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CONVERSATIONAL_SURVEY_DISPLAY"] = 47] = "SET_CONVERSATIONAL_SURVEY_DISPLAY";
58
+ LiveChatWidgetActionType[LiveChatWidgetActionType["GET_IN_MEMORY_STATE"] = 48] = "GET_IN_MEMORY_STATE";
58
59
  })(LiveChatWidgetActionType || (exports.LiveChatWidgetActionType = LiveChatWidgetActionType = {}));
@@ -45,6 +45,8 @@ const getLiveChatWidgetContextInitialState = props => {
45
45
  domainStates: {
46
46
  liveChatConfig: props.chatConfig,
47
47
  widgetElementId: "",
48
+ // Map of citation id => content injected by citations middleware
49
+ citations: {},
48
50
  renderingMiddlewareProps: (_props$webChatContain = props.webChatContainerProps) === null || _props$webChatContain === void 0 ? void 0 : _props$webChatContain.renderingMiddlewareProps,
49
51
  middlewareLocalizedTexts: _defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts,
50
52
  preChatSurveyResponse: "{}",
@@ -70,6 +70,21 @@ const reducer = (state, action) => {
70
70
  middlewareLocalizedTexts: action.payload
71
71
  }
72
72
  };
73
+ case _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CITATIONS:
74
+ inMemory = {
75
+ ...inMemory,
76
+ domainStates: {
77
+ ...inMemory.domainStates,
78
+ citations: action.payload
79
+ }
80
+ };
81
+ return {
82
+ ...state,
83
+ domainStates: {
84
+ ...state.domainStates,
85
+ citations: action.payload
86
+ }
87
+ };
73
88
  case _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_GLOBAL_DIR:
74
89
  inMemory = {
75
90
  ...inMemory,
@@ -184,6 +184,8 @@ _defineProperty(HtmlAttributeNames, "adaptiveCardClassName", "ac-adaptiveCard");
184
184
  _defineProperty(HtmlAttributeNames, "adaptiveCardTextBlockClassName", "ac-textBlock");
185
185
  _defineProperty(HtmlAttributeNames, "adaptiveCardToggleInputClassName", "ac-toggleInput");
186
186
  _defineProperty(HtmlAttributeNames, "adaptiveCardActionSetClassName", "ac-actionSet");
187
+ _defineProperty(HtmlAttributeNames, "ocwCitationPaneClassName", "ocw-citation-pane");
188
+ _defineProperty(HtmlAttributeNames, "ocwCitationPaneTitle", "Citation");
187
189
  export let WebChatMiddlewareConstants = /*#__PURE__*/_createClass(function WebChatMiddlewareConstants() {
188
190
  _classCallCheck(this, WebChatMiddlewareConstants);
189
191
  });
@@ -148,6 +148,7 @@ export let TelemetryEvent;
148
148
  TelemetryEvent["EmailTranscriptLoaded"] = "EmailTranscriptLoaded";
149
149
  TelemetryEvent["OutOfOfficePaneLoaded"] = "OutOfOfficePaneLoaded";
150
150
  TelemetryEvent["ConfirmationPaneLoaded"] = "ConfirmationPaneLoaded";
151
+ TelemetryEvent["CitationPaneLoaded"] = "CitationPaneLoaded";
151
152
  TelemetryEvent["ProactiveChatPaneLoaded"] = "ProactiveChatPaneLoaded";
152
153
  TelemetryEvent["ReconnectChatPaneLoaded"] = "ReconnectChatPaneLoaded";
153
154
  TelemetryEvent["HeaderCloseButtonClicked"] = "HeaderCloseButtonClicked";
@@ -274,7 +275,9 @@ export let TelemetryEvent;
274
275
  TelemetryEvent["UXLCWChatButtonLoadingStart"] = "UXLCWChatButtonLoadingStart";
275
276
  TelemetryEvent["UXLCWChatButtonLoadingCompleted"] = "UXLCWChatButtonLoadingCompleted";
276
277
  TelemetryEvent["UXConfirmationPaneStart"] = "UXConfirmationPaneStart";
278
+ TelemetryEvent["UXCitationPaneStart"] = "UXCitationPaneStart";
277
279
  TelemetryEvent["UXConfirmationPaneCompleted"] = "UXConfirmationPaneCompleted";
280
+ TelemetryEvent["UXCitationPaneCompleted"] = "UXCitationPaneCompleted";
278
281
  TelemetryEvent["UXLiveChatWidgetStart"] = "UXLiveChatWidgetStart";
279
282
  TelemetryEvent["UXLiveChatWidgetCompleted"] = "UXLiveChatWidgetCompleted";
280
283
  TelemetryEvent["AppInsightsInitialized"] = "AppInsightsInitialized";
@@ -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;
@@ -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
+ };