-
Notifications
You must be signed in to change notification settings - Fork 212
Shopper Agent: Control floating button visibility and fix programmatic launch when hidden @W-20615482 #3651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
96c6821
bb37419
8f7cd80
3b7a2e8
04cfcc4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -73,13 +73,15 @@ const normalizeLocaleToSalesforce = (locale) => { | |
| * @param {string} embeddedServiceDeploymentUrl - URL of the embedded service deployment | ||
| * @param {string} scrt2Url - SCRT2 URL for the embedded messaging service | ||
| * @param {string} locale - BCP-47 locale for the embedded messaging service | ||
| * @param {string} [enableAgentFromFloatingButton='true'] - When 'false', hides the floating chat button on load | ||
| */ | ||
| const initEmbeddedMessaging = ( | ||
| salesforceOrgId, | ||
| embeddedServiceDeploymentName, | ||
| embeddedServiceDeploymentUrl, | ||
| scrt2Url, | ||
| locale | ||
| locale, | ||
| enableAgentFromFloatingButton = 'true' | ||
| ) => { | ||
| try { | ||
| if ( | ||
|
|
@@ -93,6 +95,9 @@ const initEmbeddedMessaging = ( | |
| window.embeddedservice_bootstrap.settings.language = salesforceLanguage | ||
| window.embeddedservice_bootstrap.settings.disableStreamingResponses = true | ||
| window.embeddedservice_bootstrap.settings.enableUserInputForConversationWithBot = false | ||
| // Hide floating chat button when enableAgentFromFloatingButton is 'false' | ||
| window.embeddedservice_bootstrap.settings.hideChatButtonOnLoad = | ||
| enableAgentFromFloatingButton !== 'true' | ||
| window.embeddedservice_bootstrap.init( | ||
| salesforceOrgId, | ||
| embeddedServiceDeploymentName, | ||
|
|
@@ -117,6 +122,7 @@ const initEmbeddedMessaging = ( | |
| * @param {string} scrt2Url - SCRT2 URL for the embedded messaging service | ||
| * @param {string} locale - BCP-47 locale for the embedded messaging service | ||
| * @param {string} refreshToken - Refresh token for the embedded messaging service | ||
| * @param {string} [enableAgentFromFloatingButton='true'] - When 'false', hides the floating chat button on load | ||
| */ | ||
| const useMiaw = ( | ||
| scriptLoadStatus, | ||
|
|
@@ -125,7 +131,8 @@ const useMiaw = ( | |
| embeddedServiceDeploymentUrl, | ||
| scrt2Url, | ||
| locale, | ||
| refreshToken | ||
| refreshToken, | ||
| enableAgentFromFloatingButton = 'true' | ||
|
Comment on lines
+134
to
+135
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Non-blocking. This function's argument list has grown quite a lot, I would encourage to have optional argument as an object as the last parameter, that way, it's future proof in case if you ever need to add more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't it become breaking changes @kevinxh ? I think the team will need to wait for another major breaking changes for the template to do that?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Its a breaking change if the signature is used outside this repo. |
||
| ) => { | ||
| useEffect(() => { | ||
| if (scriptLoadStatus.loaded && !scriptLoadStatus.error) { | ||
|
|
@@ -135,7 +142,7 @@ const useMiaw = ( | |
| embeddedServiceDeploymentUrl, | ||
| scrt2Url, | ||
| locale, | ||
| refreshToken | ||
| enableAgentFromFloatingButton | ||
| ) | ||
| } | ||
| }, [ | ||
|
|
@@ -145,7 +152,8 @@ const useMiaw = ( | |
| embeddedServiceDeploymentUrl, | ||
| scrt2Url, | ||
| locale, | ||
| refreshToken | ||
| refreshToken, | ||
| enableAgentFromFloatingButton | ||
| ]) | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,19 +9,27 @@ const onClient = typeof window !== 'undefined' | |
| /** | ||
| * Launch the chat using the embedded service bootstrap API | ||
| * | ||
| * When the floating chat button is hidden (hideChatButtonOnLoad=true), this function | ||
| * first shows the chat button via utilAPI.showChatButton() before launching the chat, | ||
| * ensuring the chat window opens correctly. | ||
| * | ||
| * @function launchChat | ||
| * @returns {void} | ||
| */ | ||
| export function launchChat() { | ||
| if (!onClient) return | ||
|
|
||
| try { | ||
| // Launch chat using the embedded service bootstrap API | ||
| if ( | ||
| window.embeddedservice_bootstrap?.utilAPI && | ||
| typeof window.embeddedservice_bootstrap.utilAPI.launchChat === 'function' | ||
| ) { | ||
| window.embeddedservice_bootstrap.utilAPI.launchChat() | ||
| const utilAPI = window.embeddedservice_bootstrap?.utilAPI | ||
| if (!utilAPI) return | ||
| const hideChatButtonOnLoad = | ||
| window.embeddedservice_bootstrap?.settings?.hideChatButtonOnLoad === true | ||
| if (hideChatButtonOnLoad && typeof utilAPI.showChatButton === 'function') { | ||
| utilAPI.showChatButton() | ||
| } | ||
|
|
||
| if (typeof utilAPI.launchChat === 'function') { | ||
| utilAPI.launchChat() | ||
|
Comment on lines
+23
to
+32
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nitpicking, the code might be more readable if validation is extract at the top of the function like the following structure. |
||
| } | ||
| } catch (error) { | ||
| console.error('Shopper Agent: Error launching chat', error) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -80,6 +80,54 @@ describe('shopper-agent-utils', () => { | |
| expect(() => launchChat()).not.toThrow() | ||
| }) | ||
|
|
||
| test('should call showChatButton before launchChat when hideChatButtonOnLoad is true', () => { | ||
| const mockShowChatButton = jest.fn() | ||
| const mockLaunchChat = jest.fn() | ||
|
|
||
| global.window = { | ||
| embeddedservice_bootstrap: { | ||
| settings: { | ||
| hideChatButtonOnLoad: true | ||
| }, | ||
| utilAPI: { | ||
| showChatButton: mockShowChatButton, | ||
| launchChat: mockLaunchChat | ||
| } | ||
| } | ||
| } | ||
|
|
||
| launchChat() | ||
|
|
||
| expect(mockShowChatButton).toHaveBeenCalledTimes(1) | ||
| expect(mockLaunchChat).toHaveBeenCalledTimes(1) | ||
| // showChatButton must be called before launchChat | ||
| expect(mockShowChatButton.mock.invocationCallOrder[0]).toBeLessThan( | ||
| mockLaunchChat.mock.invocationCallOrder[0] | ||
| ) | ||
|
Comment on lines
+104
to
+106
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
| }) | ||
|
|
||
| test('should not call showChatButton when hideChatButtonOnLoad is false', () => { | ||
| const mockShowChatButton = jest.fn() | ||
| const mockLaunchChat = jest.fn() | ||
|
|
||
| global.window = { | ||
| embeddedservice_bootstrap: { | ||
| settings: { | ||
| hideChatButtonOnLoad: false | ||
| }, | ||
| utilAPI: { | ||
| showChatButton: mockShowChatButton, | ||
| launchChat: mockLaunchChat | ||
| } | ||
| } | ||
| } | ||
|
|
||
| launchChat() | ||
|
|
||
| expect(mockShowChatButton).not.toHaveBeenCalled() | ||
| expect(mockLaunchChat).toHaveBeenCalledTimes(1) | ||
| }) | ||
|
|
||
| test('should handle errors and log error', () => { | ||
| const mockLaunchChat = jest.fn(() => { | ||
| throw new Error('Launch error') | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
non-blocking, I would encourage to have the init function parse the inputs and convert the string input into a boolean. Feel more maintainable for me and avoid
enableAgentFromFloatingButton !== 'true'