@salesforce/retail-react-app 9.0.0 → 9.1.0-nightly-20260216081036
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.
- package/CHANGELOG.md +3 -0
- package/app/components/otp-auth/index.jsx +1 -1
- package/app/components/shopper-agent/index.jsx +4 -2
- package/app/components/shopper-agent/index.test.js +25 -1
- package/app/hooks/use-miaw.js +12 -4
- package/app/hooks/use-miaw.test.js +13 -0
- package/app/utils/config-utils.js +2 -1
- package/app/utils/shopper-agent-utils.js +14 -6
- package/app/utils/shopper-agent-utils.test.js +48 -0
- package/config/default.js +1 -1
- package/config/mocks/default.js +1 -1
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
## v9.1.0-dev
|
|
2
|
+
- Add Node 24 support. Drop Node 16 support [#3652](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3652)
|
|
3
|
+
|
|
1
4
|
## v9.0.0 (Feb 12, 2026)
|
|
2
5
|
- [Feature] One Click Checkout (in Developer Preview) [#3552](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3552)
|
|
3
6
|
- [Feature] Add `fuzzyPathMatching` to reduce computational overhead of route generation at time of application load [#3530](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3530)
|
|
@@ -302,7 +302,7 @@ const OtpAuth = ({
|
|
|
302
302
|
)}
|
|
303
303
|
|
|
304
304
|
{/* Buttons */}
|
|
305
|
-
<HStack spacing={4} width="100%" justifyContent="
|
|
305
|
+
<HStack spacing={4} width="100%" justifyContent="center">
|
|
306
306
|
{!hideCheckoutAsGuestButton && (
|
|
307
307
|
<Button
|
|
308
308
|
onClick={handleCheckoutAsGuest}
|
|
@@ -175,7 +175,8 @@ const ShopperAgentWindow = ({commerceAgentConfiguration, domainUrl}) => {
|
|
|
175
175
|
commerceOrgId,
|
|
176
176
|
siteId,
|
|
177
177
|
enableConversationContext = 'false',
|
|
178
|
-
conversationContext = []
|
|
178
|
+
conversationContext = [],
|
|
179
|
+
enableAgentFromFloatingButton = 'true'
|
|
179
180
|
} = commerceAgentConfiguration
|
|
180
181
|
|
|
181
182
|
// User session identifier hook
|
|
@@ -352,7 +353,8 @@ const ShopperAgentWindow = ({commerceAgentConfiguration, domainUrl}) => {
|
|
|
352
353
|
embeddedServiceEndpoint,
|
|
353
354
|
scrt2Url,
|
|
354
355
|
locale.id,
|
|
355
|
-
refreshToken
|
|
356
|
+
refreshToken,
|
|
357
|
+
enableAgentFromFloatingButton
|
|
356
358
|
)
|
|
357
359
|
|
|
358
360
|
// This component doesn't render visible UI, only manages the messaging service
|
|
@@ -509,7 +509,31 @@ describe('ShopperAgent Component', () => {
|
|
|
509
509
|
'https://test.salesforce.com', // embeddedServiceEndpoint
|
|
510
510
|
'https://test.salesforce.com/scrt2.js', // scrt2Url
|
|
511
511
|
'en-US', // locale.id
|
|
512
|
-
'test-refresh-token' // refreshToken
|
|
512
|
+
'test-refresh-token', // refreshToken
|
|
513
|
+
'true' // enableAgentFromFloatingButton (default)
|
|
514
|
+
)
|
|
515
|
+
})
|
|
516
|
+
|
|
517
|
+
test('should call useMiaw with enableAgentFromFloatingButton false when configured', () => {
|
|
518
|
+
const props = {
|
|
519
|
+
...defaultProps,
|
|
520
|
+
commerceAgentConfiguration: {
|
|
521
|
+
...commerceAgentSettings,
|
|
522
|
+
enableAgentFromFloatingButton: 'false'
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
render(<ShopperAgent {...props} />)
|
|
527
|
+
|
|
528
|
+
expect(mockedUseMiaw).toHaveBeenCalledWith(
|
|
529
|
+
{loaded: true, error: false},
|
|
530
|
+
'test-org-id',
|
|
531
|
+
'test-service',
|
|
532
|
+
'https://test.salesforce.com',
|
|
533
|
+
'https://test.salesforce.com/scrt2.js',
|
|
534
|
+
'en-US',
|
|
535
|
+
'test-refresh-token',
|
|
536
|
+
'false' // enableAgentFromFloatingButton
|
|
513
537
|
)
|
|
514
538
|
})
|
|
515
539
|
|
package/app/hooks/use-miaw.js
CHANGED
|
@@ -73,13 +73,15 @@ const normalizeLocaleToSalesforce = (locale) => {
|
|
|
73
73
|
* @param {string} embeddedServiceDeploymentUrl - URL of the embedded service deployment
|
|
74
74
|
* @param {string} scrt2Url - SCRT2 URL for the embedded messaging service
|
|
75
75
|
* @param {string} locale - BCP-47 locale for the embedded messaging service
|
|
76
|
+
* @param {string} [enableAgentFromFloatingButton='true'] - When 'false', hides the floating chat button on load
|
|
76
77
|
*/
|
|
77
78
|
const initEmbeddedMessaging = (
|
|
78
79
|
salesforceOrgId,
|
|
79
80
|
embeddedServiceDeploymentName,
|
|
80
81
|
embeddedServiceDeploymentUrl,
|
|
81
82
|
scrt2Url,
|
|
82
|
-
locale
|
|
83
|
+
locale,
|
|
84
|
+
enableAgentFromFloatingButton = 'true'
|
|
83
85
|
) => {
|
|
84
86
|
try {
|
|
85
87
|
if (
|
|
@@ -93,6 +95,9 @@ const initEmbeddedMessaging = (
|
|
|
93
95
|
window.embeddedservice_bootstrap.settings.language = salesforceLanguage
|
|
94
96
|
window.embeddedservice_bootstrap.settings.disableStreamingResponses = true
|
|
95
97
|
window.embeddedservice_bootstrap.settings.enableUserInputForConversationWithBot = false
|
|
98
|
+
// Hide floating chat button when enableAgentFromFloatingButton is 'false'
|
|
99
|
+
window.embeddedservice_bootstrap.settings.hideChatButtonOnLoad =
|
|
100
|
+
enableAgentFromFloatingButton !== 'true'
|
|
96
101
|
window.embeddedservice_bootstrap.init(
|
|
97
102
|
salesforceOrgId,
|
|
98
103
|
embeddedServiceDeploymentName,
|
|
@@ -117,6 +122,7 @@ const initEmbeddedMessaging = (
|
|
|
117
122
|
* @param {string} scrt2Url - SCRT2 URL for the embedded messaging service
|
|
118
123
|
* @param {string} locale - BCP-47 locale for the embedded messaging service
|
|
119
124
|
* @param {string} refreshToken - Refresh token for the embedded messaging service
|
|
125
|
+
* @param {string} [enableAgentFromFloatingButton='true'] - When 'false', hides the floating chat button on load
|
|
120
126
|
*/
|
|
121
127
|
const useMiaw = (
|
|
122
128
|
scriptLoadStatus,
|
|
@@ -125,7 +131,8 @@ const useMiaw = (
|
|
|
125
131
|
embeddedServiceDeploymentUrl,
|
|
126
132
|
scrt2Url,
|
|
127
133
|
locale,
|
|
128
|
-
refreshToken
|
|
134
|
+
refreshToken,
|
|
135
|
+
enableAgentFromFloatingButton = 'true'
|
|
129
136
|
) => {
|
|
130
137
|
useEffect(() => {
|
|
131
138
|
if (scriptLoadStatus.loaded && !scriptLoadStatus.error) {
|
|
@@ -135,7 +142,7 @@ const useMiaw = (
|
|
|
135
142
|
embeddedServiceDeploymentUrl,
|
|
136
143
|
scrt2Url,
|
|
137
144
|
locale,
|
|
138
|
-
|
|
145
|
+
enableAgentFromFloatingButton
|
|
139
146
|
)
|
|
140
147
|
}
|
|
141
148
|
}, [
|
|
@@ -145,7 +152,8 @@ const useMiaw = (
|
|
|
145
152
|
embeddedServiceDeploymentUrl,
|
|
146
153
|
scrt2Url,
|
|
147
154
|
locale,
|
|
148
|
-
refreshToken
|
|
155
|
+
refreshToken,
|
|
156
|
+
enableAgentFromFloatingButton
|
|
149
157
|
])
|
|
150
158
|
}
|
|
151
159
|
|
|
@@ -141,6 +141,7 @@ describe('useMiaw hook', () => {
|
|
|
141
141
|
expect(
|
|
142
142
|
window.embeddedservice_bootstrap.settings.enableUserInputForConversationWithBot
|
|
143
143
|
).toBe(false)
|
|
144
|
+
expect(window.embeddedservice_bootstrap.settings.hideChatButtonOnLoad).toBe(false)
|
|
144
145
|
expect(window.embeddedservice_bootstrap.init).toHaveBeenCalledWith(
|
|
145
146
|
'test-org-id',
|
|
146
147
|
'test-deployment',
|
|
@@ -167,6 +168,18 @@ describe('useMiaw hook', () => {
|
|
|
167
168
|
expect(window.embeddedservice_bootstrap.init).not.toHaveBeenCalled()
|
|
168
169
|
})
|
|
169
170
|
|
|
171
|
+
test('should hide floating chat button when enableAgentFromFloatingButton is false', () => {
|
|
172
|
+
renderHook(() =>
|
|
173
|
+
useMiaw(
|
|
174
|
+
mockScriptLoadStatus,
|
|
175
|
+
...Object.values(mockParams),
|
|
176
|
+
'false' // enableAgentFromFloatingButton
|
|
177
|
+
)
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
expect(window.embeddedservice_bootstrap.settings.hideChatButtonOnLoad).toBe(true)
|
|
181
|
+
})
|
|
182
|
+
|
|
170
183
|
test('should handle different locale mappings', () => {
|
|
171
184
|
const testCases = [
|
|
172
185
|
{locale: 'en-US', expected: 'en_US'},
|
|
@@ -20,7 +20,8 @@ export const getCommerceAgentConfig = () => {
|
|
|
20
20
|
siteId: '',
|
|
21
21
|
enableConversationContext: 'false',
|
|
22
22
|
conversationContext: [],
|
|
23
|
-
enableAgentFromHeader: 'false'
|
|
23
|
+
enableAgentFromHeader: 'false',
|
|
24
|
+
enableAgentFromFloatingButton: 'false'
|
|
24
25
|
}
|
|
25
26
|
return getConfig().app.commerceAgent ?? defaults
|
|
26
27
|
}
|
|
@@ -9,6 +9,10 @@ const onClient = typeof window !== 'undefined'
|
|
|
9
9
|
/**
|
|
10
10
|
* Launch the chat using the embedded service bootstrap API
|
|
11
11
|
*
|
|
12
|
+
* When the floating chat button is hidden (hideChatButtonOnLoad=true), this function
|
|
13
|
+
* first shows the chat button via utilAPI.showChatButton() before launching the chat,
|
|
14
|
+
* ensuring the chat window opens correctly.
|
|
15
|
+
*
|
|
12
16
|
* @function launchChat
|
|
13
17
|
* @returns {void}
|
|
14
18
|
*/
|
|
@@ -16,12 +20,16 @@ export function launchChat() {
|
|
|
16
20
|
if (!onClient) return
|
|
17
21
|
|
|
18
22
|
try {
|
|
19
|
-
|
|
20
|
-
if (
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
) {
|
|
24
|
-
|
|
23
|
+
const utilAPI = window.embeddedservice_bootstrap?.utilAPI
|
|
24
|
+
if (!utilAPI) return
|
|
25
|
+
const hideChatButtonOnLoad =
|
|
26
|
+
window.embeddedservice_bootstrap?.settings?.hideChatButtonOnLoad === true
|
|
27
|
+
if (hideChatButtonOnLoad && typeof utilAPI.showChatButton === 'function') {
|
|
28
|
+
utilAPI.showChatButton()
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (typeof utilAPI.launchChat === 'function') {
|
|
32
|
+
utilAPI.launchChat()
|
|
25
33
|
}
|
|
26
34
|
} catch (error) {
|
|
27
35
|
console.error('Shopper Agent: Error launching chat', error)
|
|
@@ -80,6 +80,54 @@ describe('shopper-agent-utils', () => {
|
|
|
80
80
|
expect(() => launchChat()).not.toThrow()
|
|
81
81
|
})
|
|
82
82
|
|
|
83
|
+
test('should call showChatButton before launchChat when hideChatButtonOnLoad is true', () => {
|
|
84
|
+
const mockShowChatButton = jest.fn()
|
|
85
|
+
const mockLaunchChat = jest.fn()
|
|
86
|
+
|
|
87
|
+
global.window = {
|
|
88
|
+
embeddedservice_bootstrap: {
|
|
89
|
+
settings: {
|
|
90
|
+
hideChatButtonOnLoad: true
|
|
91
|
+
},
|
|
92
|
+
utilAPI: {
|
|
93
|
+
showChatButton: mockShowChatButton,
|
|
94
|
+
launchChat: mockLaunchChat
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
launchChat()
|
|
100
|
+
|
|
101
|
+
expect(mockShowChatButton).toHaveBeenCalledTimes(1)
|
|
102
|
+
expect(mockLaunchChat).toHaveBeenCalledTimes(1)
|
|
103
|
+
// showChatButton must be called before launchChat
|
|
104
|
+
expect(mockShowChatButton.mock.invocationCallOrder[0]).toBeLessThan(
|
|
105
|
+
mockLaunchChat.mock.invocationCallOrder[0]
|
|
106
|
+
)
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
test('should not call showChatButton when hideChatButtonOnLoad is false', () => {
|
|
110
|
+
const mockShowChatButton = jest.fn()
|
|
111
|
+
const mockLaunchChat = jest.fn()
|
|
112
|
+
|
|
113
|
+
global.window = {
|
|
114
|
+
embeddedservice_bootstrap: {
|
|
115
|
+
settings: {
|
|
116
|
+
hideChatButtonOnLoad: false
|
|
117
|
+
},
|
|
118
|
+
utilAPI: {
|
|
119
|
+
showChatButton: mockShowChatButton,
|
|
120
|
+
launchChat: mockLaunchChat
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
launchChat()
|
|
126
|
+
|
|
127
|
+
expect(mockShowChatButton).not.toHaveBeenCalled()
|
|
128
|
+
expect(mockLaunchChat).toHaveBeenCalledTimes(1)
|
|
129
|
+
})
|
|
130
|
+
|
|
83
131
|
test('should handle errors and log error', () => {
|
|
84
132
|
const mockLaunchChat = jest.fn(() => {
|
|
85
133
|
throw new Error('Launch error')
|
package/config/default.js
CHANGED
package/config/mocks/default.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/retail-react-app",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.1.0-nightly-20260216081036",
|
|
4
4
|
"license": "See license in LICENSE",
|
|
5
5
|
"author": "cc-pwa-kit@salesforce.com",
|
|
6
6
|
"ccExtensibility": {
|
|
@@ -46,10 +46,10 @@
|
|
|
46
46
|
"@loadable/component": "^5.15.3",
|
|
47
47
|
"@peculiar/webcrypto": "^1.4.2",
|
|
48
48
|
"@salesforce/cc-datacloud-typescript": "1.1.2",
|
|
49
|
-
"@salesforce/commerce-sdk-react": "5.
|
|
50
|
-
"@salesforce/pwa-kit-dev": "3.
|
|
51
|
-
"@salesforce/pwa-kit-react-sdk": "3.
|
|
52
|
-
"@salesforce/pwa-kit-runtime": "3.
|
|
49
|
+
"@salesforce/commerce-sdk-react": "5.1.0-nightly-20260216081036",
|
|
50
|
+
"@salesforce/pwa-kit-dev": "3.17.0-nightly-20260216081036",
|
|
51
|
+
"@salesforce/pwa-kit-react-sdk": "3.17.0-nightly-20260216081036",
|
|
52
|
+
"@salesforce/pwa-kit-runtime": "3.17.0-nightly-20260216081036",
|
|
53
53
|
"@tanstack/react-query": "^4.28.0",
|
|
54
54
|
"@tanstack/react-query-devtools": "^4.29.1",
|
|
55
55
|
"@testing-library/dom": "^9.0.1",
|
|
@@ -95,8 +95,8 @@
|
|
|
95
95
|
}
|
|
96
96
|
},
|
|
97
97
|
"engines": {
|
|
98
|
-
"node": "^
|
|
99
|
-
"npm": "^
|
|
98
|
+
"node": "^18.0.0 || ^20.0.0 || ^22.0.0 || ^24.0.0",
|
|
99
|
+
"npm": "^9.0.0 || ^10.0.0 || ^11.0.0"
|
|
100
100
|
},
|
|
101
101
|
"bundlesize": [
|
|
102
102
|
{
|
|
@@ -108,5 +108,5 @@
|
|
|
108
108
|
"maxSize": "366 kB"
|
|
109
109
|
}
|
|
110
110
|
],
|
|
111
|
-
"gitHead": "
|
|
111
|
+
"gitHead": "15a0f6607217820931e77fb527cdaf3055ff5466"
|
|
112
112
|
}
|