Skip to content

Commit

Permalink
Merge branch 'main' into LYNX-722
Browse files Browse the repository at this point in the history
  • Loading branch information
svera authored Feb 12, 2025
2 parents 019378b + 37d4167 commit f7e7ac6
Show file tree
Hide file tree
Showing 18 changed files with 440 additions and 279 deletions.
43 changes: 43 additions & 0 deletions blocks/targeted-block/condition-matcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
function rulesMatched(activeRules, rules) {
return activeRules && rules.some((rule) => activeRules.includes(rule));
}

const groupMatched = (activeGroup, groups) => groups.includes(activeGroup);

export default function conditionsMatched(activeRules, blockConfig) {
const {
'customer-segments': customerSegments,
'customer-groups': customerGroups,
'cart-rules': cartRules,
'catalog-price-rules': catalogPriceRules,
} = blockConfig;

const activeSegments = activeRules.customerSegments?.map(
(segment) => segment.name,
);
const activeGroup = activeRules.customerGroup?.name;
const activeCartRules = activeRules.cart?.rules?.map(
(rule) => rule.name,
);
const activePriceRules = activeRules.catalogPriceRules?.rules?.map(
(rule) => rule.name,
);

if (customerSegments !== undefined && !rulesMatched(activeSegments, customerSegments.split(','))) {
return false;
}

if (customerGroups !== undefined && !groupMatched(activeGroup, customerGroups.split(','))) {
return false;
}

if (cartRules !== undefined && !rulesMatched(activeCartRules, cartRules.split(','))) {
return false;
}

if (catalogPriceRules !== undefined && !rulesMatched(activePriceRules, catalogPriceRules.split(','))) {
return false;
}

return true;
}
64 changes: 64 additions & 0 deletions blocks/targeted-block/qraphql.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { fetchGraphQl, setFetchGraphQlHeaders } from '@dropins/tools/fetch-graphql.js';
import { getHeaders } from '../../scripts/configs.js';

export const getActiveRules = async (cartId) => {
try {
setFetchGraphQlHeaders(await getHeaders('cart'));
const response = await fetchGraphQl(
`query CUSTOMER_SEGMENTS($cartId: String!){
customerSegments(cartId: $cartId) {
name
}
customerGroup {
name
}
cart(cart_id: $cartId) {
rules {
name
}
}
}
`,
{
method: 'GET',
variables: { cartId },
},
);
return response.data;
} catch (error) {
console.error('Could not retrieve customer segments', error);
}
return [];
};

export const getCatalogPriceRules = async (sku) => {
try {
const query = `query CATALOG_PRICE_RULES($sku: String!) {
products(filter: {
sku: {
eq: $sku
}
})
{
items {
rules {
name
}
}
}
}
`;
setFetchGraphQlHeaders(await getHeaders('cart'));
const response = await fetchGraphQl(
query,
{
method: 'GET',
variables: { sku },
},
);
return response.data?.products?.items[0];
} catch (error) {
console.error(`Could not retrieve catalog rules for ${sku}`, error);
}
return [];
};
82 changes: 13 additions & 69 deletions blocks/targeted-block/targeted-block.js
Original file line number Diff line number Diff line change
@@ -1,95 +1,38 @@
import { events } from '@dropins/tools/event-bus.js';
import * as Cart from '@dropins/storefront-cart/api.js';
import { fetchGraphQl } from '@dropins/tools/fetch-graphql.js';
import { getActiveRules, getCatalogPriceRules } from './qraphql.js';
import conditionsMatched from './condition-matcher.js';
import { readBlockConfig } from '../../scripts/aem.js';
import { loadFragment } from '../fragment/fragment.js';

const blocks = [];
const displayedBlockTypes = [];

const getActiveRules = async (cartId) => {
try {
const response = await fetchGraphQl(
`query CUSTOMER_SEGMENTS($cartId: String!){
customerSegments(cartId: $cartId) {
name
}
customerGroup {
name
}
cart(cart_id: $cartId) {
rules {
name
}
}
}
`,
{
method: 'GET',
variables: { cartId },
},
);
return response.data;
} catch (error) {
console.error('Could not retrieve customer segments', error);
}
return [];
};

const segmentsMatched = (activeSegments, segments) => segments.filter(
(segment) => (activeSegments.includes(segment)),
).length >= 1;

const groupMatched = (activeGroup, groups) => groups.includes(activeGroup);

const cartRulesMatched = (activeRules, rules) => rules.filter(
(rule) => (activeRules.includes(rule)),
).length >= 1;

const conditionsMatched = (activeRules, blockConfig) => {
const {
'customer-segments': customerSegments,
'customer-groups': customerGroups,
'cart-rules': cartRules,
} = blockConfig;

const activeSegments = activeRules.customerSegments?.map(
(segment) => segment.name,
);
const activeGroup = activeRules.customerGroup?.name;
const activeCartRules = activeRules.cart?.rules?.map(
(rule) => rule.name,
);
if (customerSegments !== undefined && !segmentsMatched(activeSegments, customerSegments.split(','))) {
return false;
}

if (customerGroups !== undefined && !groupMatched(activeGroup, customerGroups.split(','))) {
return false;
}

if (cartRules !== undefined && !cartRulesMatched(activeCartRules, cartRules.split(','))) {
return false;
}

return true;
};

const updateTargetedBlocksVisibility = async () => {
const activeRules = (Cart.getCartDataFromCache() === null) ? {
customerSegments: [],
customerGroup: [],
cart: {
rules: [],
},
catalogPriceRules: [],
} : await getActiveRules(Cart.getCartDataFromCache().id);

// eslint-disable-next-line no-underscore-dangle
const productData = events._lastEvent?.['pdp/data']?.payload ?? null;

if (productData?.sku) {
activeRules.catalogPriceRules = await getCatalogPriceRules(productData.sku);
}

displayedBlockTypes.length = 0;
blocks.forEach(async (blockConfig) => {
const index = blocks.indexOf(blockConfig);
const { fragment, type } = blockConfig;

const block = document.querySelector(`[data-targeted-block-key="${index}"]`);
block.style.display = 'none';

if (!displayedBlockTypes.includes(type) && conditionsMatched(activeRules, blockConfig)) {
displayedBlockTypes.push(type);
if (fragment !== undefined) {
Expand All @@ -113,6 +56,7 @@ export default function decorate(block) {
events.on('cart/initialized', () => {
updateTargetedBlocksVisibility();
}, { eager: true });

events.on('cart/updated', () => {
updateTargetedBlocksVisibility();
}, { eager: true });
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
"@adobe/magento-storefront-events-sdk": "^1.8.0",
"@dropins/storefront-account": "~1.0.3",
"@dropins/storefront-auth": "~1.0.3",
"@dropins/storefront-cart": "~1.0.2",
"@dropins/storefront-checkout": "~1.1.0",
"@dropins/storefront-cart": "~1.0.3",
"@dropins/storefront-checkout": "~1.2.0",
"@dropins/storefront-order": "~1.0.4",
"@dropins/storefront-payment-services": "~1.0.1",
"@dropins/storefront-pdp": "~1.0.0",
Expand Down
1 change: 1 addition & 0 deletions scripts/__dropins__/storefront-cart/api/fragments.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { CART_FRAGMENT } from './graphql/CartFragment';
export { CART_ITEM_FRAGMENT } from './graphql/CartItemFragment';
export { DOWNLOADABLE_CART_ITEMS_FRAGMENT } from './graphql/DownloadableCartItemsFragment';
//# sourceMappingURL=fragments.d.ts.map
Original file line number Diff line number Diff line change
@@ -1,2 +1,18 @@
/********************************************************************
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2024 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
* and its suppliers and are protected by all applicable intellectual
* property laws, including trade secret and copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe.
*******************************************************************/
export declare const CART_ITEM_FRAGMENT: string;
//# sourceMappingURL=CartItemFragment.d.ts.map
Original file line number Diff line number Diff line change
@@ -1,2 +1,18 @@
export declare const CUSTOMER_ACCOUNT_FRAGMENT = "\nfragment CUSTOMER_FRAGMENT on Customer {\n addresses {\n default_shipping\n country_code\n postcode\n region {\n region\n region_code\n region_id\n }\n }\n}";
/********************************************************************
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2024 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
* and its suppliers and are protected by all applicable intellectual
* property laws, including trade secret and copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe.
*******************************************************************/
export declare const CUSTOMER_ACCOUNT_FRAGMENT = "\n fragment CUSTOMER_FRAGMENT on Customer {\n addresses {\n default_shipping\n country_code\n postcode\n region {\n region\n region_code\n region_id\n }\n }\n }\n";
//# sourceMappingURL=CustomerAccountFragment.d.ts.map
Original file line number Diff line number Diff line change
@@ -1,2 +1,18 @@
export declare const CUSTOMIZABLE_OPTIONS_FRAGMENT = "\n fragment CUSTOMIZABLE_OPTIONS_FRAGMENT on SelectedCustomizableOption {\n type\n customizable_option_uid\n label\n is_required\n values {\n label\n value\n price{\n type\n units\n value\n }\n }\n }\n";
/********************************************************************
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2024 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
* and its suppliers and are protected by all applicable intellectual
* property laws, including trade secret and copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe.
*******************************************************************/
export declare const CUSTOMIZABLE_OPTIONS_FRAGMENT = "\n fragment CUSTOMIZABLE_OPTIONS_FRAGMENT on SelectedCustomizableOption {\n type\n customizable_option_uid\n label\n is_required\n values {\n label\n value\n price {\n type\n units\n value\n }\n }\n }\n";
//# sourceMappingURL=CustomizableOptionsFragment.d.ts.map
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/********************************************************************
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2024 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
* and its suppliers and are protected by all applicable intellectual
* property laws, including trade secret and copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe.
*******************************************************************/
export declare const DOWNLOADABLE_CART_ITEMS_FRAGMENT = "\n fragment DOWNLOADABLE_CART_ITEMS_FRAGMENT on DownloadableCartItem {\n links {\n sort_order\n title\n }\n customizable_options {\n ...CUSTOMIZABLE_OPTIONS_FRAGMENT\n }\n }\n";
//# sourceMappingURL=DownloadableCartItemsFragment.d.ts.map
Original file line number Diff line number Diff line change
@@ -1,2 +1,18 @@
/********************************************************************
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2024 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
* and its suppliers and are protected by all applicable intellectual
* property laws, including trade secret and copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe.
*******************************************************************/
export declare const PRICE_RANGE_FRAGMENT = "\n fragment PRICE_RANGE_FRAGMENT on PriceRange {\n minimum_price {\n regular_price {\n value\n currency\n }\n final_price {\n value\n currency\n }\n discount {\n percent_off\n amount_off\n }\n }\n maximum_price {\n regular_price {\n value\n currency\n }\n final_price {\n value\n currency\n }\n discount {\n percent_off\n amount_off\n }\n }\n }\n";
//# sourceMappingURL=PriceRangeFragment.d.ts.map
16 changes: 16 additions & 0 deletions scripts/__dropins__/storefront-cart/api/graphql/arguments.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,18 @@
/********************************************************************
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2024 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
* and its suppliers and are protected by all applicable intellectual
* property laws, including trade secret and copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe.
*******************************************************************/
export declare const CART_ITEMS_PAGINATION_ARGUMENTS = "\n $pageSize: Int! = 100,\n $currentPage: Int! = 1,\n $itemsSortInput: QuoteItemsSortInput! = {field: CREATED_AT, order: DESC}\n";
//# sourceMappingURL=arguments.d.ts.map
Loading

0 comments on commit f7e7ac6

Please sign in to comment.