@envive-ai/react-hooks 0.3.15-beta.1 → 0.3.15
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 +38 -1
- package/dist/application/commerce-api.d.cts +13 -2
- package/dist/application/commerce-api.d.ts +13 -2
- package/dist/application/commerce-api.js +39 -2
- package/dist/application/models/index.d.cts +9 -9
- package/dist/application/models/index.d.ts +9 -9
- package/dist/application/utils/productRetrievalResponseToProductRetrievalResult.cjs +18 -0
- package/dist/application/utils/productRetrievalResponseToProductRetrievalResult.js +18 -0
- package/dist/atoms/app/index.d.cts +1 -1
- package/dist/atoms/app/index.d.ts +1 -1
- package/dist/atoms/app/variant.d.cts +6 -6
- package/dist/atoms/chat/chatState.d.cts +18 -18
- package/dist/atoms/chat/form.d.cts +3 -3
- package/dist/atoms/chat/form.d.ts +2 -2
- package/dist/atoms/chat/index.d.cts +3 -3
- package/dist/atoms/chat/index.d.ts +3 -3
- 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 +7 -7
- 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 +2 -2
- package/dist/atoms/chat/suggestions.d.cts +3 -3
- package/dist/atoms/chat/suggestions.d.ts +2 -2
- package/dist/atoms/envive/enviveConfig.d.cts +13 -13
- package/dist/atoms/envive/enviveConfig.d.ts +13 -13
- 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/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.d.cts +18 -18
- package/dist/atoms/search/chatSearch.d.ts +18 -18
- package/dist/atoms/search/searchAPI.d.cts +14 -14
- package/dist/atoms/search/searchAPI.d.ts +14 -14
- package/dist/atoms/widget/chatPreviewLoading.d.cts +2 -2
- package/dist/atoms/widget/chatPreviewLoading.d.ts +2 -2
- package/dist/contexts/graphqlContext/graphqlContext.d.cts +1 -1
- package/dist/contexts/graphqlContext/graphqlContext.d.ts +1 -1
- package/dist/contexts/salesAgentContext/chatAPI.cjs +5 -4
- package/dist/contexts/salesAgentContext/chatAPI.d.cts +3 -2
- package/dist/contexts/salesAgentContext/chatAPI.d.ts +3 -2
- package/dist/contexts/salesAgentContext/chatAPI.js +5 -4
- package/dist/contexts/salesAgentContext/salesAgentContext.cjs +4 -4
- package/dist/contexts/salesAgentContext/salesAgentContext.d.cts +3 -2
- package/dist/contexts/salesAgentContext/salesAgentContext.d.ts +3 -2
- package/dist/contexts/salesAgentContext/salesAgentContext.js +4 -4
- package/dist/contexts/systemSettingsContext/systemSettingsContext.d.ts +2 -2
- package/dist/contexts/types.d.cts +1 -1
- package/dist/contexts/types.d.ts +1 -1
- package/dist/contexts/typesV3.d.cts +1 -1
- package/dist/contexts/typesV3.d.ts +1 -1
- package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.cts +2 -2
- package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.ts +2 -2
- package/dist/hooks/ProductImageUrl/index.cjs +3 -0
- package/dist/hooks/ProductImageUrl/index.d.cts +2 -0
- package/dist/hooks/ProductImageUrl/index.d.ts +2 -0
- package/dist/hooks/ProductImageUrl/index.js +3 -0
- package/dist/hooks/ProductImageUrl/useProductImageUrl.cjs +33 -0
- package/dist/hooks/ProductImageUrl/useProductImageUrl.d.cts +9 -0
- package/dist/hooks/ProductImageUrl/useProductImageUrl.d.ts +9 -0
- package/dist/hooks/ProductImageUrl/useProductImageUrl.js +32 -0
- package/dist/hooks/Search/useSearch.d.cts +1 -1
- package/dist/hooks/Search/useSearch.d.ts +1 -1
- package/dist/hooks/WidgetInteraction/types.cjs +2 -1
- package/dist/hooks/WidgetInteraction/types.d.cts +2 -1
- package/dist/hooks/WidgetInteraction/types.d.ts +2 -1
- package/dist/hooks/WidgetInteraction/types.js +2 -1
- package/dist/hooks/utils.d.cts +1 -1
- package/dist/hooks/utils.d.ts +1 -1
- package/package.json +5 -1
- package/src/application/commerce-api.ts +51 -0
- package/src/application/utils/productRetrievalResponseToProductRetrievalResult.ts +21 -0
- package/src/contexts/salesAgentContext/chatAPI.ts +4 -3
- package/src/contexts/salesAgentContext/salesAgentContext.tsx +7 -6
- package/src/hooks/ProductImageUrl/index.ts +1 -0
- package/src/hooks/ProductImageUrl/useProductImageUrl.ts +35 -0
- package/src/hooks/WidgetInteraction/types.ts +1 -0
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
DefaultApi,
|
|
8
8
|
FormType,
|
|
9
9
|
InferenceApi,
|
|
10
|
+
ProductsApi,
|
|
10
11
|
ReportSessionRequest,
|
|
11
12
|
ResponseCategory,
|
|
12
13
|
ResponseError,
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
V1OrgConfigGetSourceEnum,
|
|
17
18
|
} from '@spiffy-ai/commerce-api-client';
|
|
18
19
|
import type { Context } from '@spiffy-ai/commerce-api-client/dist/models/Context';
|
|
20
|
+
import type { ProductRetrievalResult } from 'src/atoms/search/types';
|
|
19
21
|
import Logger from 'src/application/logging/logger';
|
|
20
22
|
import {
|
|
21
23
|
Message,
|
|
@@ -57,6 +59,7 @@ import { SessionRestartRequired } from 'src/types/exceptions/sessionExceptions';
|
|
|
57
59
|
import { UnsupportedProductException } from 'src/types/exceptions/unsupportedProductExceptions';
|
|
58
60
|
import { WidgetText } from './models/api/widgetText';
|
|
59
61
|
import { WidgetTextRequest } from './models/api/widgetTextRequest';
|
|
62
|
+
import { productRetrievalResponseToProductRetrievalResult } from './utils/productRetrievalResponseToProductRetrievalResult';
|
|
60
63
|
import { apiWidgetTextResponseToCoreWidgetText } from './utils/widgetTextFromApiWidgetTextResponse';
|
|
61
64
|
import { coreWidgetTextRequestToApiRequest } from './utils/widgetTextRequestToApiRequest';
|
|
62
65
|
|
|
@@ -104,6 +107,8 @@ class CommerceApiClient {
|
|
|
104
107
|
|
|
105
108
|
private readonly inferenceApi: InferenceApi;
|
|
106
109
|
|
|
110
|
+
private readonly productsApi: ProductsApi;
|
|
111
|
+
|
|
107
112
|
private static instance: CommerceApiClient | undefined;
|
|
108
113
|
|
|
109
114
|
private suggestionsAbortController = new AbortController();
|
|
@@ -135,6 +140,7 @@ class CommerceApiClient {
|
|
|
135
140
|
this.defaultApi = new DefaultApi(config);
|
|
136
141
|
this.inferenceApi = new InferenceApi(config);
|
|
137
142
|
this.customerServiceApi = new CustomerServiceApi(config);
|
|
143
|
+
this.productsApi = new ProductsApi(config);
|
|
138
144
|
}
|
|
139
145
|
|
|
140
146
|
static resolveUrl = async (url: string) => {
|
|
@@ -437,6 +443,51 @@ class CommerceApiClient {
|
|
|
437
443
|
return apiWidgetTextResponseToCoreWidgetText(apiRequest, response);
|
|
438
444
|
};
|
|
439
445
|
|
|
446
|
+
/**
|
|
447
|
+
* Retrieves product details for the given product IDs via POST /v1/products/retrieve.
|
|
448
|
+
* Builds context from the current atom store (org, user, chat, etc.) and returns
|
|
449
|
+
* products in the shape expected by ProductRetrievalResult (camelCase attributes).
|
|
450
|
+
*
|
|
451
|
+
* @param productIds - List of product IDs to retrieve
|
|
452
|
+
* @returns ProductRetrievalResult with products and totalProductCount
|
|
453
|
+
*/
|
|
454
|
+
static retrieveProducts = async (productIds: string[]): Promise<ProductRetrievalResult> => {
|
|
455
|
+
if (productIds.length === 0) {
|
|
456
|
+
return { products: [], totalProductCount: 0 };
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
try {
|
|
460
|
+
const atomStore = getAtomStore();
|
|
461
|
+
const orgShortName = atomStore.get(orgShortNameAtom);
|
|
462
|
+
const orgId = atomStore.get(orgIdAtom);
|
|
463
|
+
const userId = atomStore.get(userIdAtom);
|
|
464
|
+
const chatId = atomStore.get(chatIdAtom);
|
|
465
|
+
const source = atomStore.get(contextSourceAtom);
|
|
466
|
+
const env = atomStore.get(envAtom);
|
|
467
|
+
|
|
468
|
+
const context: Context = {
|
|
469
|
+
user_id: userId ?? '',
|
|
470
|
+
org_id: orgId ?? '',
|
|
471
|
+
org_short_name: orgShortName ?? '',
|
|
472
|
+
chat_id: chatId ?? '',
|
|
473
|
+
source: source ?? ContextSourceEnum.App,
|
|
474
|
+
env: (env as ContextEnvEnum) ?? ContextEnvEnum.Dev,
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
const response = await CommerceApiClient.getInstance().productsApi.v1ProductsRetrievePost({
|
|
478
|
+
ProductRetrievalRequest: {
|
|
479
|
+
context,
|
|
480
|
+
product_ids: productIds,
|
|
481
|
+
},
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
return productRetrievalResponseToProductRetrievalResult(response);
|
|
485
|
+
} catch (err) {
|
|
486
|
+
await throwSessionRestartRequiredIf('Failed to retrieve products', err);
|
|
487
|
+
return { products: [], totalProductCount: 0 };
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
|
|
440
491
|
/**
|
|
441
492
|
*
|
|
442
493
|
* @param payload
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ProductRetrievalResponse } from '@spiffy-ai/commerce-api-client';
|
|
2
|
+
import { transformSnakeToCamel } from 'src/application/models/utils/snakeToCamelTransformer';
|
|
3
|
+
import type { SearchResponseProductAttributes } from 'src/application/models/api/response';
|
|
4
|
+
import type { ProductRetrievalResult } from 'src/atoms/search/types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Maps the API response from /v1/products/retrieve to the core ProductRetrievalResult.
|
|
8
|
+
* Converts product attributes from snake_case to camelCase to match SearchResponseProductAttributes.
|
|
9
|
+
*/
|
|
10
|
+
export function productRetrievalResponseToProductRetrievalResult(
|
|
11
|
+
apiResponse: ProductRetrievalResponse,
|
|
12
|
+
): ProductRetrievalResult {
|
|
13
|
+
const products = (apiResponse.products ?? []).map(product =>
|
|
14
|
+
transformSnakeToCamel(product),
|
|
15
|
+
) as SearchResponseProductAttributes['attributes'][];
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
products,
|
|
19
|
+
totalProductCount: products.length,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -48,7 +48,7 @@ export interface SalesAgentChatAPI {
|
|
|
48
48
|
onFormResponseSubmitted: (form: FormSubmittedAttributes) => void;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
export const useSalesAgentChatAPI = () => {
|
|
51
|
+
export const useSalesAgentChatAPI = (widget?: WidgetInteractionComponent) => {
|
|
52
52
|
// TODO: Each of these functions will trigger both the necessary amplitude events and initiate the
|
|
53
53
|
// necessary actions to trigger the backend API
|
|
54
54
|
const context = useAtomValue(analyticsContextAtom);
|
|
@@ -58,6 +58,7 @@ export const useSalesAgentChatAPI = () => {
|
|
|
58
58
|
const setFormSubmit = useSetAtom(formSubmitAtom);
|
|
59
59
|
const { trackEvent } = useAmplitude();
|
|
60
60
|
const { trackWidgetInteraction } = useWidgetInteraction();
|
|
61
|
+
const contextWidget = widget || WidgetInteractionComponent.FLOATING_CHAT;
|
|
61
62
|
|
|
62
63
|
const logPageVisit = useCallback(
|
|
63
64
|
({ pageVisitCategory }: { pageVisitCategory: PageVisitCategory }) => {
|
|
@@ -113,7 +114,7 @@ export const useSalesAgentChatAPI = () => {
|
|
|
113
114
|
trackWidgetInteraction({
|
|
114
115
|
eventName: EnviveMetricsEventName.WidgetInteraction,
|
|
115
116
|
trigger: {
|
|
116
|
-
widget:
|
|
117
|
+
widget: contextWidget,
|
|
117
118
|
widget_interaction: WidgetInteractionType.SUGGESTION_CLICKED,
|
|
118
119
|
widget_interaction_data: {
|
|
119
120
|
suggestion_clicked: {
|
|
@@ -182,7 +183,7 @@ export const useSalesAgentChatAPI = () => {
|
|
|
182
183
|
trackWidgetInteraction({
|
|
183
184
|
eventName: EnviveMetricsEventName.WidgetInteraction,
|
|
184
185
|
trigger: {
|
|
185
|
-
widget:
|
|
186
|
+
widget: contextWidget,
|
|
186
187
|
widget_interaction: WidgetInteractionType.MESSAGE_SUBMITTED,
|
|
187
188
|
widget_interaction_data: {
|
|
188
189
|
message_submitted: {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { UserEventCategory } from '@spiffy-ai/commerce-api-client';
|
|
1
2
|
import { useAtom, useAtomValue, useSetAtom } from 'jotai';
|
|
2
3
|
import { ReactNode, createContext, useCallback, useEffect, useMemo, useRef } from 'react';
|
|
3
|
-
import { UserEventCategory } from '@spiffy-ai/commerce-api-client';
|
|
4
4
|
import Logger from 'src/application/logging/logger';
|
|
5
|
-
import { Message, MessageRole, MessageType } from 'src/application/models/message';
|
|
6
5
|
import { NextMessageRequest, Suggestion, UserEvent } from 'src/application/models';
|
|
6
|
+
import { Message, MessageRole, MessageType } from 'src/application/models/message';
|
|
7
7
|
import {
|
|
8
8
|
initializedAtom,
|
|
9
9
|
messagesAtom,
|
|
@@ -16,12 +16,13 @@ import {
|
|
|
16
16
|
userEventQueueAtom,
|
|
17
17
|
userQueueEventCountAtom,
|
|
18
18
|
} from 'src/atoms/chat/messageQueue';
|
|
19
|
-
import { useSystemSettingsContext } from '
|
|
19
|
+
import { useSystemSettingsContext } from '../../hooks/SystemSettingsContext';
|
|
20
|
+
import { WidgetInteractionComponent } from '../../hooks/WidgetInteraction/types';
|
|
21
|
+
import { SalesAgentChatAPI, useSalesAgentChatAPI } from './chatAPI';
|
|
20
22
|
import {
|
|
21
23
|
buildFormSubmittedDisplayContent,
|
|
22
24
|
createFormSubmittedUserMessage,
|
|
23
25
|
} from './formSubmittedUtils';
|
|
24
|
-
import { SalesAgentChatAPI, useSalesAgentChatAPI } from './chatAPI';
|
|
25
26
|
import { useSalesAgentService } from './salesAgentService';
|
|
26
27
|
|
|
27
28
|
export interface SalesAgent extends SalesAgentChatAPI {
|
|
@@ -203,7 +204,7 @@ export const SalesAgentProvider: React.FC<SalesAgentProviderProps> = ({
|
|
|
203
204
|
return <SalesAgentContext.Provider value={undefined}>{children}</SalesAgentContext.Provider>;
|
|
204
205
|
};
|
|
205
206
|
|
|
206
|
-
export const useSalesAgent = (): SalesAgent => {
|
|
207
|
+
export const useSalesAgent = (contextWidget?: WidgetInteractionComponent): SalesAgent => {
|
|
207
208
|
const messages = useAtomValue(messagesAtom);
|
|
208
209
|
const suggestions = useAtomValue(suggestionsAtom);
|
|
209
210
|
const pendingMessages = useAtomValue(userEventQueueAtom);
|
|
@@ -216,7 +217,7 @@ export const useSalesAgent = (): SalesAgent => {
|
|
|
216
217
|
onSuggestionClicked,
|
|
217
218
|
onTypedMessageSubmitted,
|
|
218
219
|
onFormResponseSubmitted,
|
|
219
|
-
} = useSalesAgentChatAPI();
|
|
220
|
+
} = useSalesAgentChatAPI(contextWidget);
|
|
220
221
|
|
|
221
222
|
const salesAgent: SalesAgent = useMemo(() => {
|
|
222
223
|
return {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useProductImageUrl';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import CommerceApiClient from 'src/application/commerce-api';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Fetches the product image URL for the given product ID via CommerceApiClient.retrieveProducts.
|
|
6
|
+
* Returns undefined while loading, on error, or when productId is not provided.
|
|
7
|
+
*/
|
|
8
|
+
export const useProductImageUrl = (productId: string | undefined): string | undefined => {
|
|
9
|
+
const [imageUrl, setImageUrl] = useState<string | undefined>(undefined);
|
|
10
|
+
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!productId) {
|
|
13
|
+
setImageUrl(undefined);
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
let cancelled = false;
|
|
17
|
+
CommerceApiClient.retrieveProducts([productId]).then(
|
|
18
|
+
result => {
|
|
19
|
+
if (!cancelled && result.products?.length > 0) {
|
|
20
|
+
setImageUrl(result.products[0].imageUrl);
|
|
21
|
+
} else if (!cancelled) {
|
|
22
|
+
setImageUrl(undefined);
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
() => {
|
|
26
|
+
if (!cancelled) setImageUrl(undefined);
|
|
27
|
+
},
|
|
28
|
+
);
|
|
29
|
+
return () => {
|
|
30
|
+
cancelled = true;
|
|
31
|
+
};
|
|
32
|
+
}, [productId]);
|
|
33
|
+
|
|
34
|
+
return imageUrl;
|
|
35
|
+
};
|
|
@@ -36,6 +36,7 @@ export enum WidgetInteractionComponent {
|
|
|
36
36
|
EMBEDDED_WIDGET = 'embedded_widget',
|
|
37
37
|
SUGGESTION_BAR = 'suggestion_bar',
|
|
38
38
|
FLOATING_BUTTON = 'floating_button',
|
|
39
|
+
FULL_PAGE_SALES_AGENT = 'full_page_sales_agent',
|
|
39
40
|
SOCIAL_PROOF = 'social_proof',
|
|
40
41
|
CHAT_PREVIEW = 'chat_preview',
|
|
41
42
|
FLOATING_CHAT = 'floating_chat',
|