From 42025313b5a18f56fd726e07a0977625f636cc55 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 22 May 2025 09:57:09 -0400 Subject: [PATCH 1/8] Explicitly redirect to confirmation rather than cancelling nav. --- src/router/methods/before-each.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/router/methods/before-each.js b/src/router/methods/before-each.js index cae308ccb..dde2a45ac 100644 --- a/src/router/methods/before-each.js +++ b/src/router/methods/before-each.js @@ -49,7 +49,9 @@ export async function beforeEach(to, from) { const exceptionPages = [FUNNEL_START_PAGE.name, routeData.CONFIRMATION.name]; if (!exceptionPages.some((name) => to.name === name) && !isVirtualRoute(to.name)) { - return false; + return { + name: routeData.CONFIRMATION.name, + }; } } From 922b57d51c4607c897f7eb788e3456256b0071cc Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 22 May 2025 10:27:22 -0400 Subject: [PATCH 2/8] Stop some weird back behavior from iframe --- src/router/methods/before-each.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/router/methods/before-each.js b/src/router/methods/before-each.js index dde2a45ac..fb1ed2256 100644 --- a/src/router/methods/before-each.js +++ b/src/router/methods/before-each.js @@ -14,6 +14,7 @@ import { checkLogParam } from "@/helpers/debug-log-helper"; import { debugLog } from "@/helpers/debug-log-helper"; import { handleHeritageReturn } from "@/router/methods/helpers/handle-heritage-return"; import { isVirtualRoute } from "@/router/methods/helpers/is-virtual-route"; +import router from "@/router"; export async function beforeEach(to, from) { try { @@ -49,9 +50,13 @@ export async function beforeEach(to, from) { const exceptionPages = [FUNNEL_START_PAGE.name, routeData.CONFIRMATION.name]; if (!exceptionPages.some((name) => to.name === name) && !isVirtualRoute(to.name)) { - return { + router.push({ name: routeData.CONFIRMATION.name, - }; + }); + return false; + // return { + // name: routeData.CONFIRMATION.name, + // }; } } From 599e28294708560003d0a04679d17e10bfc78459 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 22 May 2025 10:29:08 -0400 Subject: [PATCH 3/8] Remove commented code --- src/router/methods/before-each.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/router/methods/before-each.js b/src/router/methods/before-each.js index fb1ed2256..e742f89ff 100644 --- a/src/router/methods/before-each.js +++ b/src/router/methods/before-each.js @@ -54,9 +54,6 @@ export async function beforeEach(to, from) { name: routeData.CONFIRMATION.name, }); return false; - // return { - // name: routeData.CONFIRMATION.name, - // }; } } From d3314cd889835d549e7674a84cf031ead2adb5f3 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 27 May 2025 12:00:07 -0400 Subject: [PATCH 4/8] Manually clear state rather than relying on second route --- src/router/methods/error.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/router/methods/error.js b/src/router/methods/error.js index f9f20c19d..56d32cbaf 100644 --- a/src/router/methods/error.js +++ b/src/router/methods/error.js @@ -1,17 +1,19 @@ import analyticsMixin from "@/mixins/analytics-mixin"; import { routeData } from "@/router/constants/routes"; import router from "@/router"; +import store from "@/store"; +import { storeActions } from "@/constants/store-actions"; +import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper"; export async function bailout(errorPayload, forceRestart = false) { + if (forceRestart) { + await store.dispatch(storeActions.RESET_STATE); + deleteFunnelCookie(); + } + analyticsMixin.methods.pushPageErrorToDataLayer(errorPayload); - if (forceRestart) { - router.push({ - name: routeData.RESTART.name, - }); - } else { - router.push({ - name: routeData.ERROR.name, - }); - } + router.push({ + name: routeData.ERROR.name, + }); } From ac5b7187ad0bcc57c54f747d0e8c7907f68c8df9 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 27 May 2025 12:10:30 -0400 Subject: [PATCH 5/8] prettier --- src/router/methods/error.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/router/methods/error.js b/src/router/methods/error.js index 56d32cbaf..06eea69b0 100644 --- a/src/router/methods/error.js +++ b/src/router/methods/error.js @@ -10,7 +10,7 @@ export async function bailout(errorPayload, forceRestart = false) { await store.dispatch(storeActions.RESET_STATE); deleteFunnelCookie(); } - + analyticsMixin.methods.pushPageErrorToDataLayer(errorPayload); router.push({ From 84967d0cafb9703dd2050659ee877aa2f8c4e603 Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Tue, 27 May 2025 13:48:29 -0400 Subject: [PATCH 6/8] CASH-472 update donation slider box shadow to match Figma. --- src/experiment-components/donation-block.vue | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/experiment-components/donation-block.vue b/src/experiment-components/donation-block.vue index 30fe9f8ed..e504365fb 100644 --- a/src/experiment-components/donation-block.vue +++ b/src/experiment-components/donation-block.vue @@ -208,8 +208,9 @@ export default { justify-content: center; background: $blue-100; border-radius: 3rem; - box-shadow: 0px 0px 4px 1px rgba(0, 112, 209, 1) inset; - font-size: 0.875rem; + box-shadow: inset 0px 2px 4px 0px rgba(0, 112, 209, .2); + font-size: .875rem; + border: 1px solid $blue; .label { position: relative; display: inline-flex; @@ -231,7 +232,7 @@ export default { left: -2rem; background: $blue; border-radius: 3rem; - box-shadow: 0px 0px 0px 1px rgba(0, 112, 209, 1) inset; + box-shadow: 0px 3px 4px 0px rgba(66, 68, 90, 0.2); transition: transform 750ms cubic-bezier(0.02, 0.94, 0.09, 0.97); transform: translate3d(2rem, 0, 0); } From a1c6728c12bc78b84a67fcf50da1488fd875867c Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Tue, 27 May 2025 13:51:40 -0400 Subject: [PATCH 7/8] Format code. --- src/experiment-components/donation-block.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/experiment-components/donation-block.vue b/src/experiment-components/donation-block.vue index e504365fb..0e14588d7 100644 --- a/src/experiment-components/donation-block.vue +++ b/src/experiment-components/donation-block.vue @@ -208,8 +208,8 @@ export default { justify-content: center; background: $blue-100; border-radius: 3rem; - box-shadow: inset 0px 2px 4px 0px rgba(0, 112, 209, .2); - font-size: .875rem; + box-shadow: inset 0px 2px 4px 0px rgba(0, 112, 209, 0.2); + font-size: 0.875rem; border: 1px solid $blue; .label { position: relative; From 4046b41c996d7c010433c42db046afd25f72c525 Mon Sep 17 00:00:00 2001 From: Minojhini Valaiyapathi Date: Tue, 27 May 2025 14:07:08 -0400 Subject: [PATCH 8/8] CASH-805 - Hide chat button when sierra or salesforce chat are opened in different pages --- .../salesforce-webchat/salesforce-webchat.vue | 23 +++++++ .../sierra-webchat/sierra-webchat.vue | 16 ++++- .../funnel-header/funnel-header.vue | 63 +++++++++++++++---- 3 files changed, 89 insertions(+), 13 deletions(-) diff --git a/src/digital-components/salesforce-webchat/salesforce-webchat.vue b/src/digital-components/salesforce-webchat/salesforce-webchat.vue index 2cac40833..20ac8e44f 100644 --- a/src/digital-components/salesforce-webchat/salesforce-webchat.vue +++ b/src/digital-components/salesforce-webchat/salesforce-webchat.vue @@ -34,6 +34,29 @@ export default { script.src = "https://service.force.com/embeddedservice/5.0/esw.min.js"; script.onload = this.initializeSalesforceWebchat; document.body.appendChild(script); + + // Notify funnel-header about Salesforce chat open/close state + this._salesforceChatOpenObserver = new MutationObserver(() => { + const isOpen = !!document.querySelector(".embeddedServiceSidebar"); + window.dispatchEvent( + new CustomEvent("salesforce-chat-visibility", { detail: { open: isOpen } }) + ); + }); + this._salesforceChatOpenObserver.observe(document.body, { + childList: true, + subtree: true, + }); + }, + beforeUnmount() { + // Clean up event listeners and observers + window.removeEventListener( + "salesforce-chat-visibility", + this._handleSalesforceChatVisibility + ); + window.removeEventListener("sierra-chat-transfer", this._handleSierraToSalesforceTransfer); + if (this._salesforceChatOpenObserver) { + this._salesforceChatOpenObserver.disconnect(); + } }, methods: { initializeSalesforceWebchat() { diff --git a/src/digital-components/sierra-webchat/sierra-webchat.vue b/src/digital-components/sierra-webchat/sierra-webchat.vue index 0d686202f..e12ab053e 100644 --- a/src/digital-components/sierra-webchat/sierra-webchat.vue +++ b/src/digital-components/sierra-webchat/sierra-webchat.vue @@ -93,7 +93,6 @@ export default { Email: transfer.data.email, Subject: transfer.data.chat_summary, // for now passing in chat_summery in Subject. But this will be changed in future. }; - // Start chat immediately if required fields are present if ( window.embedded_svc.liveAgentAPI && typeof window.embedded_svc.liveAgentAPI.startChat === "function" @@ -106,10 +105,25 @@ export default { } }; window.addEventListener("sierra-chat-transfer", this._handleSierraTransfer); + + // Notify funnel-header about Sierra chat open/close state + this._sierraChatContainerObserver = new MutationObserver(() => { + const isOpen = !!document.querySelector("[data-sierra-chat-container]"); + window.dispatchEvent( + new CustomEvent("sierra-chat-visibility", { detail: { open: isOpen } }) + ); + }); + this._sierraChatContainerObserver.observe(document.body, { + childList: true, + subtree: true, + }); }, beforeUnmount() { window.removeEventListener("launch-sierra-webchat", this.triggerSierraChat); window.removeEventListener("sierra-chat-transfer", this._handleSierraTransfer); + if (this._sierraChatContainerObserver) { + this._sierraChatContainerObserver.disconnect(); + } }, }; diff --git a/src/fmg-components/funnel-header/funnel-header.vue b/src/fmg-components/funnel-header/funnel-header.vue index fc77336d3..f7d55b354 100644 --- a/src/fmg-components/funnel-header/funnel-header.vue +++ b/src/fmg-components/funnel-header/funnel-header.vue @@ -55,6 +55,8 @@ export default { return { globalAlertMessages: [], sierraChatOpen: false, + salesforceChatOpen: false, + isSalesforceTransferInProgress: false, }; }, props: { @@ -73,16 +75,19 @@ export default { return this.getCmsContent(this.cmsWidgetName, "LogoImage"); }, shouldShowWebchatButton() { - // Always update experiment flag before computing visibility - this.syncSierraExperimentFlag(); - // Show if Sierra experiment is active and chat is not open - if (this.webchatGlobalNonpersistedState.shouldLaunchSierra) { - return !this.sierraChatOpen; + // Hide the chat icon if Sierra chat is open + if (this.sierraChatOpen) { + return false; } - // Otherwise, use Salesforce logic + // Hide the chat icon if Salesforce chat is open or transfer is in progress + if (this.salesforceChatOpen || this.isSalesforceTransferInProgress) { + return false; + } + // Show if either Sierra is enabled or Salesforce button is available and not hidden by page return ( - !this.shouldHideWebchatButtonOnPage && - this.webchatGlobalNonpersistedState.showWebchatButton + (this.webchatGlobalNonpersistedState.shouldLaunchSierra || + this.webchatGlobalNonpersistedState.showWebchatButton) && + !this.shouldHideWebchatButtonOnPage ); }, }, @@ -123,6 +128,7 @@ export default { progressBar, }, mounted() { + this.syncSierraExperimentFlag(); // Check if alert event is on the bus const alertEvent = eventBus.readAndPopEventFromBus( globalEvents.Categories.GLOBAL_ALERT, @@ -144,14 +150,47 @@ export default { unknownAlertEvent.displayAlert = true; this.globalAlertMessages.push(unknownAlertEvent); } - // Listen for Sierra chat close event to re-enable the chat button if needed - this._handleSierraChatClosed = () => { - this.sierraChatOpen = false; + // Listen for Sierra chat open/close events from sierra-webchat + this._handleSierraChatVisibility = (event) => { + this.sierraChatOpen = !!(event.detail && event.detail.open); + if (this.sierraChatOpen) { + this.isSalesforceTransferInProgress = false; + } }; - window.addEventListener("sierra-chat-closed", this._handleSierraChatClosed); + window.addEventListener("sierra-chat-visibility", this._handleSierraChatVisibility); + + // Listen for Salesforce chat open/close events from salesforce-webchat + this._handleSalesforceChatVisibility = (event) => { + this.salesforceChatOpen = !!(event.detail && event.detail.open === true); + }; + window.addEventListener("salesforce-chat-visibility", this._handleSalesforceChatVisibility); + + // Listen for transfer event to set transfer-in-progress flag + this._handleSierraToSalesforceTransfer = () => { + this.isSalesforceTransferInProgress = true; + }; + window.addEventListener("sierra-chat-transfer", this._handleSierraToSalesforceTransfer); + + // Reset transfer flag when Salesforce chat opens + this._handleSalesforceChatOpened = (event) => { + if (event.detail && event.detail.open === true) { + this.isSalesforceTransferInProgress = false; + this.salesforceChatOpen = true; + } else { + this.salesforceChatOpen = false; + } + }; + window.addEventListener("salesforce-chat-visibility", this._handleSalesforceChatOpened); }, beforeUnmount() { window.removeEventListener("sierra-chat-closed", this._handleSierraChatClosed); + window.removeEventListener("sierra-chat-visibility", this._handleSierraChatVisibility); + window.removeEventListener( + "salesforce-chat-visibility", + this._handleSalesforceChatVisibility + ); + window.removeEventListener("sierra-chat-transfer", this._handleSierraToSalesforceTransfer); + window.removeEventListener("salesforce-chat-visibility", this._handleSalesforceChatOpened); }, };