diff --git a/packages/atomic/src/components/commerce/atomic-commerce-product-list/atomic-commerce-product-list.tsx b/packages/atomic/src/components/commerce/atomic-commerce-product-list/atomic-commerce-product-list.tsx
index bb384d08964..7b337b8a9b3 100644
--- a/packages/atomic/src/components/commerce/atomic-commerce-product-list/atomic-commerce-product-list.tsx
+++ b/packages/atomic/src/components/commerce/atomic-commerce-product-list/atomic-commerce-product-list.tsx
@@ -217,12 +217,24 @@ export class AtomicCommerceProductList
);
}
+ private logWarningIfNeeded(message?: string) {
+ if (message) {
+ this.bindings.engine.logger.warn(message);
+ }
+ }
+
+ private getInteractiveProduct(product: Product) {
+ const parentController =
+ this.bindings.interfaceElement.type === 'product-listing'
+ ? this.productListing
+ : this.search;
+
+ return parentController.interactiveProduct({options: {product}});
+ }
+
private getPropsForAtomicProduct(product: Product) {
return {
- // TODO: add back once interactive result is implemented for products in KIT-3149
- /* interactiveResult: buildInteractiveResult(this.bindings.engine, {
- options: {result},
- }), */
+ interactiveProduct: this.getInteractiveProduct(product),
product,
renderingFunction: this.itemRenderingFunction,
loadingFlag: this.loadingFlag,
@@ -243,6 +255,7 @@ export class AtomicCommerceProductList
private renderAsGrid() {
return this.productState.products.map((product, i) => {
const propsForAtomicProduct = this.getPropsForAtomicProduct(product);
+ const {interactiveProduct} = propsForAtomicProduct;
return (
element && this.productListCommon.setNewResultRef(element, i)
}
- select={function (): void {
- throw new Error('Function not implemented. TODO KIT-3149');
+ select={() => {
+ this.logWarningIfNeeded(interactiveProduct.warningMessage);
+ interactiveProduct.select();
}}
- beginDelayedSelect={function (): void {
- throw new Error('Function not implemented. TODO KIT-3149');
+ beginDelayedSelect={() => {
+ this.logWarningIfNeeded(interactiveProduct.warningMessage);
+ interactiveProduct.beginDelayedSelect();
}}
- cancelPendingSelect={function (): void {
- throw new Error('Function not implemented. TODO KIT-3149');
+ cancelPendingSelect={() => {
+ this.logWarningIfNeeded(interactiveProduct.warningMessage);
+ interactiveProduct.cancelPendingSelect();
}}
>
-
+
);
});
@@ -328,7 +342,6 @@ export class AtomicCommerceProductList
const propsForAtomicProduct = this.getPropsForAtomicProduct(product);
return (
element && this.productListCommon.setNewResultRef(element, i)
diff --git a/packages/atomic/src/components/commerce/atomic-commerce-recommendation-interface/atomic-commerce-recommendation-interface.tsx b/packages/atomic/src/components/commerce/atomic-commerce-recommendation-interface/atomic-commerce-recommendation-interface.tsx
index 2d759fb2e86..7a7f0e9cfe8 100644
--- a/packages/atomic/src/components/commerce/atomic-commerce-recommendation-interface/atomic-commerce-recommendation-interface.tsx
+++ b/packages/atomic/src/components/commerce/atomic-commerce-recommendation-interface/atomic-commerce-recommendation-interface.tsx
@@ -126,12 +126,6 @@ export class AtomicCommerceRecommendationInterface
this,
'CoveoAtomic'
);
-
- if (!this.commonInterfaceHelper.engineIsCreated()) {
- return;
- }
-
- this.contextController = buildContext(this.bindings.engine);
}
public connectedCallback() {
@@ -233,6 +227,10 @@ export class AtomicCommerceRecommendationInterface
};
}
+ private initContext() {
+ this.contextController = buildContext(this.bindings.engine);
+ }
+
private initAriaLive() {
if (
Array.from(this.host.children).some(
@@ -246,6 +244,7 @@ export class AtomicCommerceRecommendationInterface
private async internalInitialization(initEngine: () => void) {
await this.commonInterfaceHelper.onInitialization(initEngine);
+ this.initContext();
}
private addResourceBundle(
diff --git a/packages/atomic/src/components/commerce/atomic-commerce-recommendation-list/atomic-commerce-recommendation-list.tsx b/packages/atomic/src/components/commerce/atomic-commerce-recommendation-list/atomic-commerce-recommendation-list.tsx
index 53d086d578f..a66c8c58f75 100644
--- a/packages/atomic/src/components/commerce/atomic-commerce-recommendation-list/atomic-commerce-recommendation-list.tsx
+++ b/packages/atomic/src/components/commerce/atomic-commerce-recommendation-list/atomic-commerce-recommendation-list.tsx
@@ -302,29 +302,27 @@ export class AtomicCommerceRecommendationList
);
}
- private getAtomicProductProps(recommendation: Product) {
+ private logWarningIfNeeded(message?: string) {
+ if (message) {
+ this.bindings.engine.logger.warn(message);
+ }
+ }
+
+ private getAtomicProductProps(product: Product) {
return {
interactiveProduct: this.recommendations.interactiveProduct({
- options: {
- product: {
- ...recommendation,
- name: recommendation.ec_name ?? '',
- price: this.getPrice(recommendation),
- productId: recommendation.permanentid,
- },
- position: this.currentIndex,
- },
+ options: {product},
}),
- product: recommendation,
+ product: product,
renderingFunction: this.itemRenderingFunction,
loadingFlag: this.loadingFlag,
key: this.itemListCommon.getResultId(
- recommendation.permanentid,
+ product.permanentid,
this.recommendationsState.responseId,
this.density,
this.imageSize
),
- content: this.productTemplateProvider.getTemplateContent(recommendation),
+ content: this.productTemplateProvider.getTemplateContent(product),
store: this.bindings.store,
density: this.density,
display: this.display,
@@ -332,20 +330,6 @@ export class AtomicCommerceRecommendationList
};
}
- private getPrice(recommendation: Product) {
- if (recommendation.ec_price === undefined) {
- return 0;
- }
-
- if (recommendation.ec_promo_price === undefined) {
- return recommendation.ec_price;
- }
-
- return recommendation.ec_promo_price > recommendation.ec_price
- ? recommendation.ec_promo_price
- : recommendation.ec_price;
- }
-
private computeListDisplayClasses() {
const displayPlaceholders = !this.bindings.store.isAppLoaded();
@@ -359,7 +343,8 @@ export class AtomicCommerceRecommendationList
}
private renderAsGrid(product: Product, i: number) {
- const atomicProductProps = this.getAtomicProductProps(product);
+ const propsForAtomicProduct = this.getAtomicProductProps(product);
+ const {interactiveProduct} = propsForAtomicProduct;
return (
{
+ this.logWarningIfNeeded(interactiveProduct.warningMessage);
+ interactiveProduct.select();
+ }}
+ beginDelayedSelect={() => {
+ this.logWarningIfNeeded(interactiveProduct.warningMessage);
+ interactiveProduct.beginDelayedSelect();
+ }}
+ cancelPendingSelect={() => {
+ this.logWarningIfNeeded(interactiveProduct.warningMessage);
+ interactiveProduct.cancelPendingSelect();
+ }}
setRef={(element) =>
element && this.itemListCommon.setNewResultRef(element, i)
}
>
-
+
);
}
diff --git a/packages/atomic/src/components/commerce/product-template-components/atomic-product-link/atomic-product-link.tsx b/packages/atomic/src/components/commerce/product-template-components/atomic-product-link/atomic-product-link.tsx
index 8940b8d719d..2bbd1525066 100644
--- a/packages/atomic/src/components/commerce/product-template-components/atomic-product-link/atomic-product-link.tsx
+++ b/packages/atomic/src/components/commerce/product-template-components/atomic-product-link/atomic-product-link.tsx
@@ -56,6 +56,12 @@ export class AtomicProductLink
private linkAttributes?: Attr[];
private stopPropagation?: boolean;
+ private logWarningIfNeed(warning?: string) {
+ if (warning) {
+ this.bindings.engine.logger.warn(warning);
+ }
+ }
+
public initialize() {
this.host.dispatchEvent(
buildCustomEvent(
@@ -78,16 +84,27 @@ export class AtomicProductLink
? this.product.clickUri
: 'test';
+ if (!this.interactiveProduct) {
+ return;
+ }
+
+ const {warningMessage} = this.interactiveProduct;
+
return (
this.interactiveProduct.select()}
- onBeginDelayedSelect={() =>
- this.interactiveProduct.beginDelayedSelect()
- }
- onCancelPendingSelect={() =>
- this.interactiveProduct.cancelPendingSelect()
- }
+ onSelect={() => {
+ this.logWarningIfNeed(warningMessage);
+ this.interactiveProduct.select();
+ }}
+ onBeginDelayedSelect={() => {
+ this.logWarningIfNeed(warningMessage);
+ this.interactiveProduct.beginDelayedSelect();
+ }}
+ onCancelPendingSelect={() => {
+ this.logWarningIfNeed(warningMessage);
+ this.interactiveProduct.cancelPendingSelect();
+ }}
attributes={this.linkAttributes}
stopPropagation={this.stopPropagation}
>
diff --git a/packages/atomic/src/components/commerce/search-box-suggestions/atomic-commerce-search-box-instant-products/atomic-commerce-search-box-instant-products.tsx b/packages/atomic/src/components/commerce/search-box-suggestions/atomic-commerce-search-box-instant-products/atomic-commerce-search-box-instant-products.tsx
index a9f274347ea..00f03a731fd 100644
--- a/packages/atomic/src/components/commerce/search-box-suggestions/atomic-commerce-search-box-instant-products/atomic-commerce-search-box-instant-products.tsx
+++ b/packages/atomic/src/components/commerce/search-box-suggestions/atomic-commerce-search-box-instant-products/atomic-commerce-search-box-instant-products.tsx
@@ -3,8 +3,6 @@ import {
buildInstantProducts,
Product,
InstantProducts,
- InteractiveProduct,
- CommerceEngine,
} from '@coveo/headless/commerce';
import {Component, Element, State, h, Prop, Method} from '@stencil/core';
import {InitializableComponent} from '../../../../utils/initialization-utils';
@@ -34,14 +32,6 @@ export type AriaLabelGenerator = (
product: Product
) => string | undefined;
-// TODO: KIT-3165 Uncomment once the `buildInteractiveInstantProduct` function is implemented in headless.
-function buildInteractiveInstantProduct(
- _engine: CommerceEngine<{}>,
- _arg: {options: {product: Product}}
-): InteractiveProduct {
- return {} as InteractiveProduct;
-}
-
/**
* The `atomic-commerce-search-box-instant-products` component can be added as a child of an `atomic-search-box` component, allowing for the configuration of instant results behavior.
*
@@ -141,6 +131,9 @@ export class AtomicCommerceSearchBoxInstantProducts
const elements: SearchBoxSuggestionElement[] = products.map(
(product: Product) => {
+ const interactiveProduct = this.instantProducts.interactiveProduct({
+ options: {product},
+ });
const partialItem = getPartialInstantItemElement(
this.bindings.i18n,
this.ariaLabelGenerator?.(this.bindings, product) || product.ec_name!,
@@ -153,12 +146,7 @@ export class AtomicCommerceSearchBoxInstantProducts
key={`instant-product-${encodeForDomAttribute(product.permanentid)}`}
part="outline"
product={product}
- interactiveProduct={buildInteractiveInstantProduct(
- this.bindings.engine,
- {
- options: {product},
- }
- )}
+ interactiveProduct={interactiveProduct}
display={this.display}
density={this.density}
imageSize={this.imageSize}
diff --git a/packages/atomic/src/pages/examples/commerce-website/cart.html b/packages/atomic/src/pages/examples/commerce-website/cart.html
index 63c1ac23be5..ebde5777aab 100644
--- a/packages/atomic/src/pages/examples/commerce-website/cart.html
+++ b/packages/atomic/src/pages/examples/commerce-website/cart.html
@@ -12,9 +12,12 @@
import {commerceEngine} from './engine.mjs';
(async () => {
- await customElements.whenDefined('atomic-commerce-interface');
- const commerceInterface = document.querySelector('atomic-commerce-recommendation-interface');
- await commerceInterface.initializeWithEngine(commerceEngine);
+ await customElements.whenDefined('atomic-commerce-recommendation-interface');
+ const recommendationInterfaces = document.querySelectorAll('atomic-commerce-recommendation-interface');
+
+ for (const recommendationInterface of recommendationInterfaces) {
+ await recommendationInterface.initializeWithEngine(commerceEngine);
+ }
})();