@useinsider/guido 3.7.2-beta.1e8f93e → 3.7.2-beta.2220fb0
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/@types/config/schemas.js +70 -66
- package/dist/composables/usePreviewMode.js +15 -14
- package/dist/composables/useRecommendationPreview.js +100 -0
- package/dist/config/compiler/recommendationCompilerRules.js +1 -1
- package/dist/config/compiler/utils/recommendationCompilerUtils.js +90 -82
- package/dist/config/migrator/recommendation/htmlBuilder.js +59 -58
- package/dist/config/migrator/recommendation/settingsMapper.js +38 -33
- package/dist/extensions/Blocks/Items/block.js +29 -48
- package/dist/extensions/Blocks/Items/utils/nodeConfigUtils.js +45 -62
- package/dist/extensions/Blocks/Recommendation/block.js +60 -41
- package/dist/extensions/Blocks/Recommendation/canvasPreview.css.js +16 -0
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +41 -32
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +369 -288
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +96 -84
- package/dist/extensions/Blocks/Recommendation/controls/main/pricePlacement.js +133 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +83 -81
- package/dist/extensions/Blocks/Recommendation/extension.js +30 -29
- package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +21 -7
- package/dist/extensions/Blocks/Recommendation/recommendation.css.js +64 -4
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +7 -5
- package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +109 -78
- package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +31 -30
- package/dist/extensions/Blocks/Recommendation/templates/index.js +9 -7
- package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +78 -61
- package/dist/extensions/Blocks/Recommendation/templates/list/template.js +21 -21
- package/dist/extensions/Blocks/Recommendation/templates/utils.js +90 -55
- package/dist/src/@types/config/schemas.d.ts +16 -0
- package/dist/src/composables/useConfig.d.ts +4 -0
- package/dist/src/composables/useRecommendationPreview.d.ts +10 -0
- package/dist/src/config/migrator/recommendation/settingsMapper.d.ts +1 -1
- package/dist/src/extensions/Blocks/Items/block.d.ts +0 -8
- package/dist/src/extensions/Blocks/Items/utils/nodeConfigUtils.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/block.d.ts +10 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +29 -3
- package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +3 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/pricePlacement.d.ts +59 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/grid/elementRenderer.d.ts +16 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
- package/dist/src/extensions/Blocks/Recommendation/templates/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/templates/list/elementRenderer.d.ts +13 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +3 -2
- package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +39 -1
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +15 -0
- package/dist/src/stores/config.d.ts +36 -0
- package/package.json +1 -1
|
@@ -1,70 +1,75 @@
|
|
|
1
1
|
import { CURRENT_CONFIG_VERSION as s, DEFAULT_CURRENCY as i } from "../../../extensions/Blocks/Recommendation/constants/defaultConfig.js";
|
|
2
|
-
import { DEFAULT_CARDS_IN_ROW as m, DEFAULT_MOBILE_ROW_SPACING as p, DEFAULT_MOBILE_COLUMN_SPACING as
|
|
3
|
-
import { mapLegacyStrategy as
|
|
4
|
-
function
|
|
2
|
+
import { DEFAULT_CARDS_IN_ROW as m, DEFAULT_MOBILE_ROW_SPACING as p, DEFAULT_MOBILE_COLUMN_SPACING as d, DEFAULT_ROW_SPACING as f, DEFAULT_COLUMN_SPACING as S, DEFAULT_MOBILE_CARDS_IN_ROW as a } from "../../../extensions/Blocks/Recommendation/constants/layout.js";
|
|
3
|
+
import { mapLegacyStrategy as l } from "../../../extensions/Blocks/Recommendation/utils/legacyStrategyMap.js";
|
|
4
|
+
function c(t) {
|
|
5
5
|
return t === "0" || t === 0 ? "before" : "after";
|
|
6
6
|
}
|
|
7
|
-
function
|
|
7
|
+
function I(t) {
|
|
8
8
|
if (typeof t == "number" && Number.isFinite(t))
|
|
9
9
|
return t;
|
|
10
10
|
if (typeof t == "string") {
|
|
11
|
-
const
|
|
12
|
-
if (!Number.isNaN(
|
|
13
|
-
return
|
|
11
|
+
const o = parseInt(t);
|
|
12
|
+
if (!Number.isNaN(o))
|
|
13
|
+
return o;
|
|
14
14
|
}
|
|
15
15
|
return i.decimalCount;
|
|
16
16
|
}
|
|
17
|
-
function
|
|
17
|
+
function _(t) {
|
|
18
18
|
return t === "." || t === "," || t === " " || t === "" ? t : ",";
|
|
19
19
|
}
|
|
20
|
-
function
|
|
20
|
+
function N(t) {
|
|
21
21
|
return t === "." || t === "," || t === " " ? t : ".";
|
|
22
22
|
}
|
|
23
|
-
function
|
|
23
|
+
function A(t) {
|
|
24
24
|
if (!t || typeof t != "object")
|
|
25
25
|
return { ...i };
|
|
26
|
-
const
|
|
26
|
+
const o = t, n = o.value ?? o.name ?? i.code, r = o.symbol ?? n;
|
|
27
27
|
return {
|
|
28
|
-
code:
|
|
28
|
+
code: n,
|
|
29
29
|
symbol: r,
|
|
30
|
-
alignment:
|
|
31
|
-
decimalCount:
|
|
32
|
-
decimalSeparator:
|
|
33
|
-
thousandSeparator:
|
|
30
|
+
alignment: c(o.alignment),
|
|
31
|
+
decimalCount: I(o.decimalCount),
|
|
32
|
+
decimalSeparator: N(o.decimalSeparator),
|
|
33
|
+
thousandSeparator: _(o.thousandSeparator)
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
|
-
function
|
|
36
|
+
function L(t) {
|
|
37
37
|
return t === "horizontal" || t === "list" ? "list" : "grid";
|
|
38
38
|
}
|
|
39
|
-
function
|
|
40
|
-
return
|
|
39
|
+
function R(t) {
|
|
40
|
+
return l(t) || "mostPopular";
|
|
41
41
|
}
|
|
42
|
-
function
|
|
43
|
-
const r =
|
|
42
|
+
function U(t, o, n) {
|
|
43
|
+
const r = o.rowCount ?? t.cardsInRow ?? m, u = o.totalCount ?? (typeof t.size == "string" ? parseInt(t.size) : t.size) ?? 6;
|
|
44
44
|
return {
|
|
45
|
-
recommendationId:
|
|
46
|
-
strategy:
|
|
45
|
+
recommendationId: n,
|
|
46
|
+
strategy: R(t.strategy),
|
|
47
47
|
productIds: (t.productIds ?? []).map((e) => String(e)),
|
|
48
|
-
size: String(
|
|
48
|
+
size: String(u),
|
|
49
49
|
shuffleProducts: !!t.shuffleProducts,
|
|
50
50
|
language: t.language ?? "en_US",
|
|
51
|
-
currency:
|
|
51
|
+
currency: A(t.currencySettings),
|
|
52
52
|
filters: (t.filters ?? []).map((e) => ({ ...e })),
|
|
53
|
-
layout:
|
|
53
|
+
layout: L(t.orientation ?? o.orientation),
|
|
54
54
|
cardsInRow: r,
|
|
55
|
-
mobileCardsInRow:
|
|
55
|
+
mobileCardsInRow: a,
|
|
56
56
|
mobileLayoutEnabled: !1,
|
|
57
|
-
previousMobileCardsInRow:
|
|
58
|
-
columnSpacing:
|
|
59
|
-
rowSpacing:
|
|
60
|
-
mobileColumnSpacing:
|
|
57
|
+
previousMobileCardsInRow: a,
|
|
58
|
+
columnSpacing: S,
|
|
59
|
+
rowSpacing: f,
|
|
60
|
+
mobileColumnSpacing: d,
|
|
61
61
|
mobileRowSpacing: p,
|
|
62
62
|
omnibusPrice: { textBefore: "", textAfter: "" },
|
|
63
63
|
omnibusDiscount: { textBefore: "", textAfter: "" },
|
|
64
|
+
// Preserve the legacy price-placement toggles. Absent legacy keys map to
|
|
65
|
+
// `false`, matching the legacy default (prices inline, original price not
|
|
66
|
+
// gated). New Guido blocks default differently (see DEFAULT_NODE_CONFIG).
|
|
67
|
+
priceMovedToNextLine: !!t.isPriceMovedToNextLine,
|
|
68
|
+
priceHideIfSameAsDiscounted: !!t.isPriceDeletedForZeroSale,
|
|
64
69
|
configVersion: s
|
|
65
70
|
};
|
|
66
71
|
}
|
|
67
72
|
export {
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
A as mapCurrency,
|
|
74
|
+
U as mapSettings
|
|
70
75
|
};
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { BlockId as
|
|
1
|
+
import { BlockId as g } from "../../../enums/block.js";
|
|
2
2
|
import { useOnboardingStore as p } from "../../../stores/onboarding.js";
|
|
3
|
-
import { getMigrationBannerHtml as
|
|
4
|
-
import { Block as
|
|
5
|
-
import { SETTINGS_ENUMS as
|
|
6
|
-
import { getDefaultTemplate as
|
|
7
|
-
import { getItemsBlockContainer as
|
|
8
|
-
const
|
|
9
|
-
class E extends
|
|
3
|
+
import { getMigrationBannerHtml as f } from "../../../utils/migrationBannerHtml.js";
|
|
4
|
+
import { Block as u, BlockCompositionType as I, ModificationDescription as o } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
|
+
import { SETTINGS_ENUMS as a, DefaultConfigValues as i } from "./enums/settingsEnums.js";
|
|
6
|
+
import { getDefaultTemplate as C } from "./template.js";
|
|
7
|
+
import { getItemsBlockContainer as y, getItemsBlockConfig as b, getDefaultItemsBlockConfig as h } from "./utils/nodeConfigUtils.js";
|
|
8
|
+
const c = g.Items;
|
|
9
|
+
class E extends u {
|
|
10
10
|
getId() {
|
|
11
|
-
return
|
|
11
|
+
return c;
|
|
12
12
|
}
|
|
13
13
|
getIcon() {
|
|
14
14
|
return "items-icon";
|
|
15
15
|
}
|
|
16
16
|
getBlockCompositionType() {
|
|
17
|
-
return
|
|
17
|
+
return I.CONTAINER;
|
|
18
18
|
}
|
|
19
19
|
getName() {
|
|
20
20
|
return this.api.translate("Items");
|
|
@@ -23,60 +23,41 @@ class E extends I {
|
|
|
23
23
|
return this.api.translate("Items lets you display personalized products based on user behavior.");
|
|
24
24
|
}
|
|
25
25
|
getSettingsPanelTitleHtml() {
|
|
26
|
-
return
|
|
27
|
-
|
|
26
|
+
return f(
|
|
27
|
+
c,
|
|
28
28
|
this.api.translate("Items"),
|
|
29
29
|
this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Items block and test your message to ensure it works properly.")
|
|
30
30
|
);
|
|
31
31
|
}
|
|
32
32
|
getTemplate() {
|
|
33
|
-
return
|
|
34
|
-
orientation:
|
|
35
|
-
itemsType:
|
|
33
|
+
return C({
|
|
34
|
+
orientation: a.ORIENTATION.VERTICAL,
|
|
35
|
+
itemsType: a.ITEMS_TYPE.CART_ITEMS,
|
|
36
36
|
itemId: "{{Abandoned Cart Item (1) Url}}",
|
|
37
|
-
currencySymbol:
|
|
38
|
-
currencyLocation:
|
|
39
|
-
formattedPrice:
|
|
37
|
+
currencySymbol: i.productPriceCurrencySymbolControlValue,
|
|
38
|
+
currencyLocation: i.productPriceCurrencyLocationControlValue,
|
|
39
|
+
formattedPrice: i.productPriceFormattedControlValue === "1"
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
42
|
allowInnerBlocksDND() {
|
|
43
43
|
return !1;
|
|
44
44
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
r.querySelector('[product-attr="imageSrc"] img') || n.modifyCss(r).appendRule('[product-attr="imageSrc"] img {object-fit: contain;}');
|
|
51
|
-
const t = l(i);
|
|
52
|
-
if (!t)
|
|
45
|
+
onCreated(n) {
|
|
46
|
+
const l = this.api.getDocumentModifier(), r = this.api.getDocumentRootCssNode();
|
|
47
|
+
r.querySelector('[product-attr="imageSrc"] img') || l.modifyCss(r).appendRule('[product-attr="imageSrc"] img {object-fit: contain;}');
|
|
48
|
+
const e = y(n);
|
|
49
|
+
if (!e)
|
|
53
50
|
return;
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
56
|
-
|
|
51
|
+
const s = e.getNodeConfig(), m = s && Object.keys(s).length > 0, t = b(n);
|
|
52
|
+
if (t != null && t.initialized)
|
|
53
|
+
m ? t.blockInstanceId || this.api.getDocumentModifier().modifyHtml(e).setNodeConfig({ ...t, blockInstanceId: String(Date.now()) }).apply(new o("Assign block instance ID to block")) : this.api.getDocumentModifier().modifyHtml(e).setNodeConfig(t).apply(new o("Migrate legacy config to nodeConfig"));
|
|
57
54
|
else {
|
|
58
|
-
const
|
|
59
|
-
this.api.getDocumentModifier().modifyHtml(
|
|
55
|
+
const d = h();
|
|
56
|
+
this.api.getDocumentModifier().modifyHtml(e).setNodeConfig(d).apply(new o("Initialize Items block with default configuration")), p().startOnboarding("itemsOnboarding");
|
|
60
57
|
}
|
|
61
58
|
}
|
|
62
|
-
/**
|
|
63
|
-
* Re-seeds nodeConfig from the persisted esd-ext-config when a saved module
|
|
64
|
-
* surfaces via document load. Stripo strips esd-ext-config and never restores it
|
|
65
|
-
* into nodeConfig, so without this a reused module would reset to defaults.
|
|
66
|
-
* Guarded to the nodeConfig-empty case so it runs once and never loops.
|
|
67
|
-
*/
|
|
68
|
-
onDocumentChanged(i) {
|
|
69
|
-
const n = l(i);
|
|
70
|
-
if (!n)
|
|
71
|
-
return;
|
|
72
|
-
const r = n.getNodeConfig();
|
|
73
|
-
if (r && Object.keys(r).length > 0)
|
|
74
|
-
return;
|
|
75
|
-
const e = m(i);
|
|
76
|
-
e != null && e.initialized && this.api.getDocumentModifier().modifyHtml(n).setNodeConfig(e).apply(new s("Recover Items block config from saved module"));
|
|
77
|
-
}
|
|
78
59
|
}
|
|
79
60
|
export {
|
|
80
|
-
|
|
61
|
+
c as BLOCK_ID,
|
|
81
62
|
E as ItemsBlock
|
|
82
63
|
};
|
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
import { ModificationDescription as b } from "../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
2
|
-
import { DefaultConfigValues as
|
|
2
|
+
import { DefaultConfigValues as o, SETTINGS_ENUMS as n, ItemInCartOptions as g } from "../enums/settingsEnums.js";
|
|
3
3
|
function _() {
|
|
4
4
|
return String(Date.now() + Math.floor(Math.random() * 1e3));
|
|
5
5
|
}
|
|
6
6
|
const E = (r) => r.replace(/\$/g, "$$$$");
|
|
7
|
-
function
|
|
7
|
+
function S() {
|
|
8
8
|
return {
|
|
9
9
|
initialized: !0,
|
|
10
10
|
blockInstanceId: _(),
|
|
11
11
|
source: n.ITEMS_TYPE.CART_ITEMS,
|
|
12
12
|
type: n.ITEMS_TYPE.CART_ITEMS,
|
|
13
|
-
itemsSelectValue:
|
|
13
|
+
itemsSelectValue: o.cartItemsSelectControlValue,
|
|
14
14
|
orientation: n.ORIENTATION.VERTICAL,
|
|
15
|
-
nameTrimming:
|
|
16
|
-
priceHideDiscount:
|
|
17
|
-
priceFormatted:
|
|
15
|
+
nameTrimming: o.productNameTrimmingControlValue === "1",
|
|
16
|
+
priceHideDiscount: o.productPriceHideDiscountControlValue === "1",
|
|
17
|
+
priceFormatted: o.productPriceFormattedControlValue === "1",
|
|
18
18
|
priceSinglePrice: !1,
|
|
19
|
-
priceCurrencySymbol:
|
|
20
|
-
priceCurrencyLocation:
|
|
19
|
+
priceCurrencySymbol: o.productPriceCurrencySymbolControlValue,
|
|
20
|
+
priceCurrencyLocation: o.productPriceCurrencyLocationControlValue,
|
|
21
21
|
priceOrientation: "horizontal",
|
|
22
|
-
quantityControlEnabled:
|
|
23
|
-
buttonLink:
|
|
24
|
-
imageLink:
|
|
22
|
+
quantityControlEnabled: o.productQuantityControlEnabled === "1",
|
|
23
|
+
buttonLink: o.productButtonLinkControlValue,
|
|
24
|
+
imageLink: o.productImageLinkControlValue,
|
|
25
25
|
buttonLabel: "Buy",
|
|
26
26
|
buttonFullWidth: !0,
|
|
27
27
|
// Default to full width (es-fw class)
|
|
28
|
-
imageVisible:
|
|
29
|
-
nameVisible:
|
|
30
|
-
quantityVisible:
|
|
31
|
-
priceVisible:
|
|
32
|
-
originalPriceVisible:
|
|
33
|
-
buttonVisible:
|
|
28
|
+
imageVisible: o.productImageVisible === "1",
|
|
29
|
+
nameVisible: o.productNameVisible === "1",
|
|
30
|
+
quantityVisible: o.productQuantityVisible === "1",
|
|
31
|
+
priceVisible: o.productPriceVisible === "1",
|
|
32
|
+
originalPriceVisible: o.productOriginalPriceVisible === "1",
|
|
33
|
+
buttonVisible: o.productButtonVisible === "1"
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
function p(r) {
|
|
@@ -50,26 +50,26 @@ function m(r) {
|
|
|
50
50
|
PURCHASED_ITEMS: n.ITEMS_TYPE.PURCHASED_ITEMS
|
|
51
51
|
}[r] || n.ITEMS_TYPE.CART_ITEMS : n.ITEMS_TYPE.CART_ITEMS;
|
|
52
52
|
}
|
|
53
|
-
function
|
|
53
|
+
function I(r, t) {
|
|
54
54
|
if (!r)
|
|
55
|
-
return
|
|
55
|
+
return o.cartItemsSelectControlValue;
|
|
56
56
|
if (r.includes("{{"))
|
|
57
57
|
return r;
|
|
58
58
|
if (/^\d+$/.test(r)) {
|
|
59
|
-
const e = parseInt(r) - 1,
|
|
60
|
-
if (
|
|
61
|
-
return
|
|
59
|
+
const e = parseInt(r) - 1, i = g[t];
|
|
60
|
+
if (i && i[e])
|
|
61
|
+
return i[e].value;
|
|
62
62
|
}
|
|
63
|
-
return
|
|
63
|
+
return o.cartItemsSelectControlValue;
|
|
64
64
|
}
|
|
65
65
|
function C(r) {
|
|
66
66
|
const t = r.querySelector("esd-config-block");
|
|
67
67
|
if (!t)
|
|
68
68
|
return null;
|
|
69
|
-
const e = (
|
|
69
|
+
const e = (c, s) => c == null ? s : c === "1" || c === "true", i = (c, s) => c || s, u = t.getAttribute("data-type"), a = m(u), d = t.getAttribute("data-cart_items_select_control_value"), l = I(d, a);
|
|
70
70
|
return {
|
|
71
71
|
initialized: e(t.getAttribute("data-initialized"), !1),
|
|
72
|
-
blockInstanceId:
|
|
72
|
+
blockInstanceId: i(
|
|
73
73
|
t.getAttribute("data-block-instance-id"),
|
|
74
74
|
_()
|
|
75
75
|
),
|
|
@@ -93,28 +93,28 @@ function C(r) {
|
|
|
93
93
|
t.getAttribute("data-product_price_control_single_price"),
|
|
94
94
|
!1
|
|
95
95
|
),
|
|
96
|
-
priceCurrencySymbol:
|
|
96
|
+
priceCurrencySymbol: i(
|
|
97
97
|
t.getAttribute("data-product_price_control_currency_symbol"),
|
|
98
|
-
|
|
98
|
+
o.productPriceCurrencySymbolControlValue
|
|
99
99
|
),
|
|
100
|
-
priceCurrencyLocation:
|
|
100
|
+
priceCurrencyLocation: i(
|
|
101
101
|
t.getAttribute("data-product_price_currency_location"),
|
|
102
|
-
|
|
102
|
+
o.productPriceCurrencyLocationControlValue
|
|
103
103
|
),
|
|
104
104
|
priceOrientation: t.getAttribute("data-product_original_price_control_orientation") || "horizontal",
|
|
105
105
|
quantityControlEnabled: e(
|
|
106
106
|
t.getAttribute("data-product_quantity_control_enabled"),
|
|
107
107
|
!0
|
|
108
108
|
),
|
|
109
|
-
buttonLink:
|
|
109
|
+
buttonLink: i(
|
|
110
110
|
t.getAttribute("data-product_button_link"),
|
|
111
|
-
|
|
111
|
+
o.productButtonLinkControlValue
|
|
112
112
|
),
|
|
113
|
-
imageLink:
|
|
113
|
+
imageLink: i(
|
|
114
114
|
t.getAttribute("data-product_image_link"),
|
|
115
|
-
|
|
115
|
+
o.productImageLinkControlValue
|
|
116
116
|
),
|
|
117
|
-
buttonLabel:
|
|
117
|
+
buttonLabel: i(
|
|
118
118
|
t.getAttribute("data-product_button_control_label"),
|
|
119
119
|
"Buy"
|
|
120
120
|
),
|
|
@@ -149,45 +149,28 @@ function C(r) {
|
|
|
149
149
|
)
|
|
150
150
|
};
|
|
151
151
|
}
|
|
152
|
-
function
|
|
153
|
-
if (typeof r.getAttribute != "function")
|
|
154
|
-
return null;
|
|
155
|
-
const t = r.getAttribute("esd-ext-config");
|
|
156
|
-
if (!t)
|
|
157
|
-
return null;
|
|
158
|
-
try {
|
|
159
|
-
const e = JSON.parse(t);
|
|
160
|
-
if (e && e.initialized)
|
|
161
|
-
return e;
|
|
162
|
-
} catch {
|
|
163
|
-
}
|
|
164
|
-
return null;
|
|
165
|
-
}
|
|
166
|
-
function A(r) {
|
|
152
|
+
function y(r) {
|
|
167
153
|
const t = p(r);
|
|
168
154
|
if (!t)
|
|
169
155
|
return null;
|
|
170
156
|
const e = t.getNodeConfig();
|
|
171
157
|
if (e && e.initialized)
|
|
172
158
|
return e;
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
return o;
|
|
176
|
-
const c = C(t);
|
|
177
|
-
return c || null;
|
|
159
|
+
const i = C(t);
|
|
160
|
+
return i || null;
|
|
178
161
|
}
|
|
179
|
-
function
|
|
180
|
-
const
|
|
181
|
-
if (!
|
|
162
|
+
function A(r, t, e, i) {
|
|
163
|
+
const u = p(r);
|
|
164
|
+
if (!u)
|
|
182
165
|
return;
|
|
183
|
-
const d = { ...
|
|
184
|
-
l.modifyHtml(
|
|
166
|
+
const d = { ...u.getNodeConfig() || {}, ...e }, l = i ?? t.getDocumentModifier();
|
|
167
|
+
l.modifyHtml(u).setNodeConfig(d), i || l.apply(new b("Update Items block configuration"));
|
|
185
168
|
}
|
|
186
169
|
export {
|
|
187
170
|
E as escapeReplacement,
|
|
188
171
|
_ as generateBlockInstanceId,
|
|
189
|
-
|
|
190
|
-
|
|
172
|
+
S as getDefaultItemsBlockConfig,
|
|
173
|
+
y as getItemsBlockConfig,
|
|
191
174
|
p as getItemsBlockContainer,
|
|
192
|
-
|
|
175
|
+
A as setItemsBlockConfig
|
|
193
176
|
};
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
1
|
+
var B = Object.defineProperty;
|
|
2
|
+
var D = (a, c, t) => c in a ? B(a, c, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[c] = t;
|
|
3
|
+
var h = (a, c, t) => D(a, typeof c != "symbol" ? c + "" : c, t);
|
|
4
4
|
import { BlockId as R } from "../../../enums/block.js";
|
|
5
5
|
import { getMigrationBannerHtml as y } from "../../../utils/migrationBannerHtml.js";
|
|
6
|
-
import { Block as
|
|
7
|
-
import { regenerateMobileProductRows as
|
|
8
|
-
import { ensureMobileCssRulesExist as p, setMobileLayoutOptOut as f, hasMobileLayoutOptOut as
|
|
9
|
-
import { RecommendationConfigService as
|
|
10
|
-
import { useRecommendationExtensionStore as
|
|
11
|
-
import { getDefaultTemplate as
|
|
6
|
+
import { Block as b, BlockCompositionType as A, ModificationDescription as g } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
7
|
+
import { regenerateMobileProductRows as C } from "./controls/main/utils.js";
|
|
8
|
+
import { ensureMobileCssRulesExist as p, setMobileLayoutOptOut as f, hasMobileLayoutOptOut as E } from "./controls/mobileLayout/cssRules.js";
|
|
9
|
+
import { RecommendationConfigService as s } from "./services/configService.js";
|
|
10
|
+
import { useRecommendationExtensionStore as d } from "./store/recommendation.js";
|
|
11
|
+
import { getDefaultTemplate as S } from "./templates/grid/template.js";
|
|
12
12
|
import { useRecommendationBlockWarning as M } from "./useRecommendationBlockWarning.js";
|
|
13
|
-
const
|
|
14
|
-
let
|
|
15
|
-
class
|
|
13
|
+
const _ = R.Recommendation, m = "recommendation-block-v2", u = "recommendation-id", I = "hide-price";
|
|
14
|
+
let k = !1;
|
|
15
|
+
class P extends b {
|
|
16
16
|
constructor() {
|
|
17
17
|
super();
|
|
18
18
|
/**
|
|
19
19
|
* Stores the ID generated in getTemplate() so onCreated() can reuse it.
|
|
20
20
|
* This avoids generating a new (different) ID in onCreated().
|
|
21
21
|
*/
|
|
22
|
-
|
|
22
|
+
h(this, "_pendingBlockId", null);
|
|
23
23
|
}
|
|
24
24
|
getId() {
|
|
25
|
-
return
|
|
25
|
+
return _;
|
|
26
26
|
}
|
|
27
27
|
getIcon() {
|
|
28
28
|
return "recommendation-icon";
|
|
29
29
|
}
|
|
30
30
|
getBlockCompositionType() {
|
|
31
|
-
return
|
|
31
|
+
return A.CONTAINER;
|
|
32
32
|
}
|
|
33
33
|
getName() {
|
|
34
34
|
return this.api.translate("Recommendation Block");
|
|
@@ -40,7 +40,7 @@ class H extends D {
|
|
|
40
40
|
}
|
|
41
41
|
getSettingsPanelTitleHtml() {
|
|
42
42
|
return y(
|
|
43
|
-
|
|
43
|
+
_,
|
|
44
44
|
this.api.translate("Recommendation Block"),
|
|
45
45
|
this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Recommendation block and test your message to ensure it works properly.")
|
|
46
46
|
);
|
|
@@ -60,7 +60,7 @@ class H extends D {
|
|
|
60
60
|
*/
|
|
61
61
|
getTemplate() {
|
|
62
62
|
const t = this._generateNextId();
|
|
63
|
-
return this._pendingBlockId = t,
|
|
63
|
+
return this._pendingBlockId = t, S(t);
|
|
64
64
|
}
|
|
65
65
|
/**
|
|
66
66
|
* Called when a new block is dropped into the template
|
|
@@ -83,20 +83,20 @@ class H extends D {
|
|
|
83
83
|
}
|
|
84
84
|
const i = this._pendingBlockId ?? this._generateNextId();
|
|
85
85
|
this._pendingBlockId = null, this._assignRecommendationId(t, i);
|
|
86
|
-
const { config: n, wasFreshDrop: o } =
|
|
86
|
+
const { config: n, wasFreshDrop: o } = s.initializeConfig(
|
|
87
87
|
this.api,
|
|
88
88
|
t,
|
|
89
89
|
{ recommendationId: i }
|
|
90
|
-
),
|
|
91
|
-
if (
|
|
90
|
+
), r = d();
|
|
91
|
+
if (r.setCurrentBlock(i), this._stampHidePrice(t, n.priceHideIfSameAsDiscounted), o) {
|
|
92
92
|
p(this.api);
|
|
93
93
|
const l = this._getBlockElement(t);
|
|
94
|
-
l && (f(this.api, l, !0),
|
|
94
|
+
l && (f(this.api, l, !0), C({
|
|
95
95
|
currentNode: t,
|
|
96
96
|
documentModifier: this.api.getDocumentModifier()
|
|
97
97
|
}));
|
|
98
98
|
}
|
|
99
|
-
|
|
99
|
+
r.patchCurrentBlockConfig({ language: n.language }, { triggerRefetch: !1 }), this._warnIfMultipleBlocks();
|
|
100
100
|
}
|
|
101
101
|
/**
|
|
102
102
|
* Called when the document changes or template is loaded
|
|
@@ -109,20 +109,20 @@ class H extends D {
|
|
|
109
109
|
if (!(!t || !("getNodeConfig" in t))) {
|
|
110
110
|
if (!this._getRecommendationId(t)) {
|
|
111
111
|
const e = this._generateNextId();
|
|
112
|
-
this._assignRecommendationId(t, e),
|
|
112
|
+
this._assignRecommendationId(t, e), s.hasConfig(t) && s.updateConfig(
|
|
113
113
|
this.api,
|
|
114
114
|
t,
|
|
115
115
|
{ recommendationId: e },
|
|
116
116
|
"Assign recommendation ID to legacy block"
|
|
117
117
|
);
|
|
118
118
|
}
|
|
119
|
-
this._healLingeringDuplicate(t),
|
|
119
|
+
this._healLingeringDuplicate(t), s.needsMigration(t) && this._migrateFromLegacy(t), this._healHidePriceAttr(t);
|
|
120
120
|
try {
|
|
121
|
-
|
|
122
|
-
const e =
|
|
121
|
+
k || (p(this.api), k = !0);
|
|
122
|
+
const e = s.getConfig(t), i = this._getBlockElement(t);
|
|
123
123
|
if (i) {
|
|
124
124
|
const n = !e.mobileLayoutEnabled;
|
|
125
|
-
|
|
125
|
+
E(i) !== n && f(this.api, i, n);
|
|
126
126
|
}
|
|
127
127
|
} catch {
|
|
128
128
|
}
|
|
@@ -136,7 +136,7 @@ class H extends D {
|
|
|
136
136
|
*/
|
|
137
137
|
onDelete(t) {
|
|
138
138
|
const e = this._getRecommendationId(t);
|
|
139
|
-
e &&
|
|
139
|
+
e && d().removeBlockState(e);
|
|
140
140
|
}
|
|
141
141
|
/**
|
|
142
142
|
* Warns (dark advisory toaster) when the design holds more than one live
|
|
@@ -166,8 +166,8 @@ class H extends D {
|
|
|
166
166
|
const e = this.api.getDocumentRoot();
|
|
167
167
|
e && "querySelectorAll" in e && e.querySelectorAll(`.${m}`).forEach((n) => {
|
|
168
168
|
if ("getAttribute" in n) {
|
|
169
|
-
const o = n.getAttribute(u),
|
|
170
|
-
|
|
169
|
+
const o = n.getAttribute(u), r = o ? parseInt(o) : 0;
|
|
170
|
+
r > t && (t = r);
|
|
171
171
|
}
|
|
172
172
|
});
|
|
173
173
|
} catch {
|
|
@@ -201,13 +201,13 @@ class H extends D {
|
|
|
201
201
|
const o = this._getBlockElement(t);
|
|
202
202
|
if (!o)
|
|
203
203
|
return;
|
|
204
|
-
let
|
|
204
|
+
let r = -1;
|
|
205
205
|
for (let l = 0; l < n.length; l++)
|
|
206
206
|
if (n[l] === o) {
|
|
207
|
-
|
|
207
|
+
r = l;
|
|
208
208
|
break;
|
|
209
209
|
}
|
|
210
|
-
if (
|
|
210
|
+
if (r <= 0)
|
|
211
211
|
return;
|
|
212
212
|
this._reassignDuplicateId(t, e);
|
|
213
213
|
} catch {
|
|
@@ -227,7 +227,7 @@ class H extends D {
|
|
|
227
227
|
}
|
|
228
228
|
/** Assigns a fresh id to a duplicated block and syncs DOM, node config and store. */
|
|
229
229
|
_handleDuplicate(t, e) {
|
|
230
|
-
const i = this._reassignDuplicateId(t, e), n =
|
|
230
|
+
const i = this._reassignDuplicateId(t, e), n = d();
|
|
231
231
|
n.cloneBlockState(e, i), n.setCurrentBlock(i), this._warnIfMultipleBlocks();
|
|
232
232
|
}
|
|
233
233
|
/**
|
|
@@ -243,7 +243,7 @@ class H extends D {
|
|
|
243
243
|
*/
|
|
244
244
|
_reassignDuplicateId(t, e) {
|
|
245
245
|
const i = this._generateNextId(), n = this._getBlockElement(t);
|
|
246
|
-
return this._assignRecommendationId(t, i), n && this._reassignInstanceClass(n, e, i),
|
|
246
|
+
return this._assignRecommendationId(t, i), n && this._reassignInstanceClass(n, e, i), s.hasConfig(t) && s.updateConfig(
|
|
247
247
|
this.api,
|
|
248
248
|
t,
|
|
249
249
|
{ recommendationId: i },
|
|
@@ -260,8 +260,8 @@ class H extends D {
|
|
|
260
260
|
_reassignInstanceClass(t, e, i) {
|
|
261
261
|
if (!("getAttribute" in t))
|
|
262
262
|
return;
|
|
263
|
-
const n = `ins-recommendation-v3-block-${e}`, o = `ins-recommendation-v3-block-${i}`,
|
|
264
|
-
|
|
263
|
+
const n = `ins-recommendation-v3-block-${e}`, o = `ins-recommendation-v3-block-${i}`, r = this.api.getDocumentModifier();
|
|
264
|
+
r.modifyHtml(t).removeClass(n).setClass(o), r.apply(new g(
|
|
265
265
|
`Reassign recommendation instance class ${n} -> ${o}`
|
|
266
266
|
));
|
|
267
267
|
}
|
|
@@ -276,7 +276,26 @@ class H extends D {
|
|
|
276
276
|
if (!i)
|
|
277
277
|
return;
|
|
278
278
|
const n = this.api.getDocumentModifier();
|
|
279
|
-
n.modifyHtml(i).setAttribute(u, e.toString()), n.apply(new
|
|
279
|
+
n.modifyHtml(i).setAttribute(u, e.toString()), n.apply(new g(`Assign recommendation ID ${e}`));
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Stamps the `hide-price` attribute (read by email-service at send time) on
|
|
283
|
+
* the block element from the config flag.
|
|
284
|
+
*/
|
|
285
|
+
_stampHidePrice(t, e) {
|
|
286
|
+
const i = this._getBlockElement(t);
|
|
287
|
+
i && this.api.getDocumentModifier().modifyHtml(i).setAttribute(I, String(e)).apply(new g("Stamp hide-price"));
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Stamps `hide-price` from config only when the block lacks the attribute —
|
|
291
|
+
* heals templates saved before this feature without dirtying current ones.
|
|
292
|
+
*/
|
|
293
|
+
_healHidePriceAttr(t) {
|
|
294
|
+
const e = this._getBlockElement(t);
|
|
295
|
+
if (!e || !("getAttribute" in e) || e.getAttribute(I) !== null)
|
|
296
|
+
return;
|
|
297
|
+
const { priceHideIfSameAsDiscounted: i } = s.getConfig(t);
|
|
298
|
+
this._stampHidePrice(t, i);
|
|
280
299
|
}
|
|
281
300
|
/**
|
|
282
301
|
* Gets the recommendation-id from a block node
|
|
@@ -306,10 +325,10 @@ class H extends D {
|
|
|
306
325
|
* Migrate configuration from legacy format
|
|
307
326
|
*/
|
|
308
327
|
_migrateFromLegacy(t) {
|
|
309
|
-
|
|
328
|
+
s.migrateFromDataAttributes(this.api, t);
|
|
310
329
|
}
|
|
311
330
|
}
|
|
312
331
|
export {
|
|
313
|
-
|
|
314
|
-
|
|
332
|
+
_ as BLOCK_ID,
|
|
333
|
+
P as RecommendationBlock
|
|
315
334
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const e = `/*
|
|
2
|
+
* Editor-canvas-only styles (ExtensionBuilder.withPreviewStyles).
|
|
3
|
+
* Never reaches the exported email HTML — send-time behavior stays in email-service.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* Hide-if-same: mirror the email-service rule in the canvas. The block-level
|
|
7
|
+
\`hide-price\` attr is the toggle; \`data-same-price\` is stamped per old-price
|
|
8
|
+
cell by the renderers / in-place price updates. Hiding the <p> (not the td)
|
|
9
|
+
keeps inline price columns from collapsing, matching the preview look. */
|
|
10
|
+
.recommendation-block-v2[hide-price="true"] .product-old-price[data-same-price="true"] p {
|
|
11
|
+
display: none;
|
|
12
|
+
}
|
|
13
|
+
`;
|
|
14
|
+
export {
|
|
15
|
+
e as default
|
|
16
|
+
};
|