@envive-ai/react-hooks 0.3.10 → 0.3.12
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/dist/application/commerce-api.cjs +26 -22
- package/dist/application/commerce-api.d.cts +58 -0
- package/dist/application/commerce-api.d.ts +59 -0
- package/dist/application/commerce-api.js +16 -12
- package/dist/application/models/api/widgetText.d.cts +14 -0
- package/dist/application/models/api/widgetText.d.ts +14 -0
- package/dist/application/models/api/widgetTextRequest.d.cts +16 -0
- package/dist/application/models/api/widgetTextRequest.d.ts +16 -0
- package/dist/application/models/chatElementDisplayLocationV3.cjs +4 -1
- package/dist/application/models/chatElementDisplayLocationV3.d.cts +4 -1
- package/dist/application/models/chatElementDisplayLocationV3.d.ts +4 -1
- package/dist/application/models/chatElementDisplayLocationV3.js +4 -1
- package/dist/application/models/guards/api/index.cjs +7 -7
- package/dist/application/models/guards/api/index.js +7 -7
- package/dist/application/models/guards/api/isApiFormResponse.cjs +1 -1
- package/dist/application/models/guards/api/isApiFormResponse.js +1 -1
- package/dist/application/models/guards/api/isApiFormSubmittedResponseAttributes.cjs +1 -1
- package/dist/application/models/guards/api/isApiFormSubmittedResponseAttributes.js +1 -1
- package/dist/application/models/guards/api/isApiOrderResponseAttributes.cjs +1 -1
- package/dist/application/models/guards/api/isApiOrderResponseAttributes.js +1 -1
- package/dist/application/models/guards/api/isApiProductResponseAttributes.cjs +1 -1
- package/dist/application/models/guards/api/isApiProductResponseAttributes.js +1 -1
- package/dist/application/models/guards/api/isApiResponse.cjs +1 -1
- package/dist/application/models/guards/api/isApiResponse.js +1 -1
- package/dist/application/models/index.cjs +29 -29
- package/dist/application/models/index.d.cts +25 -25
- package/dist/application/models/index.d.ts +25 -25
- package/dist/application/models/index.js +29 -29
- package/dist/application/models/validators/validateGraphQLFrontendConfig.cjs +1 -1
- package/dist/application/models/validators/validateGraphQLFrontendConfig.js +1 -1
- package/dist/application/models/validators/validateResponse.cjs +3 -3
- package/dist/application/models/validators/validateResponse.js +3 -3
- package/dist/application/models/validators/validateUserEvent.cjs +2 -2
- package/dist/application/models/validators/validateUserEvent.js +2 -2
- package/dist/application/models/variantInfo/variantInfo.cjs +2 -1
- package/dist/application/models/variantInfo/variantInfo.d.cts +6 -1
- package/dist/application/models/variantInfo/variantInfo.d.ts +6 -1
- package/dist/application/models/variantInfo/variantInfo.js +2 -1
- package/dist/application/utils/analyticsUtils.cjs +1 -1
- package/dist/application/utils/analyticsUtils.js +1 -1
- package/dist/application/utils/nodeSelector.cjs +12 -14
- package/dist/application/utils/nodeSelector.js +12 -14
- package/dist/application/utils/widgetTextFromApiWidgetTextResponse.cjs +3 -1
- package/dist/application/utils/widgetTextFromApiWidgetTextResponse.js +3 -1
- package/dist/application/utils/widgetTextRequestToApiRequest.cjs +4 -1
- package/dist/application/utils/widgetTextRequestToApiRequest.js +4 -1
- package/dist/atoms/app/index.cjs +7 -7
- package/dist/atoms/app/index.d.cts +1 -1
- package/dist/atoms/app/index.d.ts +8 -8
- package/dist/atoms/app/index.js +1 -1
- package/dist/atoms/app/variant.cjs +44 -4
- package/dist/atoms/app/variant.d.cts +8 -8
- package/dist/atoms/app/variant.d.ts +8 -8
- package/dist/atoms/app/variant.js +44 -5
- package/dist/atoms/chat/chatState.d.cts +18 -18
- package/dist/atoms/chat/chatState.d.ts +17 -17
- package/dist/atoms/chat/form.cjs +1 -1
- package/dist/atoms/chat/form.d.cts +2 -2
- package/dist/atoms/chat/form.d.ts +2 -2
- package/dist/atoms/chat/form.js +1 -1
- package/dist/atoms/chat/index.d.cts +3 -3
- package/dist/atoms/chat/index.d.ts +2 -2
- package/dist/atoms/chat/lastMessage.d.cts +2 -2
- package/dist/atoms/chat/lastMessage.d.ts +2 -2
- package/dist/atoms/chat/messageQueue.d.cts +6 -6
- package/dist/atoms/chat/messageQueue.d.ts +6 -6
- package/dist/atoms/chat/performanceMetrics.d.cts +6 -6
- package/dist/atoms/chat/performanceMetrics.d.ts +6 -6
- package/dist/atoms/chat/renderedWidgetRefs.d.cts +2 -2
- package/dist/atoms/chat/renderedWidgetRefs.d.ts +2 -2
- package/dist/atoms/chat/replies.d.cts +3 -3
- package/dist/atoms/chat/replies.d.ts +3 -3
- package/dist/atoms/chat/suggestions.d.cts +2 -2
- package/dist/atoms/chat/suggestions.d.ts +2 -2
- package/dist/atoms/envive/enviveConfig.d.cts +19 -0
- package/dist/atoms/envive/enviveConfig.d.ts +19 -0
- package/dist/atoms/globalSearch/globalSearch.d.cts +5 -5
- package/dist/atoms/globalSearch/globalSearch.d.ts +5 -5
- package/dist/atoms/org/customerService.d.cts +6 -6
- package/dist/atoms/org/customerService.d.ts +6 -6
- package/dist/atoms/org/graphqlConfig.d.cts +4 -4
- package/dist/atoms/org/graphqlConfig.d.ts +4 -4
- package/dist/atoms/org/index.cjs +1 -1
- package/dist/atoms/org/index.js +1 -1
- package/dist/atoms/org/newOrgConfigAtom.d.cts +2 -2
- package/dist/atoms/org/newOrgConfigAtom.d.ts +2 -2
- package/dist/atoms/org/orgAnalyticsConfig.d.cts +5 -5
- package/dist/atoms/org/orgAnalyticsConfig.d.ts +5 -5
- package/dist/atoms/search/chatSearch.cjs +1 -1
- package/dist/atoms/search/chatSearch.d.cts +17 -17
- package/dist/atoms/search/chatSearch.d.ts +17 -17
- package/dist/atoms/search/chatSearch.js +1 -1
- package/dist/atoms/search/searchAPI.d.cts +13 -13
- package/dist/atoms/search/searchAPI.d.ts +13 -13
- package/dist/atoms/search/types.d.cts +1 -1
- package/dist/atoms/search/types.d.ts +1 -1
- package/dist/atoms/search/utils.d.cts +1 -1
- package/dist/atoms/search/utils.d.ts +1 -1
- package/dist/atoms/widget/chatPreviewLoading.d.cts +2 -2
- package/dist/atoms/widget/chatPreviewLoading.d.ts +2 -2
- package/dist/config/locators/components/search/index.d.cts +1 -1
- package/dist/contexts/amplitudeContext/amplitudeContext.cjs +9 -7
- package/dist/contexts/amplitudeContext/amplitudeContext.d.cts +2 -2
- package/dist/contexts/amplitudeContext/amplitudeContext.d.ts +2 -2
- package/dist/contexts/amplitudeContext/amplitudeContext.js +5 -3
- package/dist/contexts/amplitudeContext/index.cjs +1 -0
- package/dist/contexts/amplitudeContext/index.d.cts +2 -2
- package/dist/contexts/amplitudeContext/index.d.ts +2 -2
- package/dist/contexts/amplitudeContext/index.js +2 -2
- package/dist/contexts/cdnContext/cdnContext.cjs +3 -3
- package/dist/contexts/enviveConfigContext/enviveConfigContext.cjs +6 -5
- package/dist/contexts/enviveConfigContext/enviveConfigContext.d.cts +2 -1
- package/dist/contexts/enviveConfigContext/enviveConfigContext.d.ts +2 -1
- package/dist/contexts/enviveConfigContext/enviveConfigContext.js +3 -2
- package/dist/contexts/enviveContext/WindowChatToggleBinder.cjs +4 -3
- package/dist/contexts/enviveContext/WindowChatToggleBinder.js +4 -3
- package/dist/contexts/enviveContext/enviveContext.cjs +23 -16
- package/dist/contexts/enviveContext/enviveContext.d.cts +5 -1
- package/dist/contexts/enviveContext/enviveContext.d.ts +5 -1
- package/dist/contexts/enviveContext/enviveContext.js +23 -16
- package/dist/contexts/enviveContext/types.d.cts +1 -1
- package/dist/contexts/enviveContext/types.d.ts +1 -1
- package/dist/contexts/featureFlagServiceContext/featureFlagServiceContext.cjs +23 -2
- package/dist/contexts/featureFlagServiceContext/featureFlagServiceContext.d.cts +11 -2
- package/dist/contexts/featureFlagServiceContext/featureFlagServiceContext.d.ts +11 -2
- package/dist/contexts/featureFlagServiceContext/featureFlagServiceContext.js +23 -2
- package/dist/contexts/featureFlagServiceContext/index.d.cts +2 -2
- package/dist/contexts/featureFlagServiceContext/index.d.ts +2 -2
- package/dist/contexts/graphqlContext/graphqlContext.cjs +7 -7
- package/dist/contexts/graphqlContext/graphqlContext.d.cts +1 -1
- package/dist/contexts/graphqlContext/graphqlContext.d.ts +1 -1
- package/dist/contexts/graphqlContext/graphqlContext.js +3 -3
- package/dist/contexts/graphqlContext/mockV3Config.cjs +10 -4
- package/dist/contexts/graphqlContext/mockV3Config.js +10 -4
- package/dist/contexts/hardcopyContext/hardcopyContext.cjs +60 -6
- package/dist/contexts/hardcopyContext/hardcopyContext.d.cts +8 -3
- package/dist/contexts/hardcopyContext/hardcopyContext.d.ts +8 -3
- package/dist/contexts/hardcopyContext/hardcopyContext.js +58 -4
- package/dist/contexts/newOrgConfigContext/newOrgConfigContext.cjs +3 -3
- package/dist/contexts/pageContext/mapping.cjs +6 -2
- package/dist/contexts/pageContext/mapping.js +6 -2
- package/dist/contexts/pageContext/pageContext.cjs +12 -7
- package/dist/contexts/pageContext/pageContext.js +10 -5
- package/dist/contexts/pageContext/types.d.cts +7 -3
- package/dist/contexts/pageContext/types.d.ts +7 -3
- package/dist/contexts/salesAgentContext/chatAPI.cjs +101 -12
- package/dist/contexts/salesAgentContext/chatAPI.d.cts +8 -4
- package/dist/contexts/salesAgentContext/chatAPI.d.ts +8 -4
- package/dist/contexts/salesAgentContext/chatAPI.js +103 -14
- package/dist/contexts/salesAgentContext/salesAgentContext.cjs +1 -1
- package/dist/contexts/salesAgentContext/salesAgentContext.js +1 -1
- package/dist/contexts/salesAgentContext/salesAgentService.cjs +52 -10
- package/dist/contexts/salesAgentContext/salesAgentService.js +50 -8
- package/dist/contexts/searchContext/searchContext.cjs +4 -4
- package/dist/contexts/searchContext/searchContext.js +1 -1
- package/dist/contexts/systemSettingsContext/systemSettingsContext.cjs +3 -3
- package/dist/contexts/systemSettingsContext/systemSettingsContext.d.cts +2 -2
- package/dist/contexts/types.cjs +1 -1
- package/dist/contexts/types.d.cts +10 -3
- package/dist/contexts/types.d.ts +10 -3
- package/dist/contexts/types.js +1 -1
- package/dist/contexts/typesV3.cjs +2 -1
- package/dist/contexts/typesV3.d.cts +28 -7
- package/dist/contexts/typesV3.d.ts +26 -5
- package/dist/contexts/typesV3.js +2 -1
- package/dist/contexts/userIdentityContext/userIdentityContext.cjs +3 -3
- package/dist/contexts/widgetConfigContext/widgetConfigContext.cjs +1 -1
- package/dist/contexts/widgetConfigContext/widgetConfigContext.js +1 -1
- package/dist/hooks/AppDetails/useAppDetails.cjs +6 -6
- package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.cts +2 -2
- package/dist/hooks/ImageResolver/useImageResolver.cjs +3 -3
- package/dist/hooks/Search/useSearch.cjs +4 -4
- package/dist/hooks/Search/useSearch.d.cts +1 -1
- package/dist/hooks/Search/useSearch.d.ts +1 -1
- package/dist/hooks/Search/useSearch.js +1 -1
- package/dist/services/amplitudeService/amplitudeService.cjs +49 -11
- package/dist/services/amplitudeService/amplitudeService.d.cts +18 -3
- package/dist/services/amplitudeService/amplitudeService.d.ts +18 -3
- package/dist/services/amplitudeService/amplitudeService.js +49 -12
- package/dist/services/amplitudeService/index.cjs +1 -0
- package/dist/services/amplitudeService/index.d.cts +2 -2
- package/dist/services/amplitudeService/index.d.ts +2 -2
- package/dist/services/amplitudeService/index.js +2 -2
- package/dist/types/customerService.d.cts +3 -1
- package/dist/types/customerService.d.ts +1 -1
- package/dist/types/enviveConfig.d.cts +4 -1
- package/dist/types/enviveConfig.d.ts +4 -1
- package/package.json +10 -2
- package/src/application/commerce-api.ts +25 -20
- package/src/application/models/api/widgetText.ts +2 -0
- package/src/application/models/api/widgetTextRequest.ts +2 -0
- package/src/application/models/chatElementDisplayLocationV3.ts +3 -0
- package/src/application/models/variantInfo/variantInfo.ts +5 -0
- package/src/application/utils/nodeSelector.ts +15 -14
- package/src/application/utils/widgetTextFromApiWidgetTextResponse.ts +2 -0
- package/src/application/utils/widgetTextRequestToApiRequest.ts +5 -0
- package/src/atoms/app/variant.ts +56 -2
- package/src/contexts/amplitudeContext/__tests__/amplitudeContext.test.tsx +2 -0
- package/src/contexts/amplitudeContext/amplitudeContext.tsx +5 -1
- package/src/contexts/enviveConfigContext/enviveConfigContext.tsx +3 -0
- package/src/contexts/enviveContext/WindowChatToggleBinder.tsx +5 -1
- package/src/contexts/enviveContext/enviveContext.tsx +10 -3
- package/src/contexts/featureFlagServiceContext/featureFlagServiceContext.tsx +36 -0
- package/src/contexts/graphqlContext/mockV3Config.ts +13 -7
- package/src/contexts/hardcopyContext/hardcopyContext.tsx +67 -4
- package/src/contexts/pageContext/mapping.ts +13 -1
- package/src/contexts/pageContext/pageContext.tsx +9 -4
- package/src/contexts/pageContext/types.ts +7 -1
- package/src/contexts/salesAgentContext/chatAPI.ts +105 -13
- package/src/contexts/salesAgentContext/salesAgentService.ts +66 -4
- package/src/contexts/types.ts +11 -2
- package/src/contexts/typesV3.ts +42 -16
- package/src/services/amplitudeService/__tests__/amplitudeService.test.ts +80 -0
- package/src/services/amplitudeService/amplitudeService.ts +55 -11
- package/src/types/enviveConfig.ts +3 -0
|
@@ -31,6 +31,9 @@ export const coreWidgetTypeToApiWidgetType = (coreWidgetType: WidgetTypeV3): Wid
|
|
|
31
31
|
return WidgetType.FloatingButtonV3;
|
|
32
32
|
case WidgetTypeV3.PromptButtonCarouselWithImageV3:
|
|
33
33
|
return WidgetType.SingleImagePromptV3;
|
|
34
|
+
// TODO: Temporary hack to make it work with FPSA.
|
|
35
|
+
case WidgetTypeV3.FullPageSalesAgentV3:
|
|
36
|
+
return WidgetType.FloatingChatV3;
|
|
34
37
|
default:
|
|
35
38
|
throw new Error(`Unsupported widget type: ${coreWidgetType}`);
|
|
36
39
|
}
|
|
@@ -39,9 +42,11 @@ export const coreWidgetTypeToApiWidgetType = (coreWidgetType: WidgetTypeV3): Wid
|
|
|
39
42
|
export const coreWidgetTextRequestToApiRequest = (
|
|
40
43
|
coreWidgetTextRequest: CoreWidgetTextRequest,
|
|
41
44
|
): ApiWidgetTextRequest => ({
|
|
45
|
+
id: coreWidgetTextRequest.requestId,
|
|
42
46
|
context: coreContextToApiContext(coreWidgetTextRequest.context),
|
|
43
47
|
feature_flags: coreWidgetTextRequest.featureFlags,
|
|
44
48
|
language: coreWidgetTextRequest.language,
|
|
45
49
|
url: coreWidgetTextRequest.url,
|
|
50
|
+
org_base_config_version: coreWidgetTextRequest.overrideConfigVersion,
|
|
46
51
|
widget_type: coreWidgetTypeToApiWidgetType(coreWidgetTextRequest.widgetType),
|
|
47
52
|
});
|
package/src/atoms/app/variant.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { atomWithStorage } from 'jotai/utils';
|
|
2
|
-
import { atom } from 'jotai';
|
|
3
1
|
import {
|
|
4
2
|
UserEvent as ApiUserEvent,
|
|
5
3
|
PageVisitCategory,
|
|
6
4
|
SupportedEventResponse,
|
|
7
5
|
} from '@spiffy-ai/commerce-api-client';
|
|
6
|
+
import { atom } from 'jotai';
|
|
7
|
+
import { atomWithStorage } from 'jotai/utils';
|
|
8
8
|
import {
|
|
9
9
|
PDPVariantInfo,
|
|
10
10
|
PLPVariantInfo,
|
|
@@ -15,6 +15,8 @@ import {
|
|
|
15
15
|
} from 'src/application/models';
|
|
16
16
|
import { sessionStorageUtil } from 'src/atoms/atomStore';
|
|
17
17
|
import type { PageVariantInfo } from 'src/contexts/pageContext/types';
|
|
18
|
+
import Logger from 'src/application/logging/logger';
|
|
19
|
+
import { ShowFloatingButtonOptions } from 'src/contexts/types';
|
|
18
20
|
|
|
19
21
|
export interface SupportedEvent extends Pick<
|
|
20
22
|
SupportedEventResponse,
|
|
@@ -167,6 +169,7 @@ const internalPlpIdAtom = atom<string>();
|
|
|
167
169
|
const internalUrlAtom = atom<string>();
|
|
168
170
|
const internalPageVisitCategoryAtom = atom<PageVisitCategory>();
|
|
169
171
|
const internalVariantAtom = atom<'pdp' | 'plp' | 'search' | 'page_visit'>('pdp');
|
|
172
|
+
const internalFloatingButtonOverrideAtom = atom<ShowFloatingButtonOptions>();
|
|
170
173
|
|
|
171
174
|
export const variantIdAtom = atom(get => get(internalVariantIdAtom));
|
|
172
175
|
export const productIdAtom = atom(get => get(internalProductIdAtom));
|
|
@@ -176,11 +179,13 @@ export const plpIdAtom = atom(get => get(internalPlpIdAtom));
|
|
|
176
179
|
export const urlAtom = atom(get => get(internalUrlAtom));
|
|
177
180
|
export const pageVisitCategoryAtom = atom(get => get(internalPageVisitCategoryAtom));
|
|
178
181
|
export const variantAtom = atom(get => get(internalVariantAtom));
|
|
182
|
+
export const floatingButtonOverrideAtom = atom(get => get(internalFloatingButtonOverrideAtom));
|
|
179
183
|
export const hasParsedVariantInfoAtom = atom(false);
|
|
180
184
|
|
|
181
185
|
export const variantInfoAtom = atom(
|
|
182
186
|
(get): VariantInfo => {
|
|
183
187
|
const variant = get(variantAtom);
|
|
188
|
+
// TODO: Maybe I need to return the fbo here too.
|
|
184
189
|
if (variant === VariantTypeEnum.Pdp) {
|
|
185
190
|
return {
|
|
186
191
|
variantId: get(variantIdAtom),
|
|
@@ -188,6 +193,7 @@ export const variantInfoAtom = atom(
|
|
|
188
193
|
productId: get(productIdAtom),
|
|
189
194
|
parentProductId: get(parentProductIdAtom),
|
|
190
195
|
url: get(urlAtom),
|
|
196
|
+
floatingButtonOverride: get(floatingButtonOverrideAtom),
|
|
191
197
|
} as PDPVariantInfo;
|
|
192
198
|
}
|
|
193
199
|
if (variant === VariantTypeEnum.Plp) {
|
|
@@ -196,6 +202,7 @@ export const variantInfoAtom = atom(
|
|
|
196
202
|
variant,
|
|
197
203
|
plpId: get(plpIdAtom),
|
|
198
204
|
url: get(urlAtom),
|
|
205
|
+
floatingButtonOverride: get(floatingButtonOverrideAtom),
|
|
199
206
|
} as PLPVariantInfo;
|
|
200
207
|
}
|
|
201
208
|
if (variant === VariantTypeEnum.PageVisit) {
|
|
@@ -204,6 +211,7 @@ export const variantInfoAtom = atom(
|
|
|
204
211
|
variant,
|
|
205
212
|
url: get(urlAtom),
|
|
206
213
|
pageVisitCategory: get(pageVisitCategoryAtom),
|
|
214
|
+
floatingButtonOverride: get(floatingButtonOverrideAtom),
|
|
207
215
|
} as PageVisitVariantInfo;
|
|
208
216
|
}
|
|
209
217
|
throw new Error('Invalid variantInfo details');
|
|
@@ -211,6 +219,7 @@ export const variantInfoAtom = atom(
|
|
|
211
219
|
(_, set, newVariant: VariantInfo) => {
|
|
212
220
|
set(internalVariantAtom, newVariant.variant);
|
|
213
221
|
set(internalVariantIdAtom, newVariant.variantId);
|
|
222
|
+
set(internalFloatingButtonOverrideAtom, newVariant.floatingButtonOverride);
|
|
214
223
|
if (newVariant.variant === VariantTypeEnum.Pdp) {
|
|
215
224
|
set(internalProductIdAtom, newVariant.productId);
|
|
216
225
|
set(internalParentProductIdAtom, newVariant.parentProductId);
|
|
@@ -227,6 +236,51 @@ export const variantInfoAtom = atom(
|
|
|
227
236
|
},
|
|
228
237
|
);
|
|
229
238
|
|
|
239
|
+
const getPageVisitContext = (pageVisitCategory: PageVisitCategory | undefined) => {
|
|
240
|
+
if (pageVisitCategory === PageVisitCategory.Search) {
|
|
241
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
242
|
+
const searchTerm = searchParams.get('esq');
|
|
243
|
+
return {
|
|
244
|
+
page_type: 'search',
|
|
245
|
+
page_id: searchTerm,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
if (pageVisitCategory === PageVisitCategory.Homepage) {
|
|
249
|
+
return {
|
|
250
|
+
page_type: 'homepage',
|
|
251
|
+
page_id: window.location.href,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
return {
|
|
255
|
+
page_type: 'other',
|
|
256
|
+
page_id: window.location.href,
|
|
257
|
+
};
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
export const analyticsContextAtom = atom(get => {
|
|
261
|
+
const variantInfo = get(variantInfoAtom);
|
|
262
|
+
if (variantInfo.variant === VariantTypeEnum.Pdp) {
|
|
263
|
+
return {
|
|
264
|
+
page_type: 'pdp',
|
|
265
|
+
page_id: variantInfo.productId,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
if (variantInfo.variant === VariantTypeEnum.Plp) {
|
|
269
|
+
return {
|
|
270
|
+
page_type: 'plp',
|
|
271
|
+
page_id: variantInfo.plpId,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
if (variantInfo.variant === VariantTypeEnum.PageVisit) {
|
|
275
|
+
return getPageVisitContext(variantInfo.pageVisitCategory);
|
|
276
|
+
}
|
|
277
|
+
Logger.logWarn('[envive-ai] Invalid variantInfo', undefined, { variantInfo });
|
|
278
|
+
return {
|
|
279
|
+
page_type: 'other',
|
|
280
|
+
page_id: window.location.href,
|
|
281
|
+
};
|
|
282
|
+
});
|
|
283
|
+
|
|
230
284
|
// Atoms for page context - can be set directly by PageProvider or for storybook/testing
|
|
231
285
|
export const pageUserEventAtom = atom<UserEvent | undefined>(undefined);
|
|
232
286
|
export const pageVariantInfoAtom = atom<PageVariantInfo | undefined>(undefined);
|
|
@@ -376,6 +376,7 @@ describe('AmplitudeProvider - React Context Integration', () => {
|
|
|
376
376
|
dataResidency: 'EU',
|
|
377
377
|
orgId: 'test-org-id',
|
|
378
378
|
show: true,
|
|
379
|
+
enviveOn: true,
|
|
379
380
|
getLocalStorageItem: mockGetLocalStorageItem,
|
|
380
381
|
featureFlagService: new FeatureFlagService([]),
|
|
381
382
|
env: 'test', // Provide required fields to match AmplitudeServiceConfig
|
|
@@ -415,6 +416,7 @@ describe('AmplitudeProvider - React Context Integration', () => {
|
|
|
415
416
|
dataResidency: 'EU',
|
|
416
417
|
orgId: 'test-org-id',
|
|
417
418
|
show: true,
|
|
419
|
+
enviveOn: true,
|
|
418
420
|
getLocalStorageItem: mockGetLocalStorageItem,
|
|
419
421
|
featureFlagService: new FeatureFlagService([]),
|
|
420
422
|
env: 'test',
|
|
@@ -13,11 +13,12 @@ import { useEnviveConfig } from 'src/contexts/enviveConfigContext/enviveConfigCo
|
|
|
13
13
|
import { useFeatureFlagService } from 'src/contexts/featureFlagServiceContext/featureFlagServiceContext';
|
|
14
14
|
import {
|
|
15
15
|
AmplitudeService,
|
|
16
|
+
EnviveMetricsEventName,
|
|
16
17
|
SpiffyMetricsEventName,
|
|
17
18
|
TrackEventParams,
|
|
18
19
|
} from 'src/services/amplitudeService/amplitudeService';
|
|
19
20
|
|
|
20
|
-
export { SpiffyMetricsEventName };
|
|
21
|
+
export { EnviveMetricsEventName, SpiffyMetricsEventName };
|
|
21
22
|
|
|
22
23
|
interface AmplitudeContextType {
|
|
23
24
|
trackEvent: (params: TrackEventParams) => Promise<void>;
|
|
@@ -43,6 +44,7 @@ export const AmplitudeProvider: React.FC<{
|
|
|
43
44
|
variantUrlOverride,
|
|
44
45
|
variantInfoOverride,
|
|
45
46
|
show,
|
|
47
|
+
enviveOn,
|
|
46
48
|
orgId,
|
|
47
49
|
orgShortName,
|
|
48
50
|
featureGates,
|
|
@@ -72,6 +74,7 @@ export const AmplitudeProvider: React.FC<{
|
|
|
72
74
|
featureFlagService,
|
|
73
75
|
orgGaConfig,
|
|
74
76
|
show: show ?? false,
|
|
77
|
+
enviveOn: enviveOn ?? false,
|
|
75
78
|
getLocalStorageItem: getItem,
|
|
76
79
|
});
|
|
77
80
|
setService(amplitudeService);
|
|
@@ -91,6 +94,7 @@ export const AmplitudeProvider: React.FC<{
|
|
|
91
94
|
variantUrlOverride,
|
|
92
95
|
variantInfoOverride,
|
|
93
96
|
show,
|
|
97
|
+
enviveOn,
|
|
94
98
|
featureGates,
|
|
95
99
|
getItem,
|
|
96
100
|
externalAmplitudeService,
|
|
@@ -24,6 +24,7 @@ interface EnviveConfigProviderProps {
|
|
|
24
24
|
variantUrlOverride?: string;
|
|
25
25
|
variantInfoOverride?: any;
|
|
26
26
|
show?: boolean;
|
|
27
|
+
enviveOn?: boolean;
|
|
27
28
|
publicKey?: string;
|
|
28
29
|
featureGates?: OrgConfigFeatureGate[]; // New prop for feature gates
|
|
29
30
|
}
|
|
@@ -45,6 +46,7 @@ export const EnviveConfigProvider: React.FC<EnviveConfigProviderProps> = ({
|
|
|
45
46
|
variantUrlOverride,
|
|
46
47
|
variantInfoOverride,
|
|
47
48
|
show,
|
|
49
|
+
enviveOn,
|
|
48
50
|
publicKey,
|
|
49
51
|
featureGates, // Destructure new prop
|
|
50
52
|
}) => {
|
|
@@ -66,6 +68,7 @@ export const EnviveConfigProvider: React.FC<EnviveConfigProviderProps> = ({
|
|
|
66
68
|
variantUrlOverride,
|
|
67
69
|
variantInfoOverride,
|
|
68
70
|
show,
|
|
71
|
+
enviveOn,
|
|
69
72
|
publicKey,
|
|
70
73
|
featureGates, // Add to config
|
|
71
74
|
};
|
|
@@ -25,7 +25,11 @@ export const WindowChatToggleBinder = () => {
|
|
|
25
25
|
toggleChatRef.current = (triggerId?: string) => hook.toggle(triggerLocation, triggerId);
|
|
26
26
|
isOpenRef.current = hook.isOpen;
|
|
27
27
|
openChatWithPromptRef.current = (prompt: string, triggerId?: string) => {
|
|
28
|
-
onTypedMessageSubmitted({
|
|
28
|
+
onTypedMessageSubmitted({
|
|
29
|
+
query: prompt,
|
|
30
|
+
userTyped: false,
|
|
31
|
+
displayLocation: ChatElementDisplayLocationV3.WINDOW_API_CALL,
|
|
32
|
+
});
|
|
29
33
|
hook.openChat(triggerLocation, triggerId);
|
|
30
34
|
};
|
|
31
35
|
}, [hook, onTypedMessageSubmitted, triggerLocation]);
|
|
@@ -17,7 +17,8 @@ import { EnviveAgent } from './types';
|
|
|
17
17
|
import { SearchProvider } from '../searchContext';
|
|
18
18
|
import { SalesAgentProvider } from '../salesAgentContext/salesAgentContext';
|
|
19
19
|
import { SystemSettingsContextProvider } from '../systemSettingsContext';
|
|
20
|
-
import { HardcopyProvider } from '../hardcopyContext';
|
|
20
|
+
import { HardcopyProvider, HardcopyResponse } from '../hardcopyContext';
|
|
21
|
+
import { WidgetTypeV3 } from '../typesV3';
|
|
21
22
|
import { WidgetConfigProvider } from '../widgetConfigContext';
|
|
22
23
|
import { PageProvider } from '../pageContext';
|
|
23
24
|
import { UiConfigProvider } from '../uiConfigContext';
|
|
@@ -45,6 +46,7 @@ interface EnviveProviderProps extends AgentWrapperProps {
|
|
|
45
46
|
variantUrlOverride?: string;
|
|
46
47
|
variantInfoOverride?: any;
|
|
47
48
|
show?: boolean;
|
|
49
|
+
enviveOn?: boolean;
|
|
48
50
|
publicKey?: string;
|
|
49
51
|
featureGates?: OrgConfigFeatureGate[]; // New prop for feature gates
|
|
50
52
|
featureFlagService?: FeatureFlagService;
|
|
@@ -56,6 +58,7 @@ interface EnviveProviderProps extends AgentWrapperProps {
|
|
|
56
58
|
previewMode?: boolean;
|
|
57
59
|
overrideConfig?: GraphQlConfigValues;
|
|
58
60
|
mockSalesAgentData?: any;
|
|
61
|
+
hardcopyOverride?: Partial<Record<WidgetTypeV3, HardcopyResponse>>;
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
const SearchAgentWrapper: React.FC<AgentWrapperProps> = ({ children, enabledAgents }) => {
|
|
@@ -67,6 +70,7 @@ const SearchAgentWrapper: React.FC<AgentWrapperProps> = ({ children, enabledAgen
|
|
|
67
70
|
|
|
68
71
|
interface SalesAgentWrapperProps extends AgentWrapperProps {
|
|
69
72
|
previewMode?: boolean;
|
|
73
|
+
showDebugBar: boolean;
|
|
70
74
|
mockSalesAgentData?: any;
|
|
71
75
|
}
|
|
72
76
|
|
|
@@ -74,13 +78,14 @@ const SalesAgentWrapper: React.FC<SalesAgentWrapperProps> = ({
|
|
|
74
78
|
children,
|
|
75
79
|
enabledAgents,
|
|
76
80
|
previewMode,
|
|
81
|
+
showDebugBar,
|
|
77
82
|
mockSalesAgentData,
|
|
78
83
|
}) => {
|
|
79
84
|
if (!enabledAgents.includes(EnviveAgent.SalesAgent)) {
|
|
80
85
|
return children;
|
|
81
86
|
}
|
|
82
87
|
return (
|
|
83
|
-
<SystemSettingsContextProvider>
|
|
88
|
+
<SystemSettingsContextProvider showDebugBar={showDebugBar}>
|
|
84
89
|
<SalesAgentProvider
|
|
85
90
|
previewMode={previewMode}
|
|
86
91
|
mockData={mockSalesAgentData}
|
|
@@ -103,6 +108,7 @@ export const EnviveProvider: React.FC<EnviveProviderProps> = ({
|
|
|
103
108
|
mockV3ConfigToDeprecatedConfig = false,
|
|
104
109
|
requestV3Config = false,
|
|
105
110
|
mockSalesAgentData,
|
|
111
|
+
hardcopyOverride,
|
|
106
112
|
...config
|
|
107
113
|
}) => {
|
|
108
114
|
const [userId, setUserId] = useState<string>('');
|
|
@@ -181,12 +187,13 @@ export const EnviveProvider: React.FC<EnviveProviderProps> = ({
|
|
|
181
187
|
<PageProvider previewMode={previewMode}>
|
|
182
188
|
<UiConfigProvider>
|
|
183
189
|
<WidgetConfigProvider>
|
|
184
|
-
<HardcopyProvider>
|
|
190
|
+
<HardcopyProvider hardcopyOverride={hardcopyOverride}>
|
|
185
191
|
<EnviveCssProvider>
|
|
186
192
|
<SearchAgentWrapper enabledAgents={enabledAgents}>
|
|
187
193
|
<WindowChatToggleBinder />
|
|
188
194
|
<SalesAgentWrapper
|
|
189
195
|
enabledAgents={enabledAgents}
|
|
196
|
+
showDebugBar={config.enviveOn || false}
|
|
190
197
|
previewMode={previewMode}
|
|
191
198
|
mockSalesAgentData={mockSalesAgentData}
|
|
192
199
|
>
|
|
@@ -5,6 +5,14 @@ import Logger from 'src/application/logging/logger';
|
|
|
5
5
|
|
|
6
6
|
const FEATURE_FLAGS_STORAGE_KEY = 'spiffy-feature-flags';
|
|
7
7
|
|
|
8
|
+
export interface FullFlagValue {
|
|
9
|
+
resolved: boolean;
|
|
10
|
+
initial: boolean | undefined;
|
|
11
|
+
query_param_override: boolean | undefined;
|
|
12
|
+
window_param_override: boolean | undefined;
|
|
13
|
+
stored_override: boolean | undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
8
16
|
// This is the class that was previously implicitly used or defined elsewhere
|
|
9
17
|
export class FeatureFlagService {
|
|
10
18
|
private featureGates: OrgConfigFeatureGate[];
|
|
@@ -124,6 +132,34 @@ export class FeatureFlagService {
|
|
|
124
132
|
);
|
|
125
133
|
};
|
|
126
134
|
|
|
135
|
+
getFullFlagValue = (featureGate: FeatureGates): FullFlagValue => {
|
|
136
|
+
const gateValue = this.featureGates.find(gate => gate.name === featureGate);
|
|
137
|
+
return {
|
|
138
|
+
resolved: this.isFeatureGateEnabled(featureGate),
|
|
139
|
+
initial: gateValue?.value,
|
|
140
|
+
query_param_override: FeatureFlagService.getQueryParamFeatureGateOverrides(featureGate),
|
|
141
|
+
window_param_override: FeatureFlagService.getWindowFeatureGateOverrides(featureGate),
|
|
142
|
+
stored_override: FeatureFlagService.getStoredFeatureGateOverrides(featureGate),
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
getFullFlagValues = (): Record<string, FullFlagValue> => {
|
|
147
|
+
const featureGates = Object.values(FeatureGates).map((featureGate: FeatureGates) => [
|
|
148
|
+
featureGate,
|
|
149
|
+
this.getFullFlagValue(featureGate),
|
|
150
|
+
]);
|
|
151
|
+
|
|
152
|
+
return featureGates.length > 0
|
|
153
|
+
? featureGates.reduce<Record<string, FullFlagValue>>((acc, entry) => {
|
|
154
|
+
const [name, value] = entry as [FeatureGates, FullFlagValue];
|
|
155
|
+
if (name && value != null) {
|
|
156
|
+
return { ...acc, [`feature_gate.${name}`]: value };
|
|
157
|
+
}
|
|
158
|
+
return acc;
|
|
159
|
+
}, {})
|
|
160
|
+
: {};
|
|
161
|
+
};
|
|
162
|
+
|
|
127
163
|
static persistFeatureGateOverrides(): void {
|
|
128
164
|
if (typeof window === 'undefined' || typeof window.localStorage === 'undefined') {
|
|
129
165
|
return;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ColorMappingV3, ColorNames, colorVar } from 'src/application/models/colorsConfigV3';
|
|
3
|
-
import { CamelCasedPropertiesDeep } from 'src/application/models';
|
|
1
|
+
import { ChatHeaderVariant } from '@envive-ai/react-toolkit-v3/ChatHeader';
|
|
4
2
|
import { ImageGalleryLayout } from '@envive-ai/react-toolkit-v3/ImageGallery';
|
|
5
3
|
import { PromptButtonVariant } from '@envive-ai/react-toolkit-v3/PromptButton';
|
|
6
4
|
import { AnimationSpeed, PromptCarouselRows } from '@envive-ai/react-toolkit-v3/PromptCarousel';
|
|
7
|
-
import { WidgetWrapperVariant } from '@envive-ai/react-toolkit-v3/WidgetWrapper';
|
|
8
|
-
import { Theme } from '@envive-ai/react-toolkit-v3/Tokens';
|
|
9
|
-
import { ChatHeaderVariant } from '@envive-ai/react-toolkit-v3/ChatHeader';
|
|
10
5
|
import { WidgetKind } from '@envive-ai/react-toolkit-v3/SocialProof';
|
|
6
|
+
import { Theme } from '@envive-ai/react-toolkit-v3/Tokens';
|
|
11
7
|
import { SparkleIconColor } from '@envive-ai/react-toolkit-v3/WelcomeMessage';
|
|
8
|
+
import { WidgetWrapperVariant } from '@envive-ai/react-toolkit-v3/WidgetWrapper';
|
|
9
|
+
import { CamelCasedPropertiesDeep } from 'src/application/models';
|
|
10
|
+
import { ColorMappingV3, ColorNames, colorVar } from 'src/application/models/colorsConfigV3';
|
|
11
|
+
import { FrontendConfigV3 } from 'src/application/models/frontendConfigV3';
|
|
12
12
|
|
|
13
|
-
import { CustomerServiceType } from 'src/types/customerService';
|
|
14
13
|
import { FloatingButtonLocation } from '@envive-ai/react-toolkit-v3/FloatingButton';
|
|
14
|
+
import { CustomerServiceType } from 'src/types/customerService';
|
|
15
15
|
import { ConfigVersionEnum, WidgetTypeV3 } from '../typesV3';
|
|
16
16
|
|
|
17
17
|
const mockImages = [
|
|
@@ -262,5 +262,11 @@ export const mockV3FrontendConfig: FrontendConfigV3 = {
|
|
|
262
262
|
imageSrc:
|
|
263
263
|
'https://www.bandolierstyle.com/cdn/shop/files/Lily17_Black_Gold_Chrome_MOD_Dec25_6.jpg?v=1765844272',
|
|
264
264
|
},
|
|
265
|
+
'full-page-sales-agent-widget': {
|
|
266
|
+
widgetConfigId: 'full-page-sales-agent-widget',
|
|
267
|
+
contentId: 'full-page-sales-agent-widget',
|
|
268
|
+
type: WidgetTypeV3.FullPageSalesAgentV3,
|
|
269
|
+
autoHeight: true,
|
|
270
|
+
},
|
|
265
271
|
},
|
|
266
272
|
};
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { ReactNode, createContext, useCallback, useContext, useMemo, useState } from 'react';
|
|
2
2
|
import Logger from 'src/application/logging/logger';
|
|
3
|
-
|
|
3
|
+
import { v4 as uuid } from 'uuid';
|
|
4
4
|
import CommerceApiClient from 'src/application/commerce-api';
|
|
5
|
-
import { WidgetText } from 'src/application/models/api/widgetText';
|
|
5
|
+
import { WidgetString, WidgetText } from 'src/application/models/api/widgetText';
|
|
6
6
|
import { WidgetTextRequest } from 'src/application/models/api/widgetTextRequest';
|
|
7
7
|
|
|
8
8
|
import { useAtomValue } from 'jotai';
|
|
9
9
|
import { appDetailsAtom } from 'src/atoms/app';
|
|
10
|
+
import { EnviveMetricsEventName } from 'src/services/amplitudeService/amplitudeService';
|
|
10
11
|
import { toCamelCase } from 'src/application/models/utils/snakeToCamelTransformer';
|
|
11
12
|
import { UserEvent } from 'src/application/models';
|
|
13
|
+
import { getQueryParam } from 'src/application/utils';
|
|
12
14
|
import { WidgetTypeV3 } from '../typesV3';
|
|
13
15
|
import { useFeatureFlagService } from '../featureFlagServiceContext/featureFlagServiceContext';
|
|
16
|
+
import { useAmplitude } from '../amplitudeContext';
|
|
14
17
|
|
|
15
18
|
interface HardcopyRequest {
|
|
16
19
|
widgetType: WidgetTypeV3;
|
|
@@ -18,7 +21,9 @@ interface HardcopyRequest {
|
|
|
18
21
|
}
|
|
19
22
|
|
|
20
23
|
export type HardcopyResponse = {
|
|
24
|
+
responseId: string;
|
|
21
25
|
language: string;
|
|
26
|
+
rawValues?: Record<string, WidgetString | WidgetString[]>;
|
|
22
27
|
values: Record<string, string | string[]>;
|
|
23
28
|
};
|
|
24
29
|
|
|
@@ -29,7 +34,9 @@ interface HardcopyContextType {
|
|
|
29
34
|
|
|
30
35
|
const convertToHardcopyResponse = (response: WidgetText): HardcopyResponse => {
|
|
31
36
|
return {
|
|
37
|
+
responseId: response.responseId,
|
|
32
38
|
language: response.language,
|
|
39
|
+
rawValues: response.values,
|
|
33
40
|
values: Object.fromEntries(
|
|
34
41
|
Object.entries(response.values).map(([key, value]) => [
|
|
35
42
|
// Transform the key from snake_case to camelCase
|
|
@@ -45,6 +52,7 @@ const convertToHardcopyResponse = (response: WidgetText): HardcopyResponse => {
|
|
|
45
52
|
// values and their names should be.
|
|
46
53
|
const MOCK_HARDCOPY_RESPONSE: Partial<Record<WidgetTypeV3, HardcopyResponse>> = {
|
|
47
54
|
[WidgetTypeV3.PromptCarouselV3]: {
|
|
55
|
+
responseId: uuid(),
|
|
48
56
|
language: 'en',
|
|
49
57
|
values: {
|
|
50
58
|
promptButtonTexts: [
|
|
@@ -57,6 +65,7 @@ const MOCK_HARDCOPY_RESPONSE: Partial<Record<WidgetTypeV3, HardcopyResponse>> =
|
|
|
57
65
|
},
|
|
58
66
|
},
|
|
59
67
|
[WidgetTypeV3.TitledPromptCarouselV3]: {
|
|
68
|
+
responseId: 'mock-response-id',
|
|
60
69
|
language: 'en',
|
|
61
70
|
values: {
|
|
62
71
|
titleLabel: 'Need some help?',
|
|
@@ -70,6 +79,7 @@ const MOCK_HARDCOPY_RESPONSE: Partial<Record<WidgetTypeV3, HardcopyResponse>> =
|
|
|
70
79
|
},
|
|
71
80
|
},
|
|
72
81
|
[WidgetTypeV3.SocialProofV3]: {
|
|
82
|
+
responseId: 'mock-response-id',
|
|
73
83
|
language: 'en',
|
|
74
84
|
values: {
|
|
75
85
|
titleLabel: 'Shopping Assistant',
|
|
@@ -88,6 +98,7 @@ const MOCK_HARDCOPY_RESPONSE: Partial<Record<WidgetTypeV3, HardcopyResponse>> =
|
|
|
88
98
|
},
|
|
89
99
|
},
|
|
90
100
|
[WidgetTypeV3.TypingAnimationV3]: {
|
|
101
|
+
responseId: 'mock-response-id',
|
|
91
102
|
language: 'en',
|
|
92
103
|
values: {
|
|
93
104
|
titleLabel: 'Shopping Assistant',
|
|
@@ -108,6 +119,7 @@ const MOCK_HARDCOPY_RESPONSE: Partial<Record<WidgetTypeV3, HardcopyResponse>> =
|
|
|
108
119
|
},
|
|
109
120
|
},
|
|
110
121
|
[WidgetTypeV3.ChatPreviewComparisonV3]: {
|
|
122
|
+
responseId: 'mock-response-id',
|
|
111
123
|
language: 'en',
|
|
112
124
|
values: {
|
|
113
125
|
titleLabel: 'Shopping Assistant',
|
|
@@ -116,6 +128,7 @@ const MOCK_HARDCOPY_RESPONSE: Partial<Record<WidgetTypeV3, HardcopyResponse>> =
|
|
|
116
128
|
},
|
|
117
129
|
},
|
|
118
130
|
[WidgetTypeV3.ChatPreviewLoadingV3]: {
|
|
131
|
+
responseId: 'mock-response-id',
|
|
119
132
|
language: 'en',
|
|
120
133
|
values: {
|
|
121
134
|
titleLabel: 'Shopping Assistant',
|
|
@@ -123,6 +136,7 @@ const MOCK_HARDCOPY_RESPONSE: Partial<Record<WidgetTypeV3, HardcopyResponse>> =
|
|
|
123
136
|
},
|
|
124
137
|
},
|
|
125
138
|
[WidgetTypeV3.ChatPreviewV3]: {
|
|
139
|
+
responseId: 'mock-response-id',
|
|
126
140
|
language: 'en',
|
|
127
141
|
values: {
|
|
128
142
|
titleLabel: 'Shopping Assistant',
|
|
@@ -130,6 +144,7 @@ const MOCK_HARDCOPY_RESPONSE: Partial<Record<WidgetTypeV3, HardcopyResponse>> =
|
|
|
130
144
|
},
|
|
131
145
|
},
|
|
132
146
|
[WidgetTypeV3.PromptButtonCarouselWithImageV3]: {
|
|
147
|
+
responseId: 'mock-response-id',
|
|
133
148
|
language: 'en',
|
|
134
149
|
values: {
|
|
135
150
|
titleLabel: 'Need some help?',
|
|
@@ -138,6 +153,7 @@ const MOCK_HARDCOPY_RESPONSE: Partial<Record<WidgetTypeV3, HardcopyResponse>> =
|
|
|
138
153
|
},
|
|
139
154
|
},
|
|
140
155
|
[WidgetTypeV3.ProductCardV3]: {
|
|
156
|
+
responseId: 'mock-response-id',
|
|
141
157
|
language: 'en',
|
|
142
158
|
values: {
|
|
143
159
|
headline: 'Discover Your Perfect Style',
|
|
@@ -157,6 +173,18 @@ const MOCK_HARDCOPY_RESPONSE: Partial<Record<WidgetTypeV3, HardcopyResponse>> =
|
|
|
157
173
|
},
|
|
158
174
|
},
|
|
159
175
|
[WidgetTypeV3.FloatingChatV3]: {
|
|
176
|
+
responseId: 'mock-response-id',
|
|
177
|
+
language: 'en',
|
|
178
|
+
values: {
|
|
179
|
+
welcomeMessageTitle: 'Welcome to Envive AI',
|
|
180
|
+
welcomeMessageText:
|
|
181
|
+
'Your personal shopper trained on the collective knowledge of thousands of real experts!',
|
|
182
|
+
chatFooterTextFieldPlaceholderText: 'Ask me anything...',
|
|
183
|
+
disclaimerText: 'This is a disclaimer...',
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
[WidgetTypeV3.FullPageSalesAgentV3]: {
|
|
187
|
+
responseId: 'mock-response-id',
|
|
160
188
|
language: 'en',
|
|
161
189
|
values: {
|
|
162
190
|
welcomeMessageTitle: 'Welcome to Envive AI',
|
|
@@ -170,26 +198,61 @@ const MOCK_HARDCOPY_RESPONSE: Partial<Record<WidgetTypeV3, HardcopyResponse>> =
|
|
|
170
198
|
|
|
171
199
|
const HardcopyContext = createContext<HardcopyContextType | undefined>(undefined);
|
|
172
200
|
|
|
173
|
-
|
|
201
|
+
interface HardcopyProviderProps {
|
|
202
|
+
children: ReactNode;
|
|
203
|
+
hardcopyOverride?: Partial<Record<WidgetTypeV3, HardcopyResponse>>;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export const HardcopyProvider: React.FC<HardcopyProviderProps> = ({
|
|
207
|
+
children,
|
|
208
|
+
hardcopyOverride,
|
|
209
|
+
}) => {
|
|
174
210
|
const languages = useMemo(() => navigator.languages, []);
|
|
175
211
|
const [isLoading, setIsLoading] = useState(false);
|
|
176
212
|
const context = useAtomValue(appDetailsAtom);
|
|
213
|
+
const { trackEvent } = useAmplitude();
|
|
177
214
|
|
|
178
215
|
const { featureFlagService } = useFeatureFlagService();
|
|
179
216
|
const getHardcopyFromBackend = useCallback(
|
|
180
217
|
async (request: HardcopyRequest): Promise<HardcopyResponse> => {
|
|
218
|
+
if (hardcopyOverride?.[request.widgetType]) {
|
|
219
|
+
Logger.logInfo('hardcopyContext | using hardcopy override', request.widgetType);
|
|
220
|
+
return hardcopyOverride[request.widgetType]!;
|
|
221
|
+
}
|
|
222
|
+
const overrideConfigVersion =
|
|
223
|
+
getQueryParam('spiffy_config_version') ||
|
|
224
|
+
getQueryParam('envive_config_version') ||
|
|
225
|
+
undefined;
|
|
181
226
|
const widgetTextRequest: WidgetTextRequest = {
|
|
227
|
+
requestId: uuid(),
|
|
182
228
|
widgetType: request.widgetType,
|
|
183
229
|
context,
|
|
184
230
|
featureFlags: featureFlagService?.getFeatureFlags() || {},
|
|
185
231
|
language: languages[0] || 'en',
|
|
232
|
+
overrideConfigVersion,
|
|
186
233
|
url: window.location.href,
|
|
187
234
|
};
|
|
235
|
+
trackEvent({
|
|
236
|
+
eventName: EnviveMetricsEventName.WidgetTextRequest,
|
|
237
|
+
eventProps: {
|
|
238
|
+
widget_type: request.widgetType,
|
|
239
|
+
request_id: widgetTextRequest.requestId,
|
|
240
|
+
},
|
|
241
|
+
});
|
|
188
242
|
try {
|
|
189
243
|
const response = await CommerceApiClient.getHardcopy(widgetTextRequest);
|
|
190
244
|
if (response) {
|
|
191
245
|
const convertedResponse = convertToHardcopyResponse(response);
|
|
192
246
|
Logger.logInfo('hardcopyContext | converted response', convertedResponse);
|
|
247
|
+
trackEvent({
|
|
248
|
+
eventName: EnviveMetricsEventName.WidgetTextResponse,
|
|
249
|
+
eventProps: {
|
|
250
|
+
widget_type: request.widgetType,
|
|
251
|
+
response_id: response.responseId,
|
|
252
|
+
widget_text: response.values,
|
|
253
|
+
request_id: widgetTextRequest.requestId,
|
|
254
|
+
},
|
|
255
|
+
});
|
|
193
256
|
return convertedResponse;
|
|
194
257
|
}
|
|
195
258
|
} catch (error) {
|
|
@@ -202,7 +265,7 @@ export const HardcopyProvider: React.FC<{ children: ReactNode }> = ({ children }
|
|
|
202
265
|
}
|
|
203
266
|
throw new Error(`No hardcopy response found for widget type: ${request.widgetType}`);
|
|
204
267
|
},
|
|
205
|
-
[context, featureFlagService, languages],
|
|
268
|
+
[context, featureFlagService, hardcopyOverride, languages, trackEvent],
|
|
206
269
|
);
|
|
207
270
|
|
|
208
271
|
const getHardcopy = useCallback(
|
|
@@ -15,7 +15,13 @@ import { isApiSearchAttributes } from 'src/application/models/guards/api/isApiSe
|
|
|
15
15
|
import { isApiSuggestionClickedAttributes } from 'src/application/models/guards/api/isApiSuggestionClickedEventAttributes';
|
|
16
16
|
import { isApiFormSubmittedResponseAttributes } from 'src/application/models/guards/api/isApiFormSubmittedResponseAttributes';
|
|
17
17
|
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
FullPageSalesAgentVariantInfo,
|
|
20
|
+
HomeVariantInfo,
|
|
21
|
+
OtherVariantInfo,
|
|
22
|
+
PageVariantInfo,
|
|
23
|
+
VisitPageVariantInfo,
|
|
24
|
+
} from './types';
|
|
19
25
|
|
|
20
26
|
export const mapUrlResolverResponseToVariantInfo = (
|
|
21
27
|
url: string,
|
|
@@ -66,6 +72,12 @@ export const mapUrlResolverResponseToVariantInfo = (
|
|
|
66
72
|
} as OtherVariantInfo;
|
|
67
73
|
}
|
|
68
74
|
|
|
75
|
+
if (response.variant_type === VariantTypeEnum.FullPageSalesAgent) {
|
|
76
|
+
return {
|
|
77
|
+
variantType: VariantTypeEnum.FullPageSalesAgent,
|
|
78
|
+
url,
|
|
79
|
+
} as FullPageSalesAgentVariantInfo;
|
|
80
|
+
}
|
|
69
81
|
throw new Error('Invalid variant type');
|
|
70
82
|
};
|
|
71
83
|
|
|
@@ -67,10 +67,15 @@ export const PageProvider: React.FC<{
|
|
|
67
67
|
|
|
68
68
|
const setVariantFromUrlResolver = useCallback(
|
|
69
69
|
(url: string, response: UrlResolverResponse) => {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
if (response.ready) {
|
|
71
|
+
const newVariantInfo = mapUrlResolverResponseToVariantInfo(url, response);
|
|
72
|
+
const newUserEvent = mapApiUserEventToUserEvent(response.user_event ?? undefined);
|
|
73
|
+
setVariantInfo(newVariantInfo);
|
|
74
|
+
setUserEvent(newUserEvent);
|
|
75
|
+
} else {
|
|
76
|
+
setUserEvent(undefined);
|
|
77
|
+
setVariantInfo(undefined);
|
|
78
|
+
}
|
|
74
79
|
},
|
|
75
80
|
[setVariantInfo, setUserEvent],
|
|
76
81
|
);
|
|
@@ -31,12 +31,18 @@ export type OtherVariantInfo = {
|
|
|
31
31
|
url: string;
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
+
export type FullPageSalesAgentVariantInfo = {
|
|
35
|
+
variantType: VariantTypeEnum.FullPageSalesAgent;
|
|
36
|
+
url: string;
|
|
37
|
+
};
|
|
38
|
+
|
|
34
39
|
export type PageVariantInfo =
|
|
35
40
|
| PDPPageVariantInfo
|
|
36
41
|
| PLPPageVariantInfo
|
|
37
42
|
| VisitPageVariantInfo
|
|
38
43
|
| HomeVariantInfo
|
|
39
|
-
| OtherVariantInfo
|
|
44
|
+
| OtherVariantInfo
|
|
45
|
+
| FullPageSalesAgentVariantInfo;
|
|
40
46
|
|
|
41
47
|
export interface PageDetails {
|
|
42
48
|
pageUrl: string | undefined;
|