@microsoft/omnichannel-chat-widget 1.0.3-main.527b216 → 1.0.3-main.c925679

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 (91) hide show
  1. package/lib/cjs/common/Constants.js +54 -1
  2. package/lib/cjs/common/storage/default/defaultCacheManager.js +7 -6
  3. package/lib/cjs/common/storage/default/defaultClientDataStoreProvider.js +9 -7
  4. package/lib/cjs/common/telemetry/TelemetryConstants.js +6 -0
  5. package/lib/cjs/common/utils.js +27 -5
  6. package/lib/cjs/components/confirmationpanestateful/ConfirmationPaneStateful.js +8 -6
  7. package/lib/cjs/components/footerstateful/FooterStateful.js +1 -1
  8. package/lib/cjs/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +8 -1
  9. package/lib/cjs/components/headerstateful/HeaderStateful.js +14 -13
  10. package/lib/cjs/components/livechatwidget/common/ActivitySubscriber/DefaultActivitySubscriber.js +1 -0
  11. package/lib/cjs/components/livechatwidget/common/ActivitySubscriber/PauseActivitySubscriber.js +1 -0
  12. package/lib/cjs/components/livechatwidget/common/Deferred.js +2 -3
  13. package/lib/cjs/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +2 -1
  14. package/lib/cjs/components/livechatwidget/common/endChat.js +197 -99
  15. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +29 -27
  16. package/lib/cjs/components/livechatwidget/common/reconnectChatHelper.js +11 -8
  17. package/lib/cjs/components/livechatwidget/common/renderSurveyHelpers.js +139 -0
  18. package/lib/cjs/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +2 -255
  19. package/lib/cjs/components/livechatwidget/common/startChat.js +70 -57
  20. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +162 -100
  21. package/lib/cjs/components/loadingpanestateful/LoadingPaneStateful.js +2 -2
  22. package/lib/cjs/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +15 -5
  23. package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +5 -4
  24. package/lib/cjs/components/reconnectchatpanestateful/ReconnectChatPaneStateful.js +4 -1
  25. package/lib/cjs/components/webchatcontainerstateful/common/mockchatsdk.js +6 -1
  26. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/WebChatStoreLoader.js +1 -0
  27. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware.js +8 -6
  28. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/webchattelemetry/WebChatLogger.js +7 -1
  29. package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +2 -0
  30. package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +16 -13
  31. package/lib/cjs/contexts/createReducer.js +13 -23
  32. package/lib/cjs/controller/componentController.js +2 -1
  33. package/lib/cjs/index.js +20 -0
  34. package/lib/esm/common/Constants.js +49 -0
  35. package/lib/esm/common/storage/default/defaultCacheManager.js +5 -4
  36. package/lib/esm/common/storage/default/defaultClientDataStoreProvider.js +9 -7
  37. package/lib/esm/common/telemetry/TelemetryConstants.js +6 -0
  38. package/lib/esm/common/utils.js +25 -4
  39. package/lib/esm/components/confirmationpanestateful/ConfirmationPaneStateful.js +8 -6
  40. package/lib/esm/components/footerstateful/FooterStateful.js +1 -1
  41. package/lib/esm/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +8 -1
  42. package/lib/esm/components/headerstateful/HeaderStateful.js +14 -13
  43. package/lib/esm/components/livechatwidget/common/ActivitySubscriber/DefaultActivitySubscriber.js +1 -0
  44. package/lib/esm/components/livechatwidget/common/ActivitySubscriber/PauseActivitySubscriber.js +1 -0
  45. package/lib/esm/components/livechatwidget/common/Deferred.js +2 -3
  46. package/lib/esm/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +2 -1
  47. package/lib/esm/components/livechatwidget/common/endChat.js +196 -99
  48. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +29 -27
  49. package/lib/esm/components/livechatwidget/common/reconnectChatHelper.js +11 -8
  50. package/lib/esm/components/livechatwidget/common/renderSurveyHelpers.js +130 -0
  51. package/lib/esm/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +3 -255
  52. package/lib/esm/components/livechatwidget/common/startChat.js +71 -58
  53. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +164 -102
  54. package/lib/esm/components/loadingpanestateful/LoadingPaneStateful.js +2 -2
  55. package/lib/esm/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +15 -5
  56. package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +5 -4
  57. package/lib/esm/components/reconnectchatpanestateful/ReconnectChatPaneStateful.js +4 -1
  58. package/lib/esm/components/webchatcontainerstateful/common/mockchatsdk.js +6 -1
  59. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/WebChatStoreLoader.js +1 -0
  60. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware.js +8 -6
  61. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/webchattelemetry/WebChatLogger.js +7 -1
  62. package/lib/esm/contexts/common/LiveChatWidgetActionType.js +2 -0
  63. package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +18 -15
  64. package/lib/esm/contexts/createReducer.js +13 -23
  65. package/lib/esm/controller/componentController.js +2 -1
  66. package/lib/esm/index.js +4 -1
  67. package/lib/types/common/Constants.d.ts +21 -0
  68. package/lib/types/common/interfaces/IContextDataStore.d.ts +3 -3
  69. package/lib/types/common/storage/default/defaultCacheManager.d.ts +2 -1
  70. package/lib/types/common/storage/default/defaultClientDataStoreProvider.d.ts +2 -1
  71. package/lib/types/common/telemetry/TelemetryConstants.d.ts +6 -0
  72. package/lib/types/common/utils.d.ts +3 -2
  73. package/lib/types/components/confirmationpanestateful/interfaces/IConfirmationPaneStatefulParams.d.ts +6 -0
  74. package/lib/types/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.d.ts +2 -1
  75. package/lib/types/components/livechatwidget/common/endChat.d.ts +4 -3
  76. package/lib/types/components/livechatwidget/common/initWebChatComposer.d.ts +1 -1
  77. package/lib/types/components/livechatwidget/common/renderSurveyHelpers.d.ts +9 -0
  78. package/lib/types/components/livechatwidget/common/setPostChatContextAndLoadSurvey.d.ts +1 -6
  79. package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetProps.d.ts +3 -1
  80. package/lib/types/components/webchatcontainerstateful/common/mockchatsdk.d.ts +4 -0
  81. package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +8 -7
  82. package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +3 -1
  83. package/lib/types/contexts/common/LiveChatWidgetContextInitialState.d.ts +2 -1
  84. package/lib/types/index.d.ts +3 -0
  85. package/package.json +2 -1
  86. package/lib/cjs/components/livechatwidget/common/agentEndConversationHelper.js +0 -36
  87. package/lib/cjs/contexts/common/ConversationEndEntity.js +0 -12
  88. package/lib/esm/components/livechatwidget/common/agentEndConversationHelper.js +0 -30
  89. package/lib/esm/contexts/common/ConversationEndEntity.js +0 -5
  90. package/lib/types/components/livechatwidget/common/agentEndConversationHelper.d.ts +0 -6
  91. package/lib/types/contexts/common/ConversationEndEntity.d.ts +0 -4
@@ -258,7 +258,11 @@ export const getDomain = hostValue => {
258
258
  }
259
259
  return AriaTelemetryConstants.Public;
260
260
  };
261
- export const getWidgetCacheId = (orgId, widgetId, widgetInstanceId) => {
261
+ export const getWidgetCacheId = function (orgId, widgetId, widgetInstanceId) {
262
+ let popoutChat = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
263
+ if (popoutChat) {
264
+ widgetInstanceId = widgetInstanceId + Constants.PopoutCacheSuffix;
265
+ }
262
266
  const widgetCacheId = `${widgetInstanceId}_${orgId}_${widgetId}`;
263
267
  return Md5.init(widgetCacheId);
264
268
  };
@@ -270,13 +274,13 @@ export const getWidgetEndChatEventName = (orgId, widgetId, widgetInstanceId) =>
270
274
  };
271
275
 
272
276
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
273
- export const getStateFromCache = (orgId, widgetId, widgetInstanceId) => {
277
+ export const getStateFromCache = widgetCacheId => {
274
278
  // Getting updated state from cache
275
279
  try {
276
280
  if (DataStoreManager.clientDataStore) {
277
281
  var _DataStoreManager$cli;
278
- const widgetStateEventName = getWidgetCacheId(orgId, widgetId, widgetInstanceId);
279
- const widgetStateFromCache = (_DataStoreManager$cli = DataStoreManager.clientDataStore) === null || _DataStoreManager$cli === void 0 ? void 0 : _DataStoreManager$cli.getData(widgetStateEventName, "localStorage");
282
+ const widgetStateEventName = widgetCacheId;
283
+ const widgetStateFromCache = (_DataStoreManager$cli = DataStoreManager.clientDataStore) === null || _DataStoreManager$cli === void 0 ? void 0 : _DataStoreManager$cli.getData(widgetStateEventName);
280
284
  const persistedState = widgetStateFromCache ? JSON.parse(widgetStateFromCache) : undefined;
281
285
  return persistedState;
282
286
  } else {
@@ -308,6 +312,23 @@ export const getBroadcastChannelName = (widgetId, widgetInstanceId) => {
308
312
  return widgetInstanceId && !isNullOrEmptyString(widgetInstanceId) ? `${widgetInstanceId}_${widgetId}` : widgetId;
309
313
  };
310
314
 
315
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
316
+ export const getWidgetCacheIdfromProps = function (props) {
317
+ var _props$chatSDK, _props$chatSDK$omnich, _props$chatSDK2, _props$chatSDK2$omnic, _props$controlProps, _props$controlProps2;
318
+ let popoutChat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
319
+ const orgId = props === null || props === void 0 ? void 0 : (_props$chatSDK = props.chatSDK) === null || _props$chatSDK === void 0 ? void 0 : (_props$chatSDK$omnich = _props$chatSDK.omnichannelConfig) === null || _props$chatSDK$omnich === void 0 ? void 0 : _props$chatSDK$omnich.orgId;
320
+ const widgetId = props === null || props === void 0 ? void 0 : (_props$chatSDK2 = props.chatSDK) === null || _props$chatSDK2 === void 0 ? void 0 : (_props$chatSDK2$omnic = _props$chatSDK2.omnichannelConfig) === null || _props$chatSDK2$omnic === void 0 ? void 0 : _props$chatSDK2$omnic.widgetId;
321
+ let widgetInstanceId = (props === null || props === void 0 ? void 0 : (_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.widgetInstanceId) ?? "";
322
+ if (props.useSessionStorage) {
323
+ widgetInstanceId = widgetInstanceId + Constants.SessionCacheSuffix;
324
+ }
325
+ if (props !== null && props !== void 0 && (_props$controlProps2 = props.controlProps) !== null && _props$controlProps2 !== void 0 && _props$controlProps2.hideStartChatButton || popoutChat === true) {
326
+ popoutChat = true;
327
+ }
328
+ const widgetCacheId = getWidgetCacheId(orgId, widgetId, widgetInstanceId, popoutChat);
329
+ return widgetCacheId;
330
+ };
331
+
311
332
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
312
333
  export const debounceLeading = function (fn) {
313
334
  let ms = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 3000;
@@ -5,9 +5,8 @@ import { findAllFocusableElement, findParentFocusableElementsWithoutChildContain
5
5
  import { DimLayer } from "../dimlayer/DimLayer";
6
6
  import { LiveChatWidgetActionType } from "../../contexts/common/LiveChatWidgetActionType";
7
7
  import { TelemetryHelper } from "../../common/telemetry/TelemetryHelper";
8
- import useChatAdapterStore from "../../hooks/useChatAdapterStore";
9
8
  import useChatContextStore from "../../hooks/useChatContextStore";
10
- import { ConversationEndEntity } from "../../contexts/common/ConversationEndEntity";
9
+ import { ConfirmationState } from "../../common/Constants";
11
10
 
12
11
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
12
  export const ConfirmationPaneStateful = props => {
@@ -15,7 +14,6 @@ export const ConfirmationPaneStateful = props => {
15
14
  let elements = [];
16
15
  const [state, dispatch] = useChatContextStore();
17
16
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
18
- const [adapter] = useChatAdapterStore();
19
17
  const controlProps = {
20
18
  id: "oc-lcw-confirmation-pane",
21
19
  dir: state.domainStates.globalDir,
@@ -28,11 +26,11 @@ export const ConfirmationPaneStateful = props => {
28
26
  type: LiveChatWidgetActionType.SET_SHOW_CONFIRMATION,
29
27
  payload: false
30
28
  });
31
- setTabIndices(elements, initialTabIndexMap, true);
32
29
  dispatch({
33
- type: LiveChatWidgetActionType.SET_CONVERSATION_ENDED_BY,
34
- payload: ConversationEndEntity.Customer
30
+ type: LiveChatWidgetActionType.SET_CONFIRMATION_STATE,
31
+ payload: ConfirmationState.Ok
35
32
  });
33
+ setTabIndices(elements, initialTabIndexMap, true);
36
34
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
37
35
  Event: TelemetryEvent.ConversationEndedByCustomer,
38
36
  Description: "Conversation is ended by customer."
@@ -47,6 +45,10 @@ export const ConfirmationPaneStateful = props => {
47
45
  type: LiveChatWidgetActionType.SET_SHOW_CONFIRMATION,
48
46
  payload: false
49
47
  });
48
+ dispatch({
49
+ type: LiveChatWidgetActionType.SET_CONFIRMATION_STATE,
50
+ payload: ConfirmationState.Cancel
51
+ });
50
52
  const previousFocusedElementId = state.appStates.previousElementIdOnFocusBeforeModalOpen;
51
53
  if (previousFocusedElementId) {
52
54
  setFocusOnElement("#" + previousFocusedElementId);
@@ -36,7 +36,7 @@ export const FooterStateful = props => {
36
36
  Event: TelemetryEvent.DownloadTranscriptButtonClicked,
37
37
  Description: "Download Transcript button clicked."
38
38
  });
39
- await downloadTranscript(chatSDK, downloadTranscriptProps === null || downloadTranscriptProps === void 0 ? void 0 : downloadTranscriptProps.renderMarkDown, downloadTranscriptProps === null || downloadTranscriptProps === void 0 ? void 0 : downloadTranscriptProps.bannerMessageOnError, downloadTranscriptProps === null || downloadTranscriptProps === void 0 ? void 0 : downloadTranscriptProps.attachmentMessage);
39
+ await downloadTranscript(chatSDK, downloadTranscriptProps === null || downloadTranscriptProps === void 0 ? void 0 : downloadTranscriptProps.renderMarkDown, downloadTranscriptProps === null || downloadTranscriptProps === void 0 ? void 0 : downloadTranscriptProps.bannerMessageOnError, downloadTranscriptProps === null || downloadTranscriptProps === void 0 ? void 0 : downloadTranscriptProps.attachmentMessage, state);
40
40
  } catch (ex) {
41
41
  TelemetryHelper.logActionEvent(LogLevel.ERROR, {
42
42
  Event: TelemetryEvent.DownloadTranscriptFailed,
@@ -151,8 +151,15 @@ const beautifyChatTranscripts = (chatTranscripts, renderMarkDown, attachmentMess
151
151
  };
152
152
 
153
153
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
154
- export const downloadTranscript = async (chatSDK, renderMarkDown, bannerMessageOnError, attachmentMessage) => {
154
+ export const downloadTranscript = async (chatSDK, renderMarkDown, bannerMessageOnError, attachmentMessage, state) => {
155
+ var _state$domainStates, _state$domainStates2, _state$domainStates2$;
156
+ // Need to keep existing request id for scenarios when trnascript is downloaded after endchat
157
+ const existingRequestId = chatSDK.requestId;
158
+ chatSDK.chatToken = state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : _state$domainStates.chatToken;
159
+ chatSDK.requestId = state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : (_state$domainStates2$ = _state$domainStates2.chatToken) === null || _state$domainStates2$ === void 0 ? void 0 : _state$domainStates2$.requestId;
155
160
  let data = await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.getLiveChatTranscript());
161
+ // This is used for allowing to start next chat
162
+ chatSDK.requestId = existingRequestId;
156
163
  if (typeof data === Constants.String) {
157
164
  data = JSON.parse(data);
158
165
  }
@@ -7,9 +7,9 @@ import { TelemetryHelper } from "../../common/telemetry/TelemetryHelper";
7
7
  import { defaultOutOfOfficeHeaderStyleProps } from "./common/styleProps/defaultOutOfOfficeHeaderStyleProps";
8
8
  import useChatAdapterStore from "../../hooks/useChatAdapterStore";
9
9
  import useChatContextStore from "../../hooks/useChatContextStore";
10
- import { ConversationEndEntity } from "../../contexts/common/ConversationEndEntity";
10
+ import { ConfirmationState } from "../../common/Constants";
11
11
  export const HeaderStateful = props => {
12
- var _state$domainStates$l, _state$domainStates$l2, _headerProps$controlP, _headerProps$controlP2, _headerProps$controlP3, _outOfOfficeHeaderPro;
12
+ var _state$domainStates$l, _state$domainStates$l2, _state$domainStates, _headerProps$controlP, _headerProps$controlP2, _headerProps$controlP3, _outOfOfficeHeaderPro, _state$domainStates3;
13
13
  const [state, dispatch] = useChatContextStore();
14
14
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
15
  const [adapter] = useChatAdapterStore();
@@ -21,8 +21,9 @@ export const HeaderStateful = props => {
21
21
  //Setting OutOfOperatingHours Flag
22
22
  const [outOfOperatingHours, setOutOfOperatingHours] = useState(((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : (_state$domainStates$l2 = _state$domainStates$l.LiveWSAndLiveChatEngJoin) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.OutOfOperatingHours) === "True");
23
23
  const outOfOfficeStyleProps = Object.assign({}, defaultOutOfOfficeHeaderStyleProps, outOfOfficeHeaderProps === null || outOfOfficeHeaderProps === void 0 ? void 0 : outOfOfficeHeaderProps.styleProps);
24
- const conversationState = useRef(state.appStates.conversationState);
25
- const conversationEndedBy = useRef(state.appStates.conversationEndedBy);
24
+
25
+ // For some reason state object is not getting updated values in this component
26
+ const localConfirmationPaneState = useRef(state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : _state$domainStates.confirmationState);
26
27
  const controlProps = {
27
28
  id: "oc-lcw-header",
28
29
  dir: state.domainStates.globalDir,
@@ -42,7 +43,7 @@ export const HeaderStateful = props => {
42
43
  Event: TelemetryEvent.HeaderCloseButtonClicked,
43
44
  Description: "Header Close button clicked."
44
45
  });
45
- if (conversationState.current === ConversationState.Active || conversationEndedBy.current === ConversationEndEntity.Agent) {
46
+ if (localConfirmationPaneState.current !== ConfirmationState.Ok) {
46
47
  dispatch({
47
48
  type: LiveChatWidgetActionType.SET_SHOW_CONFIRMATION,
48
49
  payload: true
@@ -62,9 +63,9 @@ export const HeaderStateful = props => {
62
63
  }
63
64
  },
64
65
  ...(headerProps === null || headerProps === void 0 ? void 0 : headerProps.controlProps),
65
- hideTitle: state.appStates.conversationState === ConversationState.Loading && !state.appStates.isStartChatFailing || state.appStates.conversationState === ConversationState.PostchatLoading || (headerProps === null || headerProps === void 0 ? void 0 : (_headerProps$controlP = headerProps.controlProps) === null || _headerProps$controlP === void 0 ? void 0 : _headerProps$controlP.hideTitle),
66
- hideIcon: state.appStates.conversationState === ConversationState.Loading && !state.appStates.isStartChatFailing || state.appStates.conversationState === ConversationState.PostchatLoading || (headerProps === null || headerProps === void 0 ? void 0 : (_headerProps$controlP2 = headerProps.controlProps) === null || _headerProps$controlP2 === void 0 ? void 0 : _headerProps$controlP2.hideIcon),
67
- hideCloseButton: state.appStates.conversationState === ConversationState.Loading && !state.appStates.isStartChatFailing || state.appStates.conversationState === ConversationState.PostchatLoading || state.appStates.conversationState === ConversationState.Prechat || state.appStates.conversationState === ConversationState.ReconnectChat || (headerProps === null || headerProps === void 0 ? void 0 : (_headerProps$controlP3 = headerProps.controlProps) === null || _headerProps$controlP3 === void 0 ? void 0 : _headerProps$controlP3.hideCloseButton)
66
+ hideTitle: state.appStates.conversationState === ConversationState.Loading && !state.appStates.startChatFailed || state.appStates.conversationState === ConversationState.PostchatLoading || (headerProps === null || headerProps === void 0 ? void 0 : (_headerProps$controlP = headerProps.controlProps) === null || _headerProps$controlP === void 0 ? void 0 : _headerProps$controlP.hideTitle),
67
+ hideIcon: state.appStates.conversationState === ConversationState.Loading && !state.appStates.startChatFailed || state.appStates.conversationState === ConversationState.PostchatLoading || (headerProps === null || headerProps === void 0 ? void 0 : (_headerProps$controlP2 = headerProps.controlProps) === null || _headerProps$controlP2 === void 0 ? void 0 : _headerProps$controlP2.hideIcon),
68
+ hideCloseButton: state.appStates.conversationState === ConversationState.Loading && !state.appStates.startChatFailed || state.appStates.conversationState === ConversationState.PostchatLoading || state.appStates.conversationState === ConversationState.Prechat || state.appStates.conversationState === ConversationState.ReconnectChat || (headerProps === null || headerProps === void 0 ? void 0 : (_headerProps$controlP3 = headerProps.controlProps) === null || _headerProps$controlP3 === void 0 ? void 0 : _headerProps$controlP3.hideCloseButton)
68
69
  };
69
70
  const outOfOfficeControlProps = {
70
71
  id: "oc-lcw-header",
@@ -85,11 +86,11 @@ export const HeaderStateful = props => {
85
86
  if (state.appStates.outsideOperatingHours) {
86
87
  setOutOfOperatingHours(true);
87
88
  }
88
- if (state.appStates.conversationState) {
89
- conversationState.current = state.appStates.conversationState;
90
- }
91
- conversationEndedBy.current = state.appStates.conversationEndedBy;
92
- }, [state.appStates]);
89
+ }, []);
90
+ useEffect(() => {
91
+ var _state$domainStates2;
92
+ localConfirmationPaneState.current = state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : _state$domainStates2.confirmationState;
93
+ }, [state === null || state === void 0 ? void 0 : (_state$domainStates3 = state.domainStates) === null || _state$domainStates3 === void 0 ? void 0 : _state$domainStates3.confirmationState]);
93
94
  return /*#__PURE__*/React.createElement(Header, {
94
95
  componentOverrides: headerProps === null || headerProps === void 0 ? void 0 : headerProps.componentOverrides,
95
96
  controlProps: outOfOperatingHours || state.appStates.conversationState === ConversationState.OutOfOffice ? outOfOfficeControlProps : controlProps,
@@ -3,6 +3,7 @@ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typ
3
3
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
4
4
  export class DefaultActivitySubscriber {
5
5
  constructor() {
6
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
7
  _defineProperty(this, "observer", void 0);
7
8
  }
8
9
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -4,6 +4,7 @@ function _toPrimitive(input, hint) { if (typeof input !== "object" || input ===
4
4
  import { ActivityStreamHandler } from "../ActivityStreamHandler";
5
5
  export class PauseActivitySubscriber {
6
6
  constructor() {
7
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
8
  _defineProperty(this, "observer", void 0);
8
9
  }
9
10
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -10,9 +10,11 @@ export class Deferred {
10
10
  _defineProperty(this, "_reject", () => {
11
11
  return;
12
12
  });
13
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
14
  _defineProperty(this, "resolve", value => {
14
15
  this._resolve(value);
15
16
  });
17
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
18
  _defineProperty(this, "reject", value => {
17
19
  this._reject(value);
18
20
  });
@@ -21,9 +23,6 @@ export class Deferred {
21
23
  this._reject = reject;
22
24
  });
23
25
  }
24
-
25
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
-
27
26
  get promise() {
28
27
  return this._promise;
29
28
  }
@@ -1789,5 +1789,6 @@ export const dummyDefaultProps = {
1789
1789
  hyperlinkTextOverride: false
1790
1790
  },
1791
1791
  telemetryConfig: undefined,
1792
- getAuthToken: undefined
1792
+ getAuthToken: undefined,
1793
+ initialCustomContext: undefined
1793
1794
  };
@@ -5,60 +5,84 @@ import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidge
5
5
  import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
6
6
  import { WebChatStoreLoader } from "../../webchatcontainerstateful/webchatcontroller/WebChatStoreLoader";
7
7
  import { defaultWebChatContainerStatefulProps } from "../../webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps";
8
- import { getWidgetEndChatEventName } from "../../../common/utils";
8
+ import { getWidgetEndChatEventName, isNullOrEmptyString } from "../../../common/utils";
9
9
  import { getAuthClientFunction, handleAuthentication } from "./authHelper";
10
- import { checkPostChatEnabled, initiatePostChat } from "./setPostChatContextAndLoadSurvey";
11
- import { ConversationEndEntity } from "../../../contexts/common/ConversationEndEntity";
10
+ import { initiatePostChat, getPostChatContext } from "./renderSurveyHelpers";
11
+ import { Constants, ConversationEndEntity, ConfirmationState } from "../../../common/Constants";
12
12
 
13
13
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
- const prepareEndChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, state) => {
15
- //Unable to end chat if token has expired
16
- if (props.getAuthToken) {
17
- const authClientFunction = getAuthClientFunction(props.chatConfig);
18
- if (props.getAuthToken && authClientFunction) {
19
- // set auth token to chat sdk before end chat
20
- const authSuccess = await handleAuthentication(chatSDK, props.chatConfig, props.getAuthToken);
21
- if (!authSuccess) {
22
- TelemetryHelper.logActionEvent(LogLevel.ERROR, {
23
- Event: TelemetryEvent.GetAuthTokenFailed,
24
- ExceptionDetails: {
25
- exception: "Unable to get auth token during end chat"
26
- }
27
- });
14
+ const prepareEndChat = async (props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, uwid) => {
15
+ try {
16
+ var _conversationDetails$, _state$domainStates, _state$domainStates2;
17
+ const conversationDetails = await getConversationDetails(chatSDK);
18
+
19
+ // Use Case : When post chat is not configured
20
+ if ((conversationDetails === null || conversationDetails === void 0 ? void 0 : (_conversationDetails$ = conversationDetails.canRenderPostChat) === null || _conversationDetails$ === void 0 ? void 0 : _conversationDetails$.toLowerCase()) === Constants.false) {
21
+ var _state$appStates;
22
+ // If ended by customer, just close chat
23
+ if ((state === null || state === void 0 ? void 0 : (_state$appStates = state.appStates) === null || _state$appStates === void 0 ? void 0 : _state$appStates.conversationEndedBy) === ConversationEndEntity.Customer) {
24
+ await endChat(props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, false, true, uwid);
28
25
  }
26
+ //Use Case: If ended by Agent, stay chat in InActive state
27
+ return;
29
28
  }
30
- }
31
- const isPostChatEnabled = checkPostChatEnabled(props, state);
32
- if (isPostChatEnabled) {
33
- try {
34
- await initiatePostChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, state);
35
- } catch (error) {
36
- // Ending chat because something went wrong
37
- await endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, false, false, true);
38
- }
39
- } else {
40
- if (state.appStates.conversationEndedBy === ConversationEndEntity.Agent) {
41
- dispatch({
42
- type: LiveChatWidgetActionType.SET_CHAT_TOKEN,
43
- payload: undefined
44
- });
29
+
30
+ // Use Case : Can render post chat scenarios
31
+ await getPostChatContext(chatSDK, state, dispatch);
32
+
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ const postchatContext = state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : _state$domainStates.postChatContext;
35
+ if (postchatContext === undefined) {
36
+ var _state$appStates2;
37
+ // For Customer intiated conversations, just close chat widget
38
+ if ((state === null || state === void 0 ? void 0 : (_state$appStates2 = state.appStates) === null || _state$appStates2 === void 0 ? void 0 : _state$appStates2.conversationEndedBy) === ConversationEndEntity.Customer) {
39
+ await endChat(props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, false, true, uwid);
40
+ return;
41
+ }
42
+
43
+ //For agent initiated end chat, allow to download transcript
45
44
  dispatch({
46
- type: LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
47
- payload: undefined
45
+ type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
46
+ payload: ConversationState.InActive
48
47
  });
49
- } else {
50
- await endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, false, false, true);
48
+ return;
49
+ }
50
+ endChat(props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, true, true, uwid);
51
+
52
+ // Initiate post chat render
53
+ if (state !== null && state !== void 0 && (_state$domainStates2 = state.domainStates) !== null && _state$domainStates2 !== void 0 && _state$domainStates2.postChatContext) {
54
+ await initiatePostChat(props, conversationDetails, state, dispatch);
55
+ return;
56
+ }
57
+ } catch (error) {
58
+ var _props$controlProps;
59
+ TelemetryHelper.logActionEvent(LogLevel.ERROR, {
60
+ Event: TelemetryEvent.EndChatFailed,
61
+ ExceptionDetails: {
62
+ exception: JSON.stringify(error)
63
+ }
64
+ });
65
+
66
+ //Close chat widget for any failure in embedded to allow to show start chat button
67
+ if (((_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.hideStartChatButton) === false) {
68
+ await endChat(props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, false, true, uwid);
51
69
  }
70
+ } finally {
71
+ //Chat token clean up
72
+ await chatTokenCleanUp(dispatch);
52
73
  }
53
74
  };
54
75
 
55
76
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
56
- const endChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, skipEndChatSDK, skipCloseChat, postMessageToOtherTab) => {
57
- if (!skipEndChatSDK) {
77
+ const endChat = async function (props, chatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, skipEndChatSDK, skipCloseChat, postMessageToOtherTab) {
78
+ let uwid = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : "";
79
+ if (!skipEndChatSDK && chatSDK.conversation) {
58
80
  try {
59
81
  TelemetryHelper.logSDKEvent(LogLevel.INFO, {
60
82
  Event: TelemetryEvent.EndChatSDKCall
61
83
  });
84
+ //Get auth token again if chat continued for longer time, otherwise gets 401 error
85
+ await handleAuthenticationIfEnabled(props, chatSDK);
62
86
  await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.endChat());
63
87
  } catch (ex) {
64
88
  TelemetryHelper.logSDKEvent(LogLevel.ERROR, {
@@ -68,25 +92,10 @@ const endChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, a
68
92
  }
69
93
  });
70
94
  postMessageToOtherTab = false;
95
+ } finally {
96
+ await endChatStateCleanUp(dispatch);
71
97
  }
72
98
  }
73
- // Need to clear these states immediately when chat ended from OC.
74
- dispatch({
75
- type: LiveChatWidgetActionType.SET_CHAT_TOKEN,
76
- payload: undefined
77
- });
78
- dispatch({
79
- type: LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
80
- payload: undefined
81
- });
82
- dispatch({
83
- type: LiveChatWidgetActionType.SET_RECONNECT_ID,
84
- payload: undefined
85
- });
86
- dispatch({
87
- type: LiveChatWidgetActionType.SET_CHAT_DISCONNECT_EVENT_RECEIVED,
88
- payload: false
89
- });
90
99
  if (!skipCloseChat) {
91
100
  try {
92
101
  var _props$webChatContain;
@@ -97,49 +106,7 @@ const endChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, a
97
106
  ...((_props$webChatContain = props.webChatContainerProps) === null || _props$webChatContain === void 0 ? void 0 : _props$webChatContain.webChatStyles)
98
107
  });
99
108
  WebChatStoreLoader.store = null;
100
- dispatch({
101
- type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
102
- payload: ConversationState.Closed
103
- });
104
- dispatch({
105
- type: LiveChatWidgetActionType.SET_POST_CHAT_WORKFLOW_IN_PROGRESS,
106
- payload: false
107
- });
108
- dispatch({
109
- type: LiveChatWidgetActionType.SET_SHOULD_USE_BOT_SURVEY,
110
- payload: false
111
- });
112
- dispatch({
113
- type: LiveChatWidgetActionType.SET_CONVERSATION_ENDED_BY_AGENT_EVENT_RECEIVED,
114
- payload: false
115
- });
116
- dispatch({
117
- type: LiveChatWidgetActionType.SET_CONVERSATION_ENDED_BY,
118
- payload: undefined
119
- });
120
- dispatch({
121
- type: LiveChatWidgetActionType.SET_RECONNECT_ID,
122
- payload: undefined
123
- });
124
- dispatch({
125
- type: LiveChatWidgetActionType.SET_AUDIO_NOTIFICATION,
126
- payload: null
127
- });
128
- dispatch({
129
- type: LiveChatWidgetActionType.SET_PROACTIVE_CHAT_PARAMS,
130
- payload: {
131
- proactiveChatBodyTitle: "",
132
- proactiveChatEnablePrechat: false,
133
- proactiveChatInNewWindow: false
134
- }
135
- });
136
- if (postMessageToOtherTab) {
137
- var _chatSDK$omnichannelC, _chatSDK$omnichannelC2, _props$controlProps;
138
- const endChatEventName = getWidgetEndChatEventName(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC === void 0 ? void 0 : _chatSDK$omnichannelC.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC2 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC2 === void 0 ? void 0 : _chatSDK$omnichannelC2.widgetId, (props === null || props === void 0 ? void 0 : (_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.widgetInstanceId) ?? "");
139
- BroadcastService.postMessage({
140
- eventName: endChatEventName
141
- });
142
- }
109
+ closeChatStateCleanUp(dispatch);
143
110
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
144
111
  Event: TelemetryEvent.CloseChatCall,
145
112
  Description: "Chat was closed succesfully"
@@ -152,11 +119,141 @@ const endChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, a
152
119
  }
153
120
  });
154
121
  } finally {
122
+ var _state$appStates3;
155
123
  dispatch({
156
124
  type: LiveChatWidgetActionType.SET_UNREAD_MESSAGE_COUNT,
157
125
  payload: 0
158
126
  });
127
+ //Always allow to close the chat for embedded mode irrespective of end chat errors
128
+ if (!(state !== null && state !== void 0 && (_state$appStates3 = state.appStates) !== null && _state$appStates3 !== void 0 && _state$appStates3.hideStartChatButton)) {
129
+ dispatch({
130
+ type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
131
+ payload: ConversationState.Closed
132
+ });
133
+ }
159
134
  }
160
135
  }
136
+ if (postMessageToOtherTab && !isNullOrEmptyString(uwid)) {
137
+ const endChatEventName = await getEndChatEventName(chatSDK, props);
138
+ BroadcastService.postMessage({
139
+ eventName: endChatEventName,
140
+ payload: uwid
141
+ });
142
+ }
143
+ };
144
+ const endChatStateCleanUp = async dispatch => {
145
+ // Need to clear these states immediately when chat ended from OC.
146
+ dispatch({
147
+ type: LiveChatWidgetActionType.SET_CUSTOM_CONTEXT,
148
+ payload: undefined
149
+ });
150
+ dispatch({
151
+ type: LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
152
+ payload: undefined
153
+ });
154
+ dispatch({
155
+ type: LiveChatWidgetActionType.SET_RECONNECT_ID,
156
+ payload: undefined
157
+ });
158
+ dispatch({
159
+ type: LiveChatWidgetActionType.SET_CHAT_DISCONNECT_EVENT_RECEIVED,
160
+ payload: false
161
+ });
162
+ };
163
+ const closeChatStateCleanUp = async dispatch => {
164
+ dispatch({
165
+ type: LiveChatWidgetActionType.SET_CHAT_TOKEN,
166
+ payload: undefined
167
+ });
168
+ // dispatch({ type: LiveChatWidgetActionType.SET_CONVERSATION_STATE, payload: ConversationState.Closed });
169
+ dispatch({
170
+ type: LiveChatWidgetActionType.SET_RECONNECT_ID,
171
+ payload: undefined
172
+ });
173
+ dispatch({
174
+ type: LiveChatWidgetActionType.SET_AUDIO_NOTIFICATION,
175
+ payload: null
176
+ });
177
+ dispatch({
178
+ type: LiveChatWidgetActionType.SET_CONVERSATION_ENDED_BY,
179
+ payload: ConversationEndEntity.NotSet
180
+ });
181
+ dispatch({
182
+ type: LiveChatWidgetActionType.SET_CONFIRMATION_STATE,
183
+ payload: ConfirmationState.NotSet
184
+ });
185
+ dispatch({
186
+ type: LiveChatWidgetActionType.SET_START_CHAT_FAILING,
187
+ payload: false
188
+ });
189
+ dispatch({
190
+ type: LiveChatWidgetActionType.SET_PROACTIVE_CHAT_PARAMS,
191
+ payload: {
192
+ proactiveChatBodyTitle: "",
193
+ proactiveChatEnablePrechat: false,
194
+ proactiveChatInNewWindow: false
195
+ }
196
+ });
197
+ };
198
+
199
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
200
+ const handleAuthenticationIfEnabled = async (props, chatSDK) => {
201
+ //Unable to end chat if token has expired
202
+ if (props.getAuthToken) {
203
+ const authClientFunction = getAuthClientFunction(props.chatConfig);
204
+ if (props.getAuthToken && authClientFunction) {
205
+ // set auth token to chat sdk before end chat
206
+ const authSuccess = await handleAuthentication(chatSDK, props.chatConfig, props.getAuthToken);
207
+ if (!authSuccess) {
208
+ TelemetryHelper.logActionEvent(LogLevel.ERROR, {
209
+ Event: TelemetryEvent.GetAuthTokenFailed,
210
+ ExceptionDetails: {
211
+ exception: "Unable to get auth token during end chat"
212
+ }
213
+ });
214
+ throw new Error("handleAuthenticationIfEnabled:Failed to get authentication token");
215
+ }
216
+ }
217
+ }
218
+ };
219
+
220
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
221
+ const chatTokenCleanUp = async dispatch => {
222
+ //Just do cleanup here
223
+ dispatch({
224
+ type: LiveChatWidgetActionType.SET_CHAT_TOKEN,
225
+ payload: undefined
226
+ });
227
+ dispatch({
228
+ type: LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
229
+ payload: undefined
230
+ });
231
+ };
232
+
233
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
234
+ const getEndChatEventName = async (chatSDK, props) => {
235
+ var _chatSDK$omnichannelC, _chatSDK$omnichannelC2, _props$controlProps2;
236
+ return getWidgetEndChatEventName(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC === void 0 ? void 0 : _chatSDK$omnichannelC.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC2 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC2 === void 0 ? void 0 : _chatSDK$omnichannelC2.widgetId, (props === null || props === void 0 ? void 0 : (_props$controlProps2 = props.controlProps) === null || _props$controlProps2 === void 0 ? void 0 : _props$controlProps2.widgetInstanceId) ?? "");
237
+ };
238
+
239
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
240
+ const getConversationDetails = async chatSDK => {
241
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
242
+ let conversationDetails = undefined;
243
+ try {
244
+ TelemetryHelper.logSDKEvent(LogLevel.INFO, {
245
+ Event: TelemetryEvent.GetConversationDetailsCallStarted,
246
+ Description: "Conversation details call started"
247
+ });
248
+ conversationDetails = await chatSDK.getConversationDetails();
249
+ } catch (error) {
250
+ TelemetryHelper.logSDKEvent(LogLevel.ERROR, {
251
+ Event: TelemetryEvent.GetConversationDetailsCallFailed,
252
+ ExceptionDetails: {
253
+ exception: `Get Conversation Details Call Failed : ${error}`
254
+ }
255
+ });
256
+ }
257
+ return conversationDetails;
161
258
  };
162
- export { prepareEndChat, endChat };
259
+ export { prepareEndChat, endChat, getConversationDetails };