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

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 (93) 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 -1
  5. package/lib/cjs/common/utils.js +27 -5
  6. package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +1 -10
  7. package/lib/cjs/components/confirmationpanestateful/ConfirmationPaneStateful.js +8 -6
  8. package/lib/cjs/components/footerstateful/FooterStateful.js +1 -1
  9. package/lib/cjs/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +8 -1
  10. package/lib/cjs/components/headerstateful/HeaderStateful.js +14 -13
  11. package/lib/cjs/components/livechatwidget/common/ActivitySubscriber/DefaultActivitySubscriber.js +1 -0
  12. package/lib/cjs/components/livechatwidget/common/ActivitySubscriber/PauseActivitySubscriber.js +1 -0
  13. package/lib/cjs/components/livechatwidget/common/Deferred.js +2 -3
  14. package/lib/cjs/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +2 -1
  15. package/lib/cjs/components/livechatwidget/common/endChat.js +197 -99
  16. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +29 -27
  17. package/lib/cjs/components/livechatwidget/common/reconnectChatHelper.js +11 -8
  18. package/lib/cjs/components/livechatwidget/common/renderSurveyHelpers.js +139 -0
  19. package/lib/cjs/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +2 -255
  20. package/lib/cjs/components/livechatwidget/common/startChat.js +70 -57
  21. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +162 -100
  22. package/lib/cjs/components/loadingpanestateful/LoadingPaneStateful.js +2 -2
  23. package/lib/cjs/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +15 -5
  24. package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +5 -4
  25. package/lib/cjs/components/reconnectchatpanestateful/ReconnectChatPaneStateful.js +4 -1
  26. package/lib/cjs/components/webchatcontainerstateful/common/mockchatsdk.js +6 -1
  27. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/WebChatStoreLoader.js +1 -0
  28. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware.js +8 -6
  29. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/webchattelemetry/WebChatLogger.js +7 -1
  30. package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +2 -0
  31. package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +16 -13
  32. package/lib/cjs/contexts/createReducer.js +13 -23
  33. package/lib/cjs/controller/componentController.js +2 -1
  34. package/lib/cjs/index.js +20 -0
  35. package/lib/esm/common/Constants.js +49 -0
  36. package/lib/esm/common/storage/default/defaultCacheManager.js +5 -4
  37. package/lib/esm/common/storage/default/defaultClientDataStoreProvider.js +9 -7
  38. package/lib/esm/common/telemetry/TelemetryConstants.js +6 -1
  39. package/lib/esm/common/utils.js +25 -4
  40. package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +4 -13
  41. package/lib/esm/components/confirmationpanestateful/ConfirmationPaneStateful.js +8 -6
  42. package/lib/esm/components/footerstateful/FooterStateful.js +1 -1
  43. package/lib/esm/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +8 -1
  44. package/lib/esm/components/headerstateful/HeaderStateful.js +14 -13
  45. package/lib/esm/components/livechatwidget/common/ActivitySubscriber/DefaultActivitySubscriber.js +1 -0
  46. package/lib/esm/components/livechatwidget/common/ActivitySubscriber/PauseActivitySubscriber.js +1 -0
  47. package/lib/esm/components/livechatwidget/common/Deferred.js +2 -3
  48. package/lib/esm/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +2 -1
  49. package/lib/esm/components/livechatwidget/common/endChat.js +196 -99
  50. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +29 -27
  51. package/lib/esm/components/livechatwidget/common/reconnectChatHelper.js +11 -8
  52. package/lib/esm/components/livechatwidget/common/renderSurveyHelpers.js +130 -0
  53. package/lib/esm/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +3 -255
  54. package/lib/esm/components/livechatwidget/common/startChat.js +71 -58
  55. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +164 -102
  56. package/lib/esm/components/loadingpanestateful/LoadingPaneStateful.js +2 -2
  57. package/lib/esm/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +15 -5
  58. package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +5 -4
  59. package/lib/esm/components/reconnectchatpanestateful/ReconnectChatPaneStateful.js +4 -1
  60. package/lib/esm/components/webchatcontainerstateful/common/mockchatsdk.js +6 -1
  61. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/WebChatStoreLoader.js +1 -0
  62. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware.js +8 -6
  63. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/webchattelemetry/WebChatLogger.js +7 -1
  64. package/lib/esm/contexts/common/LiveChatWidgetActionType.js +2 -0
  65. package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +18 -15
  66. package/lib/esm/contexts/createReducer.js +13 -23
  67. package/lib/esm/controller/componentController.js +2 -1
  68. package/lib/esm/index.js +4 -1
  69. package/lib/types/common/Constants.d.ts +21 -0
  70. package/lib/types/common/interfaces/IContextDataStore.d.ts +3 -3
  71. package/lib/types/common/storage/default/defaultCacheManager.d.ts +2 -1
  72. package/lib/types/common/storage/default/defaultClientDataStoreProvider.d.ts +2 -1
  73. package/lib/types/common/telemetry/TelemetryConstants.d.ts +6 -1
  74. package/lib/types/common/utils.d.ts +3 -2
  75. package/lib/types/components/confirmationpanestateful/interfaces/IConfirmationPaneStatefulParams.d.ts +6 -0
  76. package/lib/types/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.d.ts +2 -1
  77. package/lib/types/components/livechatwidget/common/endChat.d.ts +4 -3
  78. package/lib/types/components/livechatwidget/common/initWebChatComposer.d.ts +1 -1
  79. package/lib/types/components/livechatwidget/common/renderSurveyHelpers.d.ts +9 -0
  80. package/lib/types/components/livechatwidget/common/setPostChatContextAndLoadSurvey.d.ts +1 -6
  81. package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetProps.d.ts +3 -1
  82. package/lib/types/components/webchatcontainerstateful/common/mockchatsdk.d.ts +4 -0
  83. package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +8 -7
  84. package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +3 -1
  85. package/lib/types/contexts/common/LiveChatWidgetContextInitialState.d.ts +2 -1
  86. package/lib/types/index.d.ts +3 -0
  87. package/package.json +2 -1
  88. package/lib/cjs/components/livechatwidget/common/agentEndConversationHelper.js +0 -36
  89. package/lib/cjs/contexts/common/ConversationEndEntity.js +0 -12
  90. package/lib/esm/components/livechatwidget/common/agentEndConversationHelper.js +0 -30
  91. package/lib/esm/contexts/common/ConversationEndEntity.js +0 -5
  92. package/lib/types/components/livechatwidget/common/agentEndConversationHelper.d.ts +0 -6
  93. package/lib/types/contexts/common/ConversationEndEntity.d.ts +0 -4
@@ -1,18 +1,11 @@
1
- import { BroadcastEvent, LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
1
+ import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
2
2
  import { BroadcastService } from "@microsoft/omnichannel-chat-components";
3
3
  import { ConversationState } from "../../../contexts/common/ConversationState";
4
4
  import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
5
5
  import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
6
- import { Constants } from "../../../common/Constants";
7
- import { endChat } from "./endChat";
8
- import { PostChatSurveyMode } from "../../postchatsurveypanestateful/enums/PostChatSurveyMode";
9
- import { addDelayInMs } from "../../../common/utils";
10
- import { NotificationHandler } from "../../webchatcontainerstateful/webchatcontroller/notification/NotificationHandler";
11
- import { NotificationScenarios } from "../../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios";
12
- import { ConversationEndEntity } from "../../../contexts/common/ConversationEndEntity";
13
6
 
14
7
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
- const setPostChatContextAndLoadSurvey = async (chatSDK, dispatch, persistedChat) => {
8
+ export const setPostChatContextAndLoadSurvey = async (chatSDK, dispatch, persistedChat) => {
16
9
  try {
17
10
  if (!persistedChat) {
18
11
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -42,249 +35,4 @@ const setPostChatContextAndLoadSurvey = async (chatSDK, dispatch, persistedChat)
42
35
  payload: ConversationState.Postchat
43
36
  });
44
37
  });
45
- };
46
-
47
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
- const checkPostChatEnabled = (props, state) => {
49
- var _props$chatConfig, _props$chatConfig$Liv, _state$domainStates$l, _state$domainStates$l2;
50
- const isPostChatEnabled = ((_props$chatConfig = props.chatConfig) === null || _props$chatConfig === void 0 ? void 0 : (_props$chatConfig$Liv = _props$chatConfig.LiveWSAndLiveChatEngJoin) === null || _props$chatConfig$Liv === void 0 ? void 0 : _props$chatConfig$Liv.msdyn_postconversationsurveyenable) ?? ((_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.msdyn_postconversationsurveyenable);
51
- return isPostChatEnabled === Constants.true;
52
- };
53
-
54
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
- const initiatePostChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, state) => {
56
- // Check if Postchat already in progress and handle case where chat is ended by customer
57
- if (state.appStates.postChatWorkflowInProgress && state.appStates.conversationEndedBy === ConversationEndEntity.Customer) {
58
- await endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, false, false, true);
59
- return;
60
- }
61
-
62
- // Conversation Details call required by customer as well as agent
63
- const conversationDetails = await getConversationDetailsCall(chatSDK);
64
- // Start Postchat workflow
65
- dispatch({
66
- type: LiveChatWidgetActionType.SET_POST_CHAT_WORKFLOW_IN_PROGRESS,
67
- payload: true
68
- });
69
-
70
- // Below logic checks if agent or bot or noone joins conversation and handles them separately
71
- if ((conversationDetails === null || conversationDetails === void 0 ? void 0 : conversationDetails.participantType) === Constants.userParticipantTypeTag) {
72
- if (state.appStates.conversationEndedBy === ConversationEndEntity.Customer) {
73
- // Set use bot settings to false
74
- await postChatInitiatedByCustomer(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, state, conversationDetails, false);
75
- } else if (state.appStates.conversationEndedBy === ConversationEndEntity.Agent) {
76
- await postChatInitiatedByAgent(props, setWebChatStyles, dispatch, state);
77
- } else {
78
- const error = `Conversation was Ended after agent joined but App State was not set correctly: conversationEndedBy = ${state.appStates.conversationEndedBy}`;
79
- TelemetryHelper.logActionEvent(LogLevel.ERROR, {
80
- Event: TelemetryEvent.AppStatesException,
81
- ExceptionDetails: {
82
- exception: error
83
- }
84
- });
85
- throw new Error(error);
86
- }
87
- } else if ((conversationDetails === null || conversationDetails === void 0 ? void 0 : conversationDetails.participantType) === Constants.botParticipantTypeTag) {
88
- // Set Use bot survey to true
89
- dispatch({
90
- type: LiveChatWidgetActionType.SET_SHOULD_USE_BOT_SURVEY,
91
- payload: true
92
- });
93
- if (state.appStates.conversationEndedBy === ConversationEndEntity.Customer) {
94
- // Set use bot settings to true
95
- await postChatInitiatedByCustomer(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, state, conversationDetails, true);
96
- } else if (state.appStates.conversationEndedBy === ConversationEndEntity.Agent) {
97
- await postChatInitiatedByBot(props, setWebChatStyles, dispatch, state);
98
- } else {
99
- const error = `Conversation was Ended after bot joined but App State was not set correctly: conversationEndedBy = ${state.appStates.conversationEndedBy}`;
100
- TelemetryHelper.logActionEvent(LogLevel.ERROR, {
101
- Event: TelemetryEvent.AppStatesException,
102
- ExceptionDetails: {
103
- exception: error
104
- }
105
- });
106
- throw new Error(error);
107
- }
108
- } else {
109
- if (state.appStates.conversationEndedBy === ConversationEndEntity.Customer) {
110
- // No one has joined chat will be handled by postChat customer
111
- await postChatInitiatedByCustomer(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, state, conversationDetails, false);
112
- } else {
113
- const error = `ConversationDetails and App state was not set correctly: conversationDetails = ${JSON.stringify(conversationDetails)} , conversationEndedBy = ${state.appStates.conversationEndedBy}`;
114
- TelemetryHelper.logActionEvent(LogLevel.ERROR, {
115
- Event: TelemetryEvent.AppStatesException,
116
- ExceptionDetails: {
117
- exception: error
118
- }
119
- });
120
- throw new Error(error);
121
- }
122
- }
123
- };
124
-
125
- // Function for link mode postchat workflow which is essentially same for both customer and agent
126
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
127
- const linkModePostChatWorkflow = (props, dispatch, setWebChatStyles) => {
128
- var _props$webChatContain, _props$webChatContain2;
129
- TelemetryHelper.logActionEvent(LogLevel.INFO, {
130
- Event: TelemetryEvent.LinkModePostChatWorkflowStarted
131
- });
132
- dispatch({
133
- type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
134
- payload: ConversationState.InActive
135
- });
136
-
137
- // Disable SendBox
138
- if ((props === null || props === void 0 ? void 0 : (_props$webChatContain = props.webChatContainerProps) === null || _props$webChatContain === void 0 ? void 0 : (_props$webChatContain2 = _props$webChatContain.renderingMiddlewareProps) === null || _props$webChatContain2 === void 0 ? void 0 : _props$webChatContain2.hideSendboxOnConversationEnd) !== false) {
139
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
140
- setWebChatStyles(styles => {
141
- return {
142
- ...styles,
143
- hideSendBox: true
144
- };
145
- });
146
- }
147
- };
148
-
149
- // Function for embed mode postchat workflow which is essentially same for both customer and agent
150
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
151
- const embedModePostChatWorkflow = async (dispatch, state) => {
152
- TelemetryHelper.logActionEvent(LogLevel.INFO, {
153
- Event: TelemetryEvent.EmbedModePostChatWorkflowStarted
154
- });
155
- if (state.domainStates.postChatContext) {
156
- dispatch({
157
- type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
158
- payload: ConversationState.PostchatLoading
159
- });
160
- await addDelayInMs(Constants.PostChatLoadingDurationInMs);
161
- const loadPostChatEvent = {
162
- eventName: BroadcastEvent.LoadPostChatSurvey
163
- };
164
- BroadcastService.postMessage(loadPostChatEvent);
165
- } else {
166
- const error = `Conversation was Ended but App State was not set correctly: postChatContext = ${state.domainStates.postChatContext}`;
167
- TelemetryHelper.logActionEvent(LogLevel.ERROR, {
168
- Event: TelemetryEvent.AppStatesException,
169
- ExceptionDetails: {
170
- exception: error
171
- }
172
- });
173
- throw new Error(error);
174
- }
175
- };
176
-
177
- // Function will handle only postchat cases initiated by customer
178
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
179
- const postChatInitiatedByCustomer = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, state, conversationDetails, shouldUseBotSetting) => {
180
- let postChatSurveyMode = "";
181
- if (shouldUseBotSetting) {
182
- var _props$chatConfig2, _props$chatConfig2$Li, _state$domainStates$l3, _state$domainStates$l4;
183
- postChatSurveyMode = ((_props$chatConfig2 = props.chatConfig) === null || _props$chatConfig2 === void 0 ? void 0 : (_props$chatConfig2$Li = _props$chatConfig2.LiveWSAndLiveChatEngJoin) === null || _props$chatConfig2$Li === void 0 ? void 0 : _props$chatConfig2$Li.msdyn_postconversationsurveybotsurveymode) ?? ((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : (_state$domainStates$l4 = _state$domainStates$l3.LiveWSAndLiveChatEngJoin) === null || _state$domainStates$l4 === void 0 ? void 0 : _state$domainStates$l4.msdyn_postconversationsurveybotsurveymode);
184
- } else {
185
- var _props$chatConfig3, _props$chatConfig3$Li, _state$domainStates$l5, _state$domainStates$l6;
186
- postChatSurveyMode = ((_props$chatConfig3 = props.chatConfig) === null || _props$chatConfig3 === void 0 ? void 0 : (_props$chatConfig3$Li = _props$chatConfig3.LiveWSAndLiveChatEngJoin) === null || _props$chatConfig3$Li === void 0 ? void 0 : _props$chatConfig3$Li.msdyn_postconversationsurveymode) ?? ((_state$domainStates$l5 = state.domainStates.liveChatConfig) === null || _state$domainStates$l5 === void 0 ? void 0 : (_state$domainStates$l6 = _state$domainStates$l5.LiveWSAndLiveChatEngJoin) === null || _state$domainStates$l6 === void 0 ? void 0 : _state$domainStates$l6.msdyn_postconversationsurveymode);
187
- }
188
- // Check if agent or bot has joined conversation
189
- if ((conversationDetails === null || conversationDetails === void 0 ? void 0 : conversationDetails.canRenderPostChat) === Constants.truePascal) {
190
- TelemetryHelper.logActionEvent(LogLevel.INFO, {
191
- Event: TelemetryEvent.PostChatWorkflowFromCustomer,
192
- Description: shouldUseBotSetting ? "PostChat Workflow was started by customer using bot settings" : "PostChat Workflow was started by customer using agent settings"
193
- });
194
- const chatSession = await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.getCurrentLiveChatContext());
195
- // End chat call to end chatsdk but not close chat, only if chat ended by customer
196
- await endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, false, true, false);
197
- // Saving request Id below for chat transcript calls
198
- if (chatSession) {
199
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
200
- chatSDK.chatToken = chatSession.chatToken ?? {};
201
- chatSDK.requestId = chatSession.requestId;
202
- }
203
- if (postChatSurveyMode === PostChatSurveyMode.Embed) {
204
- await embedModePostChatWorkflow(dispatch, state);
205
- } else if (postChatSurveyMode === PostChatSurveyMode.Link) {
206
- linkModePostChatWorkflow(props, dispatch, setWebChatStyles);
207
- } else {
208
- const error = `Conversation was Ended but App State was not set correctly: msdyn_postconversationsurveymode = ${postChatSurveyMode}`;
209
- TelemetryHelper.logActionEvent(LogLevel.ERROR, {
210
- Event: TelemetryEvent.AppStatesException,
211
- ExceptionDetails: {
212
- exception: error
213
- }
214
- });
215
- throw new Error(error);
216
- }
217
- } else {
218
- // Agent did not join chat so end chat normally
219
- await endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, false, false, true);
220
- }
221
- };
222
-
223
- // Function will handle only postchat cases initiated by agent
224
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
225
- const postChatInitiatedByAgent = async (props, setWebChatStyles, dispatch, state) => {
226
- var _props$chatConfig4, _props$chatConfig4$Li, _state$domainStates$l7, _state$domainStates$l8;
227
- const postChatSurveyMode = ((_props$chatConfig4 = props.chatConfig) === null || _props$chatConfig4 === void 0 ? void 0 : (_props$chatConfig4$Li = _props$chatConfig4.LiveWSAndLiveChatEngJoin) === null || _props$chatConfig4$Li === void 0 ? void 0 : _props$chatConfig4$Li.msdyn_postconversationsurveymode) ?? ((_state$domainStates$l7 = state.domainStates.liveChatConfig) === null || _state$domainStates$l7 === void 0 ? void 0 : (_state$domainStates$l8 = _state$domainStates$l7.LiveWSAndLiveChatEngJoin) === null || _state$domainStates$l8 === void 0 ? void 0 : _state$domainStates$l8.msdyn_postconversationsurveymode);
228
- TelemetryHelper.logActionEvent(LogLevel.INFO, {
229
- Event: TelemetryEvent.PostChatWorkflowFromAgent,
230
- Description: "PostChat Workflow was started by agent"
231
- });
232
- if (postChatSurveyMode === PostChatSurveyMode.Embed) {
233
- await embedModePostChatWorkflow(dispatch, state);
234
- } else if (postChatSurveyMode === PostChatSurveyMode.Link) {
235
- linkModePostChatWorkflow(props, dispatch, setWebChatStyles);
236
- } else {
237
- const error = `Conversation was Ended but App State was not set correctly: msdyn_postconversationsurveymode = ${postChatSurveyMode}`;
238
- TelemetryHelper.logActionEvent(LogLevel.ERROR, {
239
- Event: TelemetryEvent.AppStatesException,
240
- ExceptionDetails: {
241
- exception: error
242
- }
243
- });
244
- throw new Error(error);
245
- }
246
- };
247
-
248
- // Function will handle only postchat cases initiated by bot
249
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
250
- const postChatInitiatedByBot = async (props, setWebChatStyles, dispatch, state) => {
251
- var _props$chatConfig5, _props$chatConfig5$Li, _state$domainStates$l9, _state$domainStates$l10;
252
- const postChatSurveyMode = ((_props$chatConfig5 = props.chatConfig) === null || _props$chatConfig5 === void 0 ? void 0 : (_props$chatConfig5$Li = _props$chatConfig5.LiveWSAndLiveChatEngJoin) === null || _props$chatConfig5$Li === void 0 ? void 0 : _props$chatConfig5$Li.msdyn_postconversationsurveybotsurveymode) ?? ((_state$domainStates$l9 = state.domainStates.liveChatConfig) === null || _state$domainStates$l9 === void 0 ? void 0 : (_state$domainStates$l10 = _state$domainStates$l9.LiveWSAndLiveChatEngJoin) === null || _state$domainStates$l10 === void 0 ? void 0 : _state$domainStates$l10.msdyn_postconversationsurveybotsurveymode);
253
- TelemetryHelper.logActionEvent(LogLevel.INFO, {
254
- Event: TelemetryEvent.PostChatWorkflowFromBot,
255
- Description: "PostChat Workflow was started by bot"
256
- });
257
- if (postChatSurveyMode === PostChatSurveyMode.Embed) {
258
- await embedModePostChatWorkflow(dispatch, state);
259
- } else if (postChatSurveyMode === PostChatSurveyMode.Link) {
260
- linkModePostChatWorkflow(props, dispatch, setWebChatStyles);
261
- } else {
262
- const error = `Conversation was Ended but App State was not set correctly: msdyn_postconversationsurveybotsurveymode = ${postChatSurveyMode}`;
263
- TelemetryHelper.logActionEvent(LogLevel.ERROR, {
264
- Event: TelemetryEvent.AppStatesException,
265
- ExceptionDetails: {
266
- exception: error
267
- }
268
- });
269
- throw new Error(error);
270
- }
271
- };
272
-
273
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
274
- const getConversationDetailsCall = async chatSDK => {
275
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
276
- let conversationDetails = undefined;
277
- try {
278
- conversationDetails = await chatSDK.getConversationDetails();
279
- } catch (error) {
280
- TelemetryHelper.logSDKEvent(LogLevel.ERROR, {
281
- Event: TelemetryEvent.GetConversationDetailsCallFailed,
282
- ExceptionDetails: {
283
- exception: `Get Conversation Details Call Failed : ${error}`
284
- }
285
- });
286
- NotificationHandler.notifyError(NotificationScenarios.Connection, "Get Conversation Details Call Failed: " + error);
287
- }
288
- return conversationDetails;
289
- };
290
- export { setPostChatContextAndLoadSurvey, checkPostChatEnabled, initiatePostChat };
38
+ };
@@ -1,6 +1,6 @@
1
1
  import { BroadcastEvent, LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
2
2
  import { ChatSDKError, LiveWorkItemState } from "../../../common/Constants";
3
- import { createTimer, getStateFromCache, isUndefinedOrEmpty } from "../../../common/utils";
3
+ import { createTimer, getStateFromCache, getWidgetCacheIdfromProps, isNullOrEmptyString, isUndefinedOrEmpty } from "../../../common/utils";
4
4
  import { getAuthClientFunction, handleAuthentication } from "./authHelper";
5
5
  import { ActivityStreamHandler } from "./ActivityStreamHandler";
6
6
  import { BroadcastService } from "@microsoft/omnichannel-chat-components";
@@ -20,21 +20,26 @@ import { updateSessionDataForTelemetry } from "./updateSessionDataForTelemetry";
20
20
  let optionalParams = {};
21
21
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
22
  let widgetInstanceId;
23
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
+ let popoutWidgetInstanceId;
23
25
 
24
26
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
27
  const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) => {
26
- var _props$controlProps;
27
28
  optionalParams = {}; //Resetting to ensure no stale values
28
- widgetInstanceId = props === null || props === void 0 ? void 0 : (_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.widgetInstanceId;
29
+ widgetInstanceId = getWidgetCacheIdfromProps(props);
29
30
 
30
31
  // reconnect > chat from cache
31
32
  await handleChatReconnect(chatSDK, props, dispatch, setAdapter, initStartChat, state);
32
-
33
33
  // If chat reconnect has kicked in chat state will become Active or Reconnect. So just exit, else go next
34
34
  if (state.appStates.conversationState === ConversationState.Active || state.appStates.conversationState === ConversationState.ReconnectChat) {
35
35
  return;
36
36
  }
37
37
 
38
+ // Check if there is any active popout chats in cache
39
+ if (await canStartPopoutChat(props)) {
40
+ return;
41
+ }
42
+
38
43
  // Can connect to existing chat session
39
44
  if (await canConnectToExistingChat(props, chatSDK, state, dispatch, setAdapter)) {
40
45
  return;
@@ -45,19 +50,12 @@ const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) =>
45
50
  const isPreChatEnabledInProactiveChat = state.appStates.proactiveChatStates.proactiveChatEnablePrechat;
46
51
 
47
52
  //Setting PreChat and intiate chat
48
- setPreChatAndInitiateChat(chatSDK, dispatch, setAdapter, isProactiveChat, isPreChatEnabledInProactiveChat, undefined, props);
53
+ await setPreChatAndInitiateChat(chatSDK, dispatch, setAdapter, isProactiveChat, isPreChatEnabledInProactiveChat, undefined, props);
49
54
  };
50
55
 
51
56
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
57
  const setPreChatAndInitiateChat = async (chatSDK, dispatch, setAdapter, isProactiveChat, proactiveChatEnablePrechatState, state, props) => {
53
58
  //Handle reconnect scenario
54
- if (state) {
55
- await handleChatReconnect(chatSDK, props, dispatch, setAdapter, initStartChat, state);
56
- // If chat reconnect has kicked in chat state will become Active or Reconnect. So just exit, else go next
57
- if (state.appStates.conversationState === ConversationState.Active || state.appStates.conversationState === ConversationState.ReconnectChat) {
58
- return;
59
- }
60
- }
61
59
 
62
60
  // Getting prechat Survey Context
63
61
  const parseToJson = false;
@@ -88,11 +86,11 @@ const setPreChatAndInitiateChat = async (chatSDK, dispatch, setAdapter, isProact
88
86
 
89
87
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
90
88
  const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persistedState) => {
91
- var _props$controlProps2;
89
+ var _props$controlProps;
92
90
  let isStartChatSuccessful = false;
93
91
  const chatConfig = props === null || props === void 0 ? void 0 : props.chatConfig;
94
92
  const getAuthToken = props === null || props === void 0 ? void 0 : props.getAuthToken;
95
- const hideErrorUIPane = props === null || props === void 0 ? void 0 : (_props$controlProps2 = props.controlProps) === null || _props$controlProps2 === void 0 ? void 0 : _props$controlProps2.hideErrorUIPane;
93
+ const hideErrorUIPane = props === null || props === void 0 ? void 0 : (_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.hideErrorUIPane;
96
94
  try {
97
95
  var _newAdapter$activity$, _TelemetryTimers$Widg;
98
96
  //Start widget load timer
@@ -106,11 +104,8 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
106
104
  // set auth token to chat sdk before start chat
107
105
  const authSuccess = await handleAuthentication(chatSDK, chatConfig, getAuthToken);
108
106
  if (!authSuccess) {
109
- dispatch({
110
- type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
111
- payload: ConversationState.Closed
112
- });
113
- return;
107
+ // Replacing with error ui
108
+ throw new Error("Authentication was not successful");
114
109
  }
115
110
  }
116
111
 
@@ -128,7 +123,7 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
128
123
  try {
129
124
  var _window$Microsoft, _window$Microsoft$Dyn, _window$Microsoft$Dyn2, _window$Microsoft$Dyn3;
130
125
  // Set custom context params
131
- setCustomContextParams(chatSDK);
126
+ setCustomContextParams();
132
127
  const defaultOptionalParams = {
133
128
  sendDefaultInitContext: true,
134
129
  isProactiveChat: !!(params !== null && params !== void 0 && params.isProactiveChat),
@@ -157,21 +152,6 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
157
152
  payload: chatToken
158
153
  });
159
154
  newAdapter === null || newAdapter === void 0 ? void 0 : (_newAdapter$activity$ = newAdapter.activity$) === null || _newAdapter$activity$ === void 0 ? void 0 : _newAdapter$activity$.subscribe(createOnNewAdapterActivityHandler(chatToken === null || chatToken === void 0 ? void 0 : chatToken.chatId, chatToken === null || chatToken === void 0 ? void 0 : chatToken.visitorId));
160
- if (persistedState) {
161
- dispatch({
162
- type: LiveChatWidgetActionType.SET_WIDGET_STATE,
163
- payload: persistedState
164
- });
165
- setPostChatContextAndLoadSurvey(chatSDK, dispatch, true);
166
- return;
167
- }
168
-
169
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
170
- const liveChatContext = await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.getCurrentLiveChatContext());
171
- dispatch({
172
- type: LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
173
- payload: liveChatContext
174
- });
175
155
 
176
156
  // Set app state to Active
177
157
  if (isStartChatSuccessful) {
@@ -186,14 +166,30 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
186
166
  payload: ConversationState.Active
187
167
  });
188
168
  }
169
+ if (persistedState) {
170
+ dispatch({
171
+ type: LiveChatWidgetActionType.SET_WIDGET_STATE,
172
+ payload: persistedState
173
+ });
174
+ await setPostChatContextAndLoadSurvey(chatSDK, dispatch, true);
175
+ return;
176
+ }
177
+
178
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
179
+ const liveChatContext = await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.getCurrentLiveChatContext());
180
+ dispatch({
181
+ type: LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
182
+ payload: liveChatContext
183
+ });
189
184
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
190
185
  Event: TelemetryEvent.WidgetLoadComplete,
191
186
  Description: "Widget load complete",
192
187
  ElapsedTimeInMilliseconds: TelemetryTimers === null || TelemetryTimers === void 0 ? void 0 : (_TelemetryTimers$Widg = TelemetryTimers.WidgetLoadTimer) === null || _TelemetryTimers$Widg === void 0 ? void 0 : _TelemetryTimers$Widg.milliSecondsElapsed
193
188
  });
194
189
 
195
- // Set post chat context in state, no survey load
196
- setPostChatContextAndLoadSurvey(chatSDK, dispatch);
190
+ // Set post chat context in state
191
+ // Commenting this for now as post chat context is fetched during end chat
192
+ await setPostChatContextAndLoadSurvey(chatSDK, dispatch);
197
193
 
198
194
  // Updating chat session detail for telemetry
199
195
  await updateSessionDataForTelemetry(chatSDK, dispatch);
@@ -217,12 +213,12 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
217
213
  });
218
214
  return;
219
215
  }
216
+ dispatch({
217
+ type: LiveChatWidgetActionType.SET_START_CHAT_FAILING,
218
+ payload: true
219
+ });
220
220
  if (!hideErrorUIPane) {
221
221
  // Set app state to failing start chat if hideErrorUI is not turned on
222
- dispatch({
223
- type: LiveChatWidgetActionType.SET_START_CHAT_FAILING,
224
- payload: true
225
- });
226
222
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
227
223
  Event: TelemetryEvent.ErrorUIPaneLoaded,
228
224
  Description: "Error UI Pane Loaded"
@@ -258,15 +254,15 @@ const forceEndChat = async chatSDK => {
258
254
 
259
255
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
260
256
  const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdapter) => {
261
- var _chatSDK$omnichannelC, _chatSDK$omnichannelC2, _props$controlProps3, _persistedState$domai6;
257
+ var _state$appStates, _persistedState$domai6, _persistedState$appSt;
262
258
  // By pass this function in case of popout chat
263
- if (state.appStates.hideStartChatButton === true) {
259
+ if ((state === null || state === void 0 ? void 0 : (_state$appStates = state.appStates) === null || _state$appStates === void 0 ? void 0 : _state$appStates.hideStartChatButton) === true) {
264
260
  return false;
265
261
  }
266
- const persistedState = getStateFromCache(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$controlProps3 = props.controlProps) === null || _props$controlProps3 === void 0 ? void 0 : _props$controlProps3.widgetInstanceId) ?? "");
262
+ const persistedState = getStateFromCache(getWidgetCacheIdfromProps(props));
267
263
 
268
264
  //Connect to only active chat session
269
- if (persistedState && !isUndefinedOrEmpty(persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai6 = persistedState.domainStates) === null || _persistedState$domai6 === void 0 ? void 0 : _persistedState$domai6.liveChatContext)) {
265
+ if (persistedState && !isUndefinedOrEmpty(persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai6 = persistedState.domainStates) === null || _persistedState$domai6 === void 0 ? void 0 : _persistedState$domai6.liveChatContext) && (persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$appSt = persistedState.appStates) === null || _persistedState$appSt === void 0 ? void 0 : _persistedState$appSt.conversationState) === ConversationState.Active) {
270
266
  var _persistedState$domai7;
271
267
  dispatch({
272
268
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
@@ -277,16 +273,15 @@ const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdap
277
273
  };
278
274
  await initStartChat(chatSDK, dispatch, setAdapter, props, optionalParams, persistedState);
279
275
  return true;
280
- } else {
281
- return false;
282
276
  }
277
+ return false;
283
278
  };
284
279
 
285
280
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
286
- const setCustomContextParams = chatSDK => {
287
- var _chatSDK$omnichannelC3, _chatSDK$omnichannelC4, _persistedState$domai8;
281
+ const setCustomContextParams = () => {
282
+ var _persistedState$domai8;
288
283
  // Add custom context only for unauthenticated chat
289
- const persistedState = getStateFromCache(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC3 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC3 === void 0 ? void 0 : _chatSDK$omnichannelC3.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC4 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC4 === void 0 ? void 0 : _chatSDK$omnichannelC4.widgetId, widgetInstanceId ?? "");
284
+ const persistedState = getStateFromCache(widgetInstanceId);
290
285
  if (!isUndefinedOrEmpty(persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai8 = persistedState.domainStates) === null || _persistedState$domai8 === void 0 ? void 0 : _persistedState$domai8.customContext)) {
291
286
  var _persistedState$domai9, _persistedState$domai10;
292
287
  if (persistedState !== null && persistedState !== void 0 && (_persistedState$domai9 = persistedState.domainStates.liveChatConfig) !== null && _persistedState$domai9 !== void 0 && _persistedState$domai9.LiveChatConfigAuthSettings) {
@@ -304,25 +299,43 @@ const setCustomContextParams = chatSDK => {
304
299
  });
305
300
  }
306
301
  };
302
+ const canStartPopoutChat = async props => {
303
+ if (props.allowSdkChatSupport === false) {
304
+ return false;
305
+ }
306
+ popoutWidgetInstanceId = getWidgetCacheIdfromProps(props, true);
307
+ if (!isNullOrEmptyString(popoutWidgetInstanceId)) {
308
+ var _persistedState$domai11, _persistedState$appSt2;
309
+ const persistedState = getStateFromCache(popoutWidgetInstanceId);
310
+ if (persistedState && !isUndefinedOrEmpty(persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai11 = persistedState.domainStates) === null || _persistedState$domai11 === void 0 ? void 0 : _persistedState$domai11.liveChatContext) && (persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$appSt2 = persistedState.appStates) === null || _persistedState$appSt2 === void 0 ? void 0 : _persistedState$appSt2.conversationState) === ConversationState.Active) {
311
+ // Initiate popout chat
312
+ BroadcastService.postMessage({
313
+ eventName: BroadcastEvent.InitiateStartChatInPopoutMode
314
+ });
315
+ return true;
316
+ }
317
+ }
318
+ return false;
319
+ };
307
320
 
308
321
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
309
322
  const checkIfConversationStillValid = async (chatSDK, dispatch, state) => {
310
323
  var _state$domainStates, _state$domainStates$l;
311
- const requestId = (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_state$domainStates$l = _state$domainStates.liveChatContext) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.requestId;
324
+ const requestIdFromCache = (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_state$domainStates$l = _state$domainStates.liveChatContext) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.requestId;
312
325
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
313
326
  let conversationDetails = undefined;
314
327
 
315
- //Preserve old requestId
316
- const oldRequestId = chatSDK.requestId ?? "";
328
+ //Preserve current requestId
329
+ const currentRequestId = chatSDK.requestId ?? "";
317
330
  dispatch({
318
331
  type: LiveChatWidgetActionType.SET_INITIAL_CHAT_SDK_REQUEST_ID,
319
- payload: oldRequestId
332
+ payload: currentRequestId
320
333
  });
321
334
  try {
322
- chatSDK.requestId = requestId;
335
+ chatSDK.requestId = requestIdFromCache;
323
336
  conversationDetails = await chatSDK.getConversationDetails();
324
337
  if (Object.keys(conversationDetails).length === 0) {
325
- chatSDK.requestId = oldRequestId;
338
+ chatSDK.requestId = currentRequestId;
326
339
  return false;
327
340
  }
328
341
  if (conversationDetails.state === LiveWorkItemState.Closed || conversationDetails.state === LiveWorkItemState.WrapUp) {
@@ -330,7 +343,7 @@ const checkIfConversationStillValid = async (chatSDK, dispatch, state) => {
330
343
  type: LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
331
344
  payload: undefined
332
345
  });
333
- chatSDK.requestId = oldRequestId;
346
+ chatSDK.requestId = currentRequestId;
334
347
  return false;
335
348
  }
336
349
  return true;
@@ -341,7 +354,7 @@ const checkIfConversationStillValid = async (chatSDK, dispatch, state) => {
341
354
  exception: `Conversation is not valid: ${erorr}`
342
355
  }
343
356
  });
344
- chatSDK.requestId = oldRequestId;
357
+ chatSDK.requestId = currentRequestId;
345
358
  return false;
346
359
  }
347
360
  };