From 52775ccfe3f4666bbbdc0daadc87282ffd37cc93 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Thu, 13 Feb 2025 14:05:39 +0000 Subject: [PATCH 01/11] LYNX-759: Separate requests for customer group and segment --- .../targeted-block/{qraphql.js => graphql.js} | 61 ++++++++++++++++--- blocks/targeted-block/targeted-block.js | 20 ++++-- 2 files changed, 67 insertions(+), 14 deletions(-) rename blocks/targeted-block/{qraphql.js => graphql.js} (50%) diff --git a/blocks/targeted-block/qraphql.js b/blocks/targeted-block/graphql.js similarity index 50% rename from blocks/targeted-block/qraphql.js rename to blocks/targeted-block/graphql.js index df26707693..28889eb87a 100644 --- a/blocks/targeted-block/qraphql.js +++ b/blocks/targeted-block/graphql.js @@ -1,17 +1,55 @@ import { fetchGraphQl, setFetchGraphQlHeaders } from '@dropins/tools/fetch-graphql.js'; import { getHeaders } from '../../scripts/configs.js'; -export const getActiveRules = async (cartId) => { +const getCustomerGroups = async () => { try { - setFetchGraphQlHeaders(await getHeaders('cart')); + // setFetchGraphQlHeaders(await getHeaders('cart')); const response = await fetchGraphQl( - `query CUSTOMER_SEGMENTS($cartId: String!){ - customerSegments(cartId: $cartId) { - name - } + `query { customerGroup { name } + } + `, + { + method: 'GET', + }, + ); + return response.data; + } catch (error) { + console.error('Could not retrieve customer groups', error); + } + return []; +}; + +const getCustomerSegments = async () => { + try { + // setFetchGraphQlHeaders(await getHeaders('cart')); + const response = await fetchGraphQl( + `query { + customer { + segments { + name + } + } + } + `, + { + method: 'GET', + }, + ); + return response.data; + } catch (error) { + console.error('Could not retrieve customer segments', error); + } + return []; +}; + +const getCartRules = async (cartId) => { + try { + // setFetchGraphQlHeaders(await getHeaders('cart')); + const response = await fetchGraphQl( + `query CART_RULES($cartId: String!){ cart(cart_id: $cartId) { rules { name @@ -31,7 +69,7 @@ export const getActiveRules = async (cartId) => { return []; }; -export const getCatalogPriceRules = async (sku) => { +const getCatalogPriceRules = async (sku) => { try { const query = `query CATALOG_PRICE_RULES($sku: String!) { products(filter: { @@ -48,7 +86,7 @@ export const getCatalogPriceRules = async (sku) => { } } `; - setFetchGraphQlHeaders(await getHeaders('cart')); + // setFetchGraphQlHeaders(await getHeaders('cart')); const response = await fetchGraphQl( query, { @@ -62,3 +100,10 @@ export const getCatalogPriceRules = async (sku) => { } return []; }; + +export { + getCustomerGroups, + getCustomerSegments, + getCartRules, + getCatalogPriceRules, +}; diff --git a/blocks/targeted-block/targeted-block.js b/blocks/targeted-block/targeted-block.js index f5fd407709..bb28522686 100644 --- a/blocks/targeted-block/targeted-block.js +++ b/blocks/targeted-block/targeted-block.js @@ -1,6 +1,11 @@ import { events } from '@dropins/tools/event-bus.js'; import * as Cart from '@dropins/storefront-cart/api.js'; -import { getActiveRules, getCatalogPriceRules } from './qraphql.js'; +import { + getCustomerGroups, + getCustomerSegments, + getCartRules, + getCatalogPriceRules, +} from './graphql.js'; import conditionsMatched from './condition-matcher.js'; import { readBlockConfig } from '../../scripts/aem.js'; import { loadFragment } from '../fragment/fragment.js'; @@ -9,18 +14,21 @@ const blocks = []; const displayedBlockTypes = []; const updateTargetedBlocksVisibility = async () => { - const activeRules = (Cart.getCartDataFromCache() === null) ? { - customerSegments: [], - customerGroup: [], + const activeRules = { + customerSegments: await getCustomerSegments(), + customerGroup: await getCustomerGroups(), cart: { rules: [], }, catalogPriceRules: [], - } : await getActiveRules(Cart.getCartDataFromCache().id); + }; + + if (Cart.getCartDataFromCache() !== null) { + activeRules.cart = await getCartRules(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); } From e0bb70edf44d899fb3c64b407668409f7b6d3566 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Thu, 13 Feb 2025 14:25:45 +0000 Subject: [PATCH 02/11] LYNX-759: Refactoring; bugfixing; --- blocks/targeted-block/condition-matcher.js | 2 +- blocks/targeted-block/graphql.js | 10 +++++----- blocks/targeted-block/targeted-block.js | 4 +--- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/blocks/targeted-block/condition-matcher.js b/blocks/targeted-block/condition-matcher.js index fb26d2538d..3a14fad46c 100644 --- a/blocks/targeted-block/condition-matcher.js +++ b/blocks/targeted-block/condition-matcher.js @@ -16,7 +16,7 @@ export default function conditionsMatched(activeRules, blockConfig) { (segment) => segment.name, ); const activeGroup = activeRules.customerGroup?.name; - const activeCartRules = activeRules.cart?.rules?.map( + const activeCartRules = activeRules.cart?.map( (rule) => rule.name, ); const activePriceRules = activeRules.catalogPriceRules?.rules?.map( diff --git a/blocks/targeted-block/graphql.js b/blocks/targeted-block/graphql.js index 28889eb87a..81a0c2ef46 100644 --- a/blocks/targeted-block/graphql.js +++ b/blocks/targeted-block/graphql.js @@ -15,7 +15,7 @@ const getCustomerGroups = async () => { method: 'GET', }, ); - return response.data; + return response.data?.customerGroup; } catch (error) { console.error('Could not retrieve customer groups', error); } @@ -38,7 +38,7 @@ const getCustomerSegments = async () => { method: 'GET', }, ); - return response.data; + return response.data?.customer?.segments || []; } catch (error) { console.error('Could not retrieve customer segments', error); } @@ -62,9 +62,9 @@ const getCartRules = async (cartId) => { variables: { cartId }, }, ); - return response.data; + return response.data?.cart?.rules || []; } catch (error) { - console.error('Could not retrieve customer segments', error); + console.error('Could not retrieve customer cart rules', error); } return []; }; @@ -96,7 +96,7 @@ const getCatalogPriceRules = async (sku) => { ); return response.data?.products?.items[0]; } catch (error) { - console.error(`Could not retrieve catalog rules for ${sku}`, error); + console.error(`Could not retrieve catalog price rules for ${sku}`, error); } return []; }; diff --git a/blocks/targeted-block/targeted-block.js b/blocks/targeted-block/targeted-block.js index bb28522686..6c05144cdd 100644 --- a/blocks/targeted-block/targeted-block.js +++ b/blocks/targeted-block/targeted-block.js @@ -17,9 +17,7 @@ const updateTargetedBlocksVisibility = async () => { const activeRules = { customerSegments: await getCustomerSegments(), customerGroup: await getCustomerGroups(), - cart: { - rules: [], - }, + cart: [], catalogPriceRules: [], }; From 1f023add451adf0fe12e4c1c04988a3f6a4afc8d Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Thu, 13 Feb 2025 14:44:21 +0000 Subject: [PATCH 03/11] LYNX-759: Fix for copy-pasted rules containing whitespaces characters --- blocks/targeted-block/condition-matcher.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/blocks/targeted-block/condition-matcher.js b/blocks/targeted-block/condition-matcher.js index 3a14fad46c..597e4e956e 100644 --- a/blocks/targeted-block/condition-matcher.js +++ b/blocks/targeted-block/condition-matcher.js @@ -1,5 +1,5 @@ function rulesMatched(activeRules, rules) { - return activeRules && rules.some((rule) => activeRules.includes(rule)); + return activeRules && rules.some((rule) => activeRules.includes(rule.trim())); } const groupMatched = (activeGroup, groups) => groups.includes(activeGroup); @@ -13,14 +13,14 @@ export default function conditionsMatched(activeRules, blockConfig) { } = blockConfig; const activeSegments = activeRules.customerSegments?.map( - (segment) => segment.name, + (segment) => segment.name.trim(), ); - const activeGroup = activeRules.customerGroup?.name; + const activeGroup = activeRules.customerGroup?.name.trim(); const activeCartRules = activeRules.cart?.map( - (rule) => rule.name, + (rule) => rule.name.trim(), ); const activePriceRules = activeRules.catalogPriceRules?.rules?.map( - (rule) => rule.name, + (rule) => rule.name.trim(), ); if (customerSegments !== undefined && !rulesMatched(activeSegments, customerSegments.split(','))) { From 5d3444c80e5e74ae9e9e6b8de54d92408cf173c1 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Thu, 13 Feb 2025 15:34:28 +0000 Subject: [PATCH 04/11] LYNX-759: Conditionally query for segments and cart rules --- blocks/targeted-block/graphql.js | 7 +++++-- blocks/targeted-block/targeted-block.js | 16 +++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/blocks/targeted-block/graphql.js b/blocks/targeted-block/graphql.js index 81a0c2ef46..8b036542eb 100644 --- a/blocks/targeted-block/graphql.js +++ b/blocks/targeted-block/graphql.js @@ -49,7 +49,10 @@ const getCartRules = async (cartId) => { try { // setFetchGraphQlHeaders(await getHeaders('cart')); const response = await fetchGraphQl( - `query CART_RULES($cartId: String!){ + `query CUSTOMER_SEGMENTS($cartId: String!){ + customerSegments(cartId: $cartId) { + name + } cart(cart_id: $cartId) { rules { name @@ -62,7 +65,7 @@ const getCartRules = async (cartId) => { variables: { cartId }, }, ); - return response.data?.cart?.rules || []; + return response.data || []; } catch (error) { console.error('Could not retrieve customer cart rules', error); } diff --git a/blocks/targeted-block/targeted-block.js b/blocks/targeted-block/targeted-block.js index 6c05144cdd..2af6471fd8 100644 --- a/blocks/targeted-block/targeted-block.js +++ b/blocks/targeted-block/targeted-block.js @@ -9,20 +9,30 @@ import { import conditionsMatched from './condition-matcher.js'; import { readBlockConfig } from '../../scripts/aem.js'; import { loadFragment } from '../fragment/fragment.js'; +import { getUserTokenCookie } from '../../scripts/initializers/index.js'; const blocks = []; const displayedBlockTypes = []; const updateTargetedBlocksVisibility = async () => { const activeRules = { - customerSegments: await getCustomerSegments(), + customerSegments: [], customerGroup: await getCustomerGroups(), cart: [], catalogPriceRules: [], }; - if (Cart.getCartDataFromCache() !== null) { - activeRules.cart = await getCartRules(Cart.getCartDataFromCache().id); + if (getUserTokenCookie()) { + if (Cart.getCartDataFromCache() === null) { + activeRules.customerSegments = await getCustomerSegments(); + } else { + const cartId = Cart.getCartDataFromCache().id; + if (cartId) { + const response = await getCartRules(cartId); + activeRules.cart = response.cart?.rules || []; + activeRules.customerSegments = response.customerSegments || []; + } + } } // eslint-disable-next-line no-underscore-dangle From 5512110185dec567254934051f38a4b8d47380e6 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Fri, 14 Feb 2025 09:39:29 +0000 Subject: [PATCH 05/11] LYNX-759: handle authenticated event to hide Targeted Block(s) which does not apply anymore --- blocks/targeted-block/targeted-block.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/blocks/targeted-block/targeted-block.js b/blocks/targeted-block/targeted-block.js index 2af6471fd8..1bdb0d785b 100644 --- a/blocks/targeted-block/targeted-block.js +++ b/blocks/targeted-block/targeted-block.js @@ -69,6 +69,10 @@ export default function decorate(block) { block.setAttribute('data-targeted-block-key', blocks.length - 1); } +events.on('authenticated', () => { + updateTargetedBlocksVisibility(); +}, { eager: true }); + events.on('cart/initialized', () => { updateTargetedBlocksVisibility(); }, { eager: true }); From cb5cbfbe0fc1fba98876fb8e41e81f7b10565376 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Fri, 14 Feb 2025 10:38:43 +0000 Subject: [PATCH 06/11] LYNX-759: get customer segments for Guest using cartId --- blocks/targeted-block/graphql.js | 4 ++-- blocks/targeted-block/targeted-block.js | 21 +++++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/blocks/targeted-block/graphql.js b/blocks/targeted-block/graphql.js index 8b036542eb..9d99460068 100644 --- a/blocks/targeted-block/graphql.js +++ b/blocks/targeted-block/graphql.js @@ -49,7 +49,7 @@ const getCartRules = async (cartId) => { try { // setFetchGraphQlHeaders(await getHeaders('cart')); const response = await fetchGraphQl( - `query CUSTOMER_SEGMENTS($cartId: String!){ + `query TB_GET_CUSTOMER_SEGMENTS_CART_RULES($cartId: String!){ customerSegments(cartId: $cartId) { name } @@ -74,7 +74,7 @@ const getCartRules = async (cartId) => { const getCatalogPriceRules = async (sku) => { try { - const query = `query CATALOG_PRICE_RULES($sku: String!) { + const query = `query TB_GET_CATALOG_PRICE_RULES($sku: String!) { products(filter: { sku: { eq: $sku diff --git a/blocks/targeted-block/targeted-block.js b/blocks/targeted-block/targeted-block.js index 1bdb0d785b..bed047ad8a 100644 --- a/blocks/targeted-block/targeted-block.js +++ b/blocks/targeted-block/targeted-block.js @@ -15,6 +15,7 @@ const blocks = []; const displayedBlockTypes = []; const updateTargetedBlocksVisibility = async () => { + const activeRules = { customerSegments: [], customerGroup: await getCustomerGroups(), @@ -22,19 +23,19 @@ const updateTargetedBlocksVisibility = async () => { catalogPriceRules: [], }; - if (getUserTokenCookie()) { - if (Cart.getCartDataFromCache() === null) { - activeRules.customerSegments = await getCustomerSegments(); - } else { - const cartId = Cart.getCartDataFromCache().id; - if (cartId) { - const response = await getCartRules(cartId); - activeRules.cart = response.cart?.rules || []; - activeRules.customerSegments = response.customerSegments || []; - } + if (Cart.getCartDataFromCache() !== null) { + const cartId = Cart.getCartDataFromCache() && Cart.getCartDataFromCache().id; + if (cartId) { + const response = await getCartRules(cartId); + activeRules.cart = response.cart?.rules || []; + activeRules.customerSegments = response.customerSegments || []; } } + if (Cart.getCartDataFromCache() === null && getUserTokenCookie()) { + activeRules.customerSegments = await getCustomerSegments(); + } + // eslint-disable-next-line no-underscore-dangle const productData = events._lastEvent?.['pdp/data']?.payload ?? null; if (productData?.sku) { From 34314436c5fa37764ebc854ddb84bf82f406a86f Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Fri, 14 Feb 2025 13:45:30 +0000 Subject: [PATCH 07/11] LYNX-759: Make sure updateTargetedBlocksVisibility() is called only once --- blocks/targeted-block/targeted-block.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/blocks/targeted-block/targeted-block.js b/blocks/targeted-block/targeted-block.js index bed047ad8a..0f3e174bce 100644 --- a/blocks/targeted-block/targeted-block.js +++ b/blocks/targeted-block/targeted-block.js @@ -13,9 +13,13 @@ import { getUserTokenCookie } from '../../scripts/initializers/index.js'; const blocks = []; const displayedBlockTypes = []; +let updated = false; const updateTargetedBlocksVisibility = async () => { - + if (updated) { + return; + } + const activeRules = { customerSegments: [], customerGroup: await getCustomerGroups(), @@ -62,6 +66,7 @@ const updateTargetedBlocksVisibility = async () => { block.style.display = ''; } }); + updated = true; }; export default function decorate(block) { From fb8cb659dd83aed3b2512c08106f34bd6829a431 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Fri, 14 Feb 2025 13:49:23 +0000 Subject: [PATCH 08/11] revert latest change --- blocks/targeted-block/targeted-block.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/blocks/targeted-block/targeted-block.js b/blocks/targeted-block/targeted-block.js index 0f3e174bce..b1a129f14f 100644 --- a/blocks/targeted-block/targeted-block.js +++ b/blocks/targeted-block/targeted-block.js @@ -13,13 +13,8 @@ import { getUserTokenCookie } from '../../scripts/initializers/index.js'; const blocks = []; const displayedBlockTypes = []; -let updated = false; const updateTargetedBlocksVisibility = async () => { - if (updated) { - return; - } - const activeRules = { customerSegments: [], customerGroup: await getCustomerGroups(), @@ -66,7 +61,6 @@ const updateTargetedBlocksVisibility = async () => { block.style.display = ''; } }); - updated = true; }; export default function decorate(block) { @@ -75,14 +69,14 @@ export default function decorate(block) { block.setAttribute('data-targeted-block-key', blocks.length - 1); } -events.on('authenticated', () => { +events.on('cart/initialized', () => { updateTargetedBlocksVisibility(); }, { eager: true }); -events.on('cart/initialized', () => { +events.on('cart/updated', () => { updateTargetedBlocksVisibility(); }, { eager: true }); -events.on('cart/updated', () => { +events.on('authenticated', () => { updateTargetedBlocksVisibility(); }, { eager: true }); From f19381bd8d1842b7e345c8666dfd80035f94009d Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Fri, 14 Feb 2025 13:59:34 +0000 Subject: [PATCH 09/11] LYNX-759: Make sure updateTargetedBlocksVisibility() is called only once --- blocks/targeted-block/targeted-block.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/blocks/targeted-block/targeted-block.js b/blocks/targeted-block/targeted-block.js index b1a129f14f..1ba3199cbe 100644 --- a/blocks/targeted-block/targeted-block.js +++ b/blocks/targeted-block/targeted-block.js @@ -69,14 +69,14 @@ export default function decorate(block) { block.setAttribute('data-targeted-block-key', blocks.length - 1); } -events.on('cart/initialized', () => { +events.on('cart/reset', () => { updateTargetedBlocksVisibility(); }, { eager: true }); -events.on('cart/updated', () => { +events.on('cart/initialized', () => { updateTargetedBlocksVisibility(); }, { eager: true }); -events.on('authenticated', () => { +events.on('cart/updated', () => { updateTargetedBlocksVisibility(); }, { eager: true }); From 324a5b2cc30f15aeaf345c893cb91f9fe388dc39 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Fri, 14 Feb 2025 14:53:08 +0000 Subject: [PATCH 10/11] remove redundant condition --- blocks/targeted-block/targeted-block.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blocks/targeted-block/targeted-block.js b/blocks/targeted-block/targeted-block.js index 1ba3199cbe..0b4e8f18b4 100644 --- a/blocks/targeted-block/targeted-block.js +++ b/blocks/targeted-block/targeted-block.js @@ -23,7 +23,7 @@ const updateTargetedBlocksVisibility = async () => { }; if (Cart.getCartDataFromCache() !== null) { - const cartId = Cart.getCartDataFromCache() && Cart.getCartDataFromCache().id; + const cartId = Cart.getCartDataFromCache().id || null; if (cartId) { const response = await getCartRules(cartId); activeRules.cart = response.cart?.rules || []; From 81681fa315421fedf614993ff1d55b86b70bfb92 Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko Date: Fri, 14 Feb 2025 17:16:12 +0000 Subject: [PATCH 11/11] Headers fix --- blocks/targeted-block/graphql.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/blocks/targeted-block/graphql.js b/blocks/targeted-block/graphql.js index 9d99460068..d32403fac7 100644 --- a/blocks/targeted-block/graphql.js +++ b/blocks/targeted-block/graphql.js @@ -1,9 +1,16 @@ -import { fetchGraphQl, setFetchGraphQlHeaders } from '@dropins/tools/fetch-graphql.js'; +import { fetchGraphQl, setFetchGraphQlHeader } from '@dropins/tools/fetch-graphql.js'; import { getHeaders } from '../../scripts/configs.js'; +const addCartHeaders = async () => { + const cartHeaders = await getHeaders('cart'); + cartHeaders.keys().forEach((key) => { + setFetchGraphQlHeader(key, cartHeaders[key]); + }); +}; + const getCustomerGroups = async () => { try { - // setFetchGraphQlHeaders(await getHeaders('cart')); + addCartHeaders(); const response = await fetchGraphQl( `query { customerGroup { @@ -24,7 +31,7 @@ const getCustomerGroups = async () => { const getCustomerSegments = async () => { try { - // setFetchGraphQlHeaders(await getHeaders('cart')); + addCartHeaders(); const response = await fetchGraphQl( `query { customer { @@ -47,7 +54,7 @@ const getCustomerSegments = async () => { const getCartRules = async (cartId) => { try { - // setFetchGraphQlHeaders(await getHeaders('cart')); + addCartHeaders(); const response = await fetchGraphQl( `query TB_GET_CUSTOMER_SEGMENTS_CART_RULES($cartId: String!){ customerSegments(cartId: $cartId) { @@ -89,7 +96,7 @@ const getCatalogPriceRules = async (sku) => { } } `; - // setFetchGraphQlHeaders(await getHeaders('cart')); + addCartHeaders(); const response = await fetchGraphQl( query, {