@useinsider/guido 3.7.0-beta.340a6d3 → 3.7.0-beta.4311638
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/extensions/Blocks/Items/block.js +48 -29
- package/dist/extensions/Blocks/Items/utils/nodeConfigUtils.js +62 -45
- package/dist/extensions/Blocks/Recommendation/block.js +1 -4
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +135 -152
- package/dist/src/extensions/Blocks/Items/block.d.ts +8 -0
- package/dist/src/extensions/Blocks/Items/utils/nodeConfigUtils.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { BlockId as
|
|
1
|
+
import { BlockId as u } 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 C } from "../../../utils/migrationBannerHtml.js";
|
|
4
|
+
import { Block as I, BlockCompositionType as y, ModificationDescription as s } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
|
+
import { SETTINGS_ENUMS as c, DefaultConfigValues as a } from "./enums/settingsEnums.js";
|
|
6
|
+
import { getDefaultTemplate as h } from "./template.js";
|
|
7
|
+
import { getItemsBlockContainer as l, getItemsBlockConfig as m, getDefaultItemsBlockConfig as b } from "./utils/nodeConfigUtils.js";
|
|
8
|
+
const d = u.Items;
|
|
9
|
+
class E extends I {
|
|
10
10
|
getId() {
|
|
11
|
-
return
|
|
11
|
+
return d;
|
|
12
12
|
}
|
|
13
13
|
getIcon() {
|
|
14
14
|
return "items-icon";
|
|
15
15
|
}
|
|
16
16
|
getBlockCompositionType() {
|
|
17
|
-
return
|
|
17
|
+
return y.CONTAINER;
|
|
18
18
|
}
|
|
19
19
|
getName() {
|
|
20
20
|
return this.api.translate("Items");
|
|
@@ -23,41 +23,60 @@ class E extends u {
|
|
|
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 C(
|
|
27
|
+
d,
|
|
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 h({
|
|
34
|
+
orientation: c.ORIENTATION.VERTICAL,
|
|
35
|
+
itemsType: c.ITEMS_TYPE.CART_ITEMS,
|
|
36
36
|
itemId: "{{Abandoned Cart Item (1) Url}}",
|
|
37
|
-
currencySymbol:
|
|
38
|
-
currencyLocation:
|
|
39
|
-
formattedPrice:
|
|
37
|
+
currencySymbol: a.productPriceCurrencySymbolControlValue,
|
|
38
|
+
currencyLocation: a.productPriceCurrencyLocationControlValue,
|
|
39
|
+
formattedPrice: a.productPriceFormattedControlValue === "1"
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
42
|
allowInnerBlocksDND() {
|
|
43
43
|
return !1;
|
|
44
44
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
canBeSavedAsModule() {
|
|
46
|
+
return !0;
|
|
47
|
+
}
|
|
48
|
+
onCreated(i) {
|
|
49
|
+
const n = this.api.getDocumentModifier(), r = this.api.getDocumentRootCssNode();
|
|
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)
|
|
50
53
|
return;
|
|
51
|
-
const
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
+
const e = t.getNodeConfig(), g = e && Object.keys(e).length > 0, o = m(i);
|
|
55
|
+
if (o != null && o.initialized)
|
|
56
|
+
g ? o.blockInstanceId || this.api.getDocumentModifier().modifyHtml(t).setNodeConfig({ ...o, blockInstanceId: String(Date.now()) }).apply(new s("Assign block instance ID to block")) : this.api.getDocumentModifier().modifyHtml(t).setNodeConfig(o).apply(new s("Migrate legacy config to nodeConfig"));
|
|
54
57
|
else {
|
|
55
|
-
const
|
|
56
|
-
this.api.getDocumentModifier().modifyHtml(
|
|
58
|
+
const f = b();
|
|
59
|
+
this.api.getDocumentModifier().modifyHtml(t).setNodeConfig(f).apply(new s("Initialize Items block with default configuration")), p().startOnboarding("itemsOnboarding");
|
|
57
60
|
}
|
|
58
61
|
}
|
|
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
|
+
}
|
|
59
78
|
}
|
|
60
79
|
export {
|
|
61
|
-
|
|
80
|
+
d as BLOCK_ID,
|
|
62
81
|
E as ItemsBlock
|
|
63
82
|
};
|
|
@@ -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 i, 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 y() {
|
|
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: i.cartItemsSelectControlValue,
|
|
14
14
|
orientation: n.ORIENTATION.VERTICAL,
|
|
15
|
-
nameTrimming:
|
|
16
|
-
priceHideDiscount:
|
|
17
|
-
priceFormatted:
|
|
15
|
+
nameTrimming: i.productNameTrimmingControlValue === "1",
|
|
16
|
+
priceHideDiscount: i.productPriceHideDiscountControlValue === "1",
|
|
17
|
+
priceFormatted: i.productPriceFormattedControlValue === "1",
|
|
18
18
|
priceSinglePrice: !1,
|
|
19
|
-
priceCurrencySymbol:
|
|
20
|
-
priceCurrencyLocation:
|
|
19
|
+
priceCurrencySymbol: i.productPriceCurrencySymbolControlValue,
|
|
20
|
+
priceCurrencyLocation: i.productPriceCurrencyLocationControlValue,
|
|
21
21
|
priceOrientation: "horizontal",
|
|
22
|
-
quantityControlEnabled:
|
|
23
|
-
buttonLink:
|
|
24
|
-
imageLink:
|
|
22
|
+
quantityControlEnabled: i.productQuantityControlEnabled === "1",
|
|
23
|
+
buttonLink: i.productButtonLinkControlValue,
|
|
24
|
+
imageLink: i.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: i.productImageVisible === "1",
|
|
29
|
+
nameVisible: i.productNameVisible === "1",
|
|
30
|
+
quantityVisible: i.productQuantityVisible === "1",
|
|
31
|
+
priceVisible: i.productPriceVisible === "1",
|
|
32
|
+
originalPriceVisible: i.productOriginalPriceVisible === "1",
|
|
33
|
+
buttonVisible: i.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 f(r, t) {
|
|
54
54
|
if (!r)
|
|
55
|
-
return
|
|
55
|
+
return i.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, o = g[t];
|
|
60
|
+
if (o && o[e])
|
|
61
|
+
return o[e].value;
|
|
62
62
|
}
|
|
63
|
-
return
|
|
63
|
+
return i.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 = (u, s) => u == null ? s : u === "1" || u === "true", o = (u, s) => u || s, c = t.getAttribute("data-type"), a = m(c), d = t.getAttribute("data-cart_items_select_control_value"), l = f(d, a);
|
|
70
70
|
return {
|
|
71
71
|
initialized: e(t.getAttribute("data-initialized"), !1),
|
|
72
|
-
blockInstanceId:
|
|
72
|
+
blockInstanceId: o(
|
|
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: o(
|
|
97
97
|
t.getAttribute("data-product_price_control_currency_symbol"),
|
|
98
|
-
|
|
98
|
+
i.productPriceCurrencySymbolControlValue
|
|
99
99
|
),
|
|
100
|
-
priceCurrencyLocation:
|
|
100
|
+
priceCurrencyLocation: o(
|
|
101
101
|
t.getAttribute("data-product_price_currency_location"),
|
|
102
|
-
|
|
102
|
+
i.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: o(
|
|
110
110
|
t.getAttribute("data-product_button_link"),
|
|
111
|
-
|
|
111
|
+
i.productButtonLinkControlValue
|
|
112
112
|
),
|
|
113
|
-
imageLink:
|
|
113
|
+
imageLink: o(
|
|
114
114
|
t.getAttribute("data-product_image_link"),
|
|
115
|
-
|
|
115
|
+
i.productImageLinkControlValue
|
|
116
116
|
),
|
|
117
|
-
buttonLabel:
|
|
117
|
+
buttonLabel: o(
|
|
118
118
|
t.getAttribute("data-product_button_control_label"),
|
|
119
119
|
"Buy"
|
|
120
120
|
),
|
|
@@ -149,28 +149,45 @@ function C(r) {
|
|
|
149
149
|
)
|
|
150
150
|
};
|
|
151
151
|
}
|
|
152
|
-
function
|
|
152
|
+
function I(r) {
|
|
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) {
|
|
153
167
|
const t = p(r);
|
|
154
168
|
if (!t)
|
|
155
169
|
return null;
|
|
156
170
|
const e = t.getNodeConfig();
|
|
157
171
|
if (e && e.initialized)
|
|
158
172
|
return e;
|
|
159
|
-
const
|
|
160
|
-
|
|
173
|
+
const o = I(t);
|
|
174
|
+
if (o)
|
|
175
|
+
return o;
|
|
176
|
+
const c = C(t);
|
|
177
|
+
return c || null;
|
|
161
178
|
}
|
|
162
|
-
function
|
|
163
|
-
const
|
|
164
|
-
if (!
|
|
179
|
+
function V(r, t, e, o) {
|
|
180
|
+
const c = p(r);
|
|
181
|
+
if (!c)
|
|
165
182
|
return;
|
|
166
|
-
const d = { ...
|
|
167
|
-
l.modifyHtml(
|
|
183
|
+
const d = { ...c.getNodeConfig() || {}, ...e }, l = o ?? t.getDocumentModifier();
|
|
184
|
+
l.modifyHtml(c).setNodeConfig(d), o || l.apply(new b("Update Items block configuration"));
|
|
168
185
|
}
|
|
169
186
|
export {
|
|
170
187
|
E as escapeReplacement,
|
|
171
188
|
_ as generateBlockInstanceId,
|
|
172
|
-
|
|
173
|
-
|
|
189
|
+
y as getDefaultItemsBlockConfig,
|
|
190
|
+
A as getItemsBlockConfig,
|
|
174
191
|
p as getItemsBlockContainer,
|
|
175
|
-
|
|
192
|
+
V as setItemsBlockConfig
|
|
176
193
|
};
|
|
@@ -47,11 +47,8 @@ class q extends R {
|
|
|
47
47
|
allowInnerBlocksDND() {
|
|
48
48
|
return !1;
|
|
49
49
|
}
|
|
50
|
-
// A saved module carries its config in the esd-config blob, restored on
|
|
51
|
-
// re-drop by migrateFromDataAttributes; per-element styles ride the
|
|
52
|
-
// preserved inner HTML. (onCreated early-returns for re-drops, never clobbers.)
|
|
53
50
|
canBeSavedAsModule() {
|
|
54
|
-
return !
|
|
51
|
+
return !1;
|
|
55
52
|
}
|
|
56
53
|
/**
|
|
57
54
|
* Returns the template HTML for a new recommendation block.
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var S = (p,
|
|
4
|
-
import { UIElementType as f, UEAttr as
|
|
5
|
-
import { CommonControl as
|
|
6
|
-
import { ATTR_PRODUCT_IMAGE as
|
|
7
|
-
import { DEFAULT_COMPOSITION as P, DEFAULT_VISIBILITY as
|
|
8
|
-
import { RecommendationConfigService as
|
|
1
|
+
var J = Object.defineProperty;
|
|
2
|
+
var Q = (p, _, t) => _ in p ? J(p, _, { enumerable: !0, configurable: !0, writable: !0, value: t }) : p[_] = t;
|
|
3
|
+
var S = (p, _, t) => Q(p, typeof _ != "symbol" ? _ + "" : _, t);
|
|
4
|
+
import { UIElementType as f, UEAttr as I, ModificationDescription as A } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
|
+
import { CommonControl as Z } from "../../../common-control.js";
|
|
6
|
+
import { ATTR_PRODUCT_IMAGE as D, ATTR_PRODUCT_NAME as tt, ATTR_PRODUCT_PRICE as et, ATTR_PRODUCT_OLD_PRICE as rt, ATTR_PRODUCT_OMNIBUS_PRICE as ot, ATTR_PRODUCT_OMNIBUS_DISCOUNT as st, ATTR_PRODUCT_BUTTON as U, ATTR_DATA_CUSTOM_ATTRIBUTES as q, ATTR_CUSTOM_PREFIX as m, BUILT_IN_DEFAULT_ATTRIBUTES as it } from "../../constants/selectors.js";
|
|
7
|
+
import { DEFAULT_COMPOSITION as P, DEFAULT_VISIBILITY as F } from "../../constants/defaultConfig.js";
|
|
8
|
+
import { RecommendationConfigService as nt } from "../../services/configService.js";
|
|
9
9
|
import { useRecommendationExtensionStore as lt } from "../../store/recommendation.js";
|
|
10
10
|
import { ATTRIBUTE_CELL_CLASS as at, gridElementRenderer as ct, DEFAULT_CELL_PADDING as ut, buildFillerCell as dt } from "../../templates/grid/elementRenderer.js";
|
|
11
11
|
import { listElementRenderer as mt } from "../../templates/list/elementRenderer.js";
|
|
12
|
-
import { toDisplayName as ht, isDefaultAttribute as pt, toDisplayableAttributeValue as
|
|
12
|
+
import { toDisplayName as ht, isDefaultAttribute as pt, toDisplayableAttributeValue as _t, buildElementRenderer as w } from "../../templates/utils.js";
|
|
13
13
|
import { getTableDisplayValue as ft } from "../../utils/tagName.js";
|
|
14
|
-
import { getCurrentLayout as
|
|
15
|
-
const bt = "ui-elements-recommendation-card-composition",
|
|
14
|
+
import { getCurrentLayout as gt } from "../main/utils.js";
|
|
15
|
+
const bt = "ui-elements-recommendation-card-composition", C = ".recommendation-attribute-row", L = ".product-card-wrapper > tbody", M = ".product-info-cell > table > tbody", V = "data-card-composition", y = "data-attribute-type", v = "data-visibility", x = {
|
|
16
16
|
ADD_ATTRIBUTE: "addAttribute"
|
|
17
|
-
},
|
|
18
|
-
{ key:
|
|
19
|
-
{ key:
|
|
20
|
-
{ key:
|
|
21
|
-
{ key:
|
|
22
|
-
{ key:
|
|
23
|
-
{ key:
|
|
17
|
+
}, g = 5, E = "reorderIcon_", h = [
|
|
18
|
+
{ key: D, label: "Product Image" },
|
|
19
|
+
{ key: tt, label: "Product Name" },
|
|
20
|
+
{ key: et, label: "Product Price" },
|
|
21
|
+
{ key: rt, label: "Product Original Price" },
|
|
22
|
+
{ key: ot, label: "Omnibus Price" },
|
|
23
|
+
{ key: st, label: "Omnibus Discount" },
|
|
24
24
|
{ key: U, label: "Product Button" }
|
|
25
|
-
], yt = new Set(h.map((p) => p.key)), T = "customAttr_",
|
|
26
|
-
class
|
|
25
|
+
], yt = new Set(h.map((p) => p.key)), T = "customAttr_", R = "deleteAttr_";
|
|
26
|
+
class Ut extends Z {
|
|
27
27
|
constructor() {
|
|
28
28
|
super(...arguments);
|
|
29
29
|
S(this, "store", lt());
|
|
@@ -47,7 +47,7 @@ class Ht extends tt {
|
|
|
47
47
|
${this._GuToggle(`visibility_${l.key}`)}
|
|
48
48
|
</div>
|
|
49
49
|
`).join(""), r = Array.from(
|
|
50
|
-
{ length:
|
|
50
|
+
{ length: g },
|
|
51
51
|
(l, u) => `
|
|
52
52
|
<div data-custom-select-key="${T}${u}" style="display: none;">
|
|
53
53
|
${this._GuSelect({
|
|
@@ -57,13 +57,13 @@ class Ht extends tt {
|
|
|
57
57
|
})}
|
|
58
58
|
</div>
|
|
59
59
|
`
|
|
60
|
-
).join(""), e = h.length +
|
|
60
|
+
).join(""), e = h.length + g, o = Array.from(
|
|
61
61
|
{ length: e },
|
|
62
62
|
(l, u) => `
|
|
63
|
-
<div data-reorder-icon-key="${
|
|
63
|
+
<div data-reorder-icon-key="${E}${u}" style="display: none;">
|
|
64
64
|
<${f.BUTTON}
|
|
65
65
|
class="drag-handle-btn flat-inline flat-white"
|
|
66
|
-
${
|
|
66
|
+
${I.BUTTON.name}="${E}${u}"
|
|
67
67
|
>
|
|
68
68
|
<${f.ICON}
|
|
69
69
|
src="reorder"
|
|
@@ -73,12 +73,12 @@ class Ht extends tt {
|
|
|
73
73
|
</div>
|
|
74
74
|
`
|
|
75
75
|
).join(""), s = Array.from(
|
|
76
|
-
{ length:
|
|
76
|
+
{ length: g },
|
|
77
77
|
(l, u) => `
|
|
78
|
-
<div data-custom-delete-key="${
|
|
78
|
+
<div data-custom-delete-key="${R}${u}" style="display: none;">
|
|
79
79
|
<${f.BUTTON}
|
|
80
80
|
class="custom-attr-delete flat-inline flat-white"
|
|
81
|
-
${
|
|
81
|
+
${I.BUTTON.name}="${R}${u}"
|
|
82
82
|
>
|
|
83
83
|
<${f.ICON}
|
|
84
84
|
src="delete"
|
|
@@ -89,15 +89,15 @@ class Ht extends tt {
|
|
|
89
89
|
`
|
|
90
90
|
).join(""), i = "https://academy.insiderone.com/docs/new-editor-email-recommendation-block", n = this.api.translate(
|
|
91
91
|
"Drag and drop the card elements to reorder them, adjust their visibility or add new attributes up to 5."
|
|
92
|
-
),
|
|
92
|
+
), a = this.api.translate("For more information, you can"), c = this.api.translate("visit Academy");
|
|
93
93
|
return `
|
|
94
94
|
<div class="recommendation-controls-container" data-card-composition-control>
|
|
95
95
|
<div class="container">
|
|
96
96
|
<p class="card-composition-description">
|
|
97
97
|
${n}
|
|
98
|
-
${
|
|
98
|
+
${a}
|
|
99
99
|
<!-- cspell:disable-next-line -->
|
|
100
|
-
<a href="${i}" target="_blank" rel="noopener noreferrer">${
|
|
100
|
+
<a href="${i}" target="_blank" rel="noopener noreferrer">${c}</a>.
|
|
101
101
|
</p>
|
|
102
102
|
</div>
|
|
103
103
|
|
|
@@ -120,7 +120,7 @@ class Ht extends tt {
|
|
|
120
120
|
<div class="orderable-list" data-composition-list></div>
|
|
121
121
|
|
|
122
122
|
${this._GuButton({
|
|
123
|
-
name:
|
|
123
|
+
name: x.ADD_ATTRIBUTE,
|
|
124
124
|
label: this.api.translate("Add Attribute"),
|
|
125
125
|
id: "guido__btn-add-attribute"
|
|
126
126
|
})}
|
|
@@ -149,7 +149,7 @@ class Ht extends tt {
|
|
|
149
149
|
this._applyVisibilityToBlock(t.key, r);
|
|
150
150
|
});
|
|
151
151
|
});
|
|
152
|
-
for (let t = 0; t <
|
|
152
|
+
for (let t = 0; t < g; t++) {
|
|
153
153
|
const r = `${T}${t}`, e = t;
|
|
154
154
|
this.api.onValueChanged(r, (o) => {
|
|
155
155
|
this._onCustomAttributeChanged(e, o);
|
|
@@ -162,42 +162,36 @@ class Ht extends tt {
|
|
|
162
162
|
_readCompositionFromNode() {
|
|
163
163
|
if (!this.currentNode || !("getAttribute" in this.currentNode))
|
|
164
164
|
return [...P];
|
|
165
|
-
const t = this.currentNode.getAttribute(
|
|
166
|
-
|
|
167
|
-
return t.split(",").filter(Boolean);
|
|
168
|
-
const { composition: r } = $.getConfig(this.currentNode);
|
|
169
|
-
return r != null && r.length ? [...r] : [...P];
|
|
165
|
+
const t = this.currentNode.getAttribute(V);
|
|
166
|
+
return t ? t.split(",").filter(Boolean) : [...P];
|
|
170
167
|
}
|
|
171
168
|
_readCustomAttributesFromNode() {
|
|
172
169
|
if (!this.currentNode || !("getAttribute" in this.currentNode))
|
|
173
170
|
return [];
|
|
174
|
-
const t = this.currentNode.getAttribute(
|
|
175
|
-
if (t)
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
171
|
+
const t = this.currentNode.getAttribute(q);
|
|
172
|
+
if (!t)
|
|
173
|
+
return [];
|
|
174
|
+
try {
|
|
175
|
+
return JSON.parse(t);
|
|
176
|
+
} catch {
|
|
177
|
+
return [];
|
|
178
|
+
}
|
|
182
179
|
}
|
|
183
180
|
_readVisibilityFromRows() {
|
|
184
181
|
if (!this.currentNode)
|
|
185
182
|
return this._getDefaultVisibilities();
|
|
186
|
-
const t = Array.from(this.currentNode.querySelectorAll(
|
|
187
|
-
|
|
188
|
-
return this._mergeWithDefaults(r);
|
|
189
|
-
const e = $.getConfig(this.currentNode).visibility;
|
|
190
|
-
return this._mergeWithDefaults({ ...e });
|
|
183
|
+
const t = Array.from(this.currentNode.querySelectorAll(C)), r = this._extractVisibilityFromRows(t);
|
|
184
|
+
return this._mergeWithDefaults(r);
|
|
191
185
|
}
|
|
192
186
|
_getDefaultVisibilities() {
|
|
193
|
-
return { ...
|
|
187
|
+
return { ...F };
|
|
194
188
|
}
|
|
195
189
|
_extractVisibilityFromRows(t) {
|
|
196
190
|
const r = {};
|
|
197
191
|
return t.forEach((e) => {
|
|
198
192
|
if (!("getAttribute" in e))
|
|
199
193
|
return;
|
|
200
|
-
const o = e.getAttribute(y), s = e.getAttribute(
|
|
194
|
+
const o = e.getAttribute(y), s = e.getAttribute(v);
|
|
201
195
|
o && s !== null && (r[o] = this._parseVisibilityValue(s));
|
|
202
196
|
}), r;
|
|
203
197
|
}
|
|
@@ -205,7 +199,7 @@ class Ht extends tt {
|
|
|
205
199
|
return t === "1" || t === "true";
|
|
206
200
|
}
|
|
207
201
|
_mergeWithDefaults(t) {
|
|
208
|
-
return Object.entries(
|
|
202
|
+
return Object.entries(F).forEach(([r, e]) => {
|
|
209
203
|
r in t || (t[r] = e);
|
|
210
204
|
}), t;
|
|
211
205
|
}
|
|
@@ -229,19 +223,19 @@ class Ht extends tt {
|
|
|
229
223
|
return !1;
|
|
230
224
|
const s = new Set(r);
|
|
231
225
|
let i = 0, n = 0;
|
|
232
|
-
const
|
|
233
|
-
if (yt.has(
|
|
234
|
-
const l = h.find((u) => u.key ===
|
|
226
|
+
const a = t.map((c) => {
|
|
227
|
+
if (yt.has(c)) {
|
|
228
|
+
const l = h.find((u) => u.key === c);
|
|
235
229
|
return this._createBuiltInItemHtml(l, n++);
|
|
236
230
|
}
|
|
237
|
-
if (
|
|
238
|
-
const l =
|
|
231
|
+
if (c.startsWith(m)) {
|
|
232
|
+
const l = c.substring(m.length);
|
|
239
233
|
if (s.has(l))
|
|
240
|
-
return this._createCustomItemHtml(
|
|
234
|
+
return this._createCustomItemHtml(c, i++, n++);
|
|
241
235
|
}
|
|
242
236
|
return "";
|
|
243
237
|
}).join("");
|
|
244
|
-
return this._rescueTogglesToStore(e), this._rescueSelectsToStore(e), this._rescueDeleteButtonsToStore(e), this._rescueReorderIconsToStore(e), o.innerHTML =
|
|
238
|
+
return this._rescueTogglesToStore(e), this._rescueSelectsToStore(e), this._rescueDeleteButtonsToStore(e), this._rescueReorderIconsToStore(e), o.innerHTML = a, this._moveTogglesIntoItems(e), this._moveSelectsIntoItems(e, r.length), this._moveDeleteButtonsIntoItems(e, r.length), this._moveReorderIconsIntoItems(e, n), !0;
|
|
245
239
|
}
|
|
246
240
|
/**
|
|
247
241
|
* Attempts to reorder existing orderable-item elements to match the composition order.
|
|
@@ -253,27 +247,27 @@ class Ht extends tt {
|
|
|
253
247
|
const e = Array.from(t.querySelectorAll(".orderable-item"));
|
|
254
248
|
if (e.length !== r.length)
|
|
255
249
|
return !1;
|
|
256
|
-
const o = e.map((
|
|
250
|
+
const o = e.map((c) => c.dataset.key).filter(Boolean);
|
|
257
251
|
if (o.length !== r.length)
|
|
258
252
|
return !1;
|
|
259
253
|
const s = [...o].sort().join(","), i = [...r].sort().join(",");
|
|
260
|
-
if (s !== i || r.some((
|
|
254
|
+
if (s !== i || r.some((c) => c.startsWith(m)))
|
|
261
255
|
return !1;
|
|
262
256
|
const n = /* @__PURE__ */ new Map();
|
|
263
|
-
e.forEach((
|
|
264
|
-
const { key: l } =
|
|
257
|
+
e.forEach((c) => {
|
|
258
|
+
const { key: l } = c.dataset;
|
|
265
259
|
if (l) {
|
|
266
260
|
const u = n.get(l) || [];
|
|
267
|
-
u.push(
|
|
261
|
+
u.push(c), n.set(l, u);
|
|
268
262
|
}
|
|
269
263
|
});
|
|
270
|
-
const
|
|
271
|
-
return r.forEach((
|
|
272
|
-
const l = n.get(
|
|
264
|
+
const a = /* @__PURE__ */ new Map();
|
|
265
|
+
return r.forEach((c) => {
|
|
266
|
+
const l = n.get(c);
|
|
273
267
|
if (!l)
|
|
274
268
|
return;
|
|
275
|
-
const u =
|
|
276
|
-
|
|
269
|
+
const u = a.get(c) || 0;
|
|
270
|
+
a.set(c, u + 1), l[u] && t.appendChild(l[u]);
|
|
277
271
|
}), !0;
|
|
278
272
|
}
|
|
279
273
|
_createBuiltInItemHtml(t, r) {
|
|
@@ -322,7 +316,7 @@ class Ht extends tt {
|
|
|
322
316
|
t.length !== 0 && setTimeout(() => {
|
|
323
317
|
t.forEach((r, e) => {
|
|
324
318
|
const o = `${T}${e}`, s = this._getSelectOptions(r, t);
|
|
325
|
-
this.api.setUIEAttribute(o,
|
|
319
|
+
this.api.setUIEAttribute(o, I.SELECTPICKER.items, s), this.api.updateValues({ [o]: r });
|
|
326
320
|
});
|
|
327
321
|
}, 0);
|
|
328
322
|
}
|
|
@@ -372,7 +366,7 @@ class Ht extends tt {
|
|
|
372
366
|
* Same rescue pattern as _rescueTogglesToStore — prevents innerHTML from destroying them.
|
|
373
367
|
*/
|
|
374
368
|
_rescueSelectsToStore(t) {
|
|
375
|
-
for (let r = 0; r <
|
|
369
|
+
for (let r = 0; r < g; r++) {
|
|
376
370
|
const e = `${T}${r}`, o = t.querySelector(`[data-custom-select-key="${e}"]`), s = t.querySelector(`[data-custom-select-slot="${r}"]`);
|
|
377
371
|
if (s) {
|
|
378
372
|
const i = s.querySelector("ue-select");
|
|
@@ -386,7 +380,7 @@ class Ht extends tt {
|
|
|
386
380
|
*/
|
|
387
381
|
_moveDeleteButtonsIntoItems(t, r) {
|
|
388
382
|
for (let e = 0; e < r; e++) {
|
|
389
|
-
const o = `${
|
|
383
|
+
const o = `${R}${e}`, s = t.querySelector(`[data-custom-delete-key="${o}"]`), i = t.querySelector(`[data-custom-delete-slot="${e}"]`);
|
|
390
384
|
if (s && i) {
|
|
391
385
|
const n = s.querySelector("ue-button");
|
|
392
386
|
n && i.appendChild(n);
|
|
@@ -398,8 +392,8 @@ class Ht extends tt {
|
|
|
398
392
|
* Same rescue pattern as _rescueSelectsToStore — prevents innerHTML from destroying them.
|
|
399
393
|
*/
|
|
400
394
|
_rescueDeleteButtonsToStore(t) {
|
|
401
|
-
for (let r = 0; r <
|
|
402
|
-
const e = `${
|
|
395
|
+
for (let r = 0; r < g; r++) {
|
|
396
|
+
const e = `${R}${r}`, o = t.querySelector(`[data-custom-delete-key="${e}"]`), s = t.querySelector(`[data-custom-delete-slot="${r}"]`);
|
|
403
397
|
if (s) {
|
|
404
398
|
const i = s.querySelector("ue-button");
|
|
405
399
|
i && o && o.appendChild(i);
|
|
@@ -412,7 +406,7 @@ class Ht extends tt {
|
|
|
412
406
|
*/
|
|
413
407
|
_moveReorderIconsIntoItems(t, r) {
|
|
414
408
|
for (let e = 0; e < r; e++) {
|
|
415
|
-
const o = `${
|
|
409
|
+
const o = `${E}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
|
|
416
410
|
if (s && i) {
|
|
417
411
|
const n = s.querySelector("ue-button");
|
|
418
412
|
n && i.appendChild(n);
|
|
@@ -424,9 +418,9 @@ class Ht extends tt {
|
|
|
424
418
|
* Same rescue pattern as _rescueDeleteButtonsToStore — prevents innerHTML from destroying them.
|
|
425
419
|
*/
|
|
426
420
|
_rescueReorderIconsToStore(t) {
|
|
427
|
-
const r = h.length +
|
|
421
|
+
const r = h.length + g;
|
|
428
422
|
for (let e = 0; e < r; e++) {
|
|
429
|
-
const o = `${
|
|
423
|
+
const o = `${E}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
|
|
430
424
|
if (i) {
|
|
431
425
|
const n = i.querySelector("ue-button");
|
|
432
426
|
n && s && s.appendChild(n);
|
|
@@ -450,24 +444,24 @@ class Ht extends tt {
|
|
|
450
444
|
_setupDragAndDrop(t, r) {
|
|
451
445
|
let e = null, o = null;
|
|
452
446
|
t.addEventListener("dragstart", (s) => {
|
|
453
|
-
var
|
|
447
|
+
var a;
|
|
454
448
|
const n = s.target.closest(".orderable-item");
|
|
455
|
-
n && (e = n, n.classList.add("dragging"), (
|
|
449
|
+
n && (e = n, n.classList.add("dragging"), (a = s.dataTransfer) == null || a.setData("text/plain", n.dataset.key || ""));
|
|
456
450
|
}, { signal: r }), t.addEventListener("dragend", () => {
|
|
457
451
|
e && e.classList.remove("dragging"), e = null, o == null || o.classList.remove("drag-over"), o = null;
|
|
458
452
|
}, { signal: r }), t.addEventListener("dragover", (s) => {
|
|
459
453
|
s.preventDefault();
|
|
460
|
-
const n = s.target.closest(".orderable-item"),
|
|
461
|
-
|
|
454
|
+
const n = s.target.closest(".orderable-item"), a = n && n !== e ? n : null;
|
|
455
|
+
a !== o && (o == null || o.classList.remove("drag-over"), o = a, o == null || o.classList.add("drag-over"));
|
|
462
456
|
}, { signal: r }), t.addEventListener("drop", (s) => {
|
|
463
457
|
s.preventDefault();
|
|
464
458
|
const n = s.target.closest(".orderable-item");
|
|
465
459
|
if (!n || !e || n === e)
|
|
466
460
|
return;
|
|
467
|
-
const
|
|
468
|
-
s.clientY <
|
|
469
|
-
const u = t.querySelectorAll(".orderable-item"),
|
|
470
|
-
this._onReorder(
|
|
461
|
+
const a = n.getBoundingClientRect(), c = a.top + a.height / 2;
|
|
462
|
+
s.clientY < c ? t.insertBefore(e, n) : t.insertBefore(e, n.nextSibling), o == null || o.classList.remove("drag-over"), o = null, e.classList.remove("dragging");
|
|
463
|
+
const u = t.querySelectorAll(".orderable-item"), d = Array.from(u).map((b) => b.dataset.key).filter(Boolean);
|
|
464
|
+
this._onReorder(d), e = null;
|
|
471
465
|
}, { signal: r });
|
|
472
466
|
}
|
|
473
467
|
_setupDeleteHandler(t, r) {
|
|
@@ -483,7 +477,7 @@ class Ht extends tt {
|
|
|
483
477
|
// Actions (Add, Delete, Reorder)
|
|
484
478
|
// ========================================================================
|
|
485
479
|
_onAddAttribute(t, r) {
|
|
486
|
-
const e = `${
|
|
480
|
+
const e = `${m}${t}`, o = this._readCompositionFromNode();
|
|
487
481
|
o.push(e);
|
|
488
482
|
const s = [...this._readCustomAttributesFromNode(), t];
|
|
489
483
|
this._updateBothAttributes(o, s), this._injectCustomAttributeHtml(t, r, e, o), this._renderOrderableItems(o, s), this._initializeCustomSelects(s), this._updateAddButtonState();
|
|
@@ -496,7 +490,7 @@ class Ht extends tt {
|
|
|
496
490
|
const r = this._readCustomAttributesFromNode();
|
|
497
491
|
if (r[t] === void 0)
|
|
498
492
|
return;
|
|
499
|
-
const o = this._readCompositionFromNode(), s = this._findNthCustomKeyIndex(o, t), i = o.filter((
|
|
493
|
+
const o = this._readCompositionFromNode(), s = this._findNthCustomKeyIndex(o, t), i = o.filter((a, c) => c !== s), n = r.filter((a, c) => c !== t);
|
|
500
494
|
this._updateBothAttributes(i, n), this._removeCustomAttributeHtml(i), this._renderOrderableItems(i, n), this._initializeCustomSelects(n), this._updateAddButtonState();
|
|
501
495
|
}
|
|
502
496
|
/**
|
|
@@ -507,13 +501,13 @@ class Ht extends tt {
|
|
|
507
501
|
const e = this._readCustomAttributesFromNode(), o = e[t];
|
|
508
502
|
if (o === void 0 || o === r)
|
|
509
503
|
return;
|
|
510
|
-
const s = `${
|
|
504
|
+
const s = `${m}${r}`, i = this._readCompositionFromNode(), n = this._findNthCustomKeyIndex(i, t);
|
|
511
505
|
n !== -1 && (i[n] = s), e[t] = r;
|
|
512
|
-
const
|
|
513
|
-
this._updateBothAttributes(i, e), this._injectCustomAttributeHtml(r,
|
|
506
|
+
const a = this._getDisplayNameForAttribute(r);
|
|
507
|
+
this._updateBothAttributes(i, e), this._injectCustomAttributeHtml(r, a, s, i), this._renderOrderableItems(i, e), this._initializeCustomSelects(e);
|
|
514
508
|
}
|
|
515
509
|
_onReorder(t) {
|
|
516
|
-
const r = t.filter((e) => e.startsWith(
|
|
510
|
+
const r = t.filter((e) => e.startsWith(m)).map((e) => e.substring(m.length));
|
|
517
511
|
this.reorderInProgress = !0;
|
|
518
512
|
try {
|
|
519
513
|
this._updateBothAttributes(t, r), this._getCurrentLayout() === "grid" && this._reorderProductAttributes(t);
|
|
@@ -534,58 +528,58 @@ class Ht extends tt {
|
|
|
534
528
|
const s = this.currentNode.querySelectorAll(L);
|
|
535
529
|
if (!(s != null && s.length))
|
|
536
530
|
return;
|
|
537
|
-
const i =
|
|
531
|
+
const i = nt.getConfig(this.currentNode), a = `0 ${Math.floor(i.columnSpacing / 2)}px`, c = this.api.getDocumentModifier(), l = this.store.recommendationProducts.length;
|
|
538
532
|
let u = 0;
|
|
539
|
-
s.forEach((
|
|
540
|
-
var
|
|
541
|
-
const b =
|
|
542
|
-
if (
|
|
543
|
-
const
|
|
533
|
+
s.forEach((d) => {
|
|
534
|
+
var H;
|
|
535
|
+
const b = d.querySelector(C), $ = ((H = b == null ? void 0 : b.querySelectorAll(`.${at}`)) == null ? void 0 : H.length) || 1, B = (100 / $).toFixed(2), { bgStyle: j, bgAttr: W } = this._extractSegmentBgFromCard(d), O = l > 0 ? Math.min($, l - u) : $, K = o.map((k) => {
|
|
536
|
+
if (k === e) {
|
|
537
|
+
const z = Array.from(
|
|
544
538
|
{ length: O },
|
|
545
|
-
(
|
|
546
|
-
const
|
|
539
|
+
(At, Y) => {
|
|
540
|
+
const X = this._resolveAttributeContent(
|
|
547
541
|
t,
|
|
548
542
|
r,
|
|
549
|
-
u +
|
|
543
|
+
u + Y
|
|
550
544
|
);
|
|
551
545
|
return this._getGridCellHtml(
|
|
552
546
|
t,
|
|
553
|
-
|
|
547
|
+
X,
|
|
554
548
|
B,
|
|
549
|
+
j,
|
|
555
550
|
W,
|
|
556
|
-
|
|
557
|
-
c
|
|
551
|
+
a
|
|
558
552
|
);
|
|
559
553
|
}
|
|
560
|
-
).join(""),
|
|
561
|
-
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${
|
|
554
|
+
).join(""), G = dt(B, a).repeat($ - O);
|
|
555
|
+
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${v}="1">${z}${G}</tr>`;
|
|
562
556
|
}
|
|
563
|
-
const
|
|
564
|
-
`${
|
|
557
|
+
const N = d.querySelector(
|
|
558
|
+
`${C}[${y}="${k}"]`
|
|
565
559
|
);
|
|
566
|
-
return
|
|
560
|
+
return N && "getOuterHTML" in N ? N.getOuterHTML() : "";
|
|
567
561
|
}).join("");
|
|
568
|
-
u += O, l > 0 && u >= l && (u = 0),
|
|
569
|
-
}),
|
|
562
|
+
u += O, l > 0 && u >= l && (u = 0), c.modifyHtml(d).setInnerHtml(K);
|
|
563
|
+
}), c.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
|
|
570
564
|
}
|
|
571
565
|
_injectListAttributeRow(t, r, e, o) {
|
|
572
|
-
const s = this.currentNode.querySelectorAll(
|
|
566
|
+
const s = this.currentNode.querySelectorAll(M);
|
|
573
567
|
if (!(s != null && s.length))
|
|
574
568
|
return;
|
|
575
|
-
const i = o.filter((
|
|
576
|
-
s.forEach((
|
|
569
|
+
const i = o.filter((a) => a !== D && a !== U), n = this.api.getDocumentModifier();
|
|
570
|
+
s.forEach((a, c) => {
|
|
577
571
|
const l = i.map((u) => {
|
|
578
572
|
if (u === e) {
|
|
579
|
-
const b = this._resolveAttributeContent(t, r,
|
|
573
|
+
const b = this._resolveAttributeContent(t, r, c);
|
|
580
574
|
return this._getListRowHtml(t, b, e);
|
|
581
575
|
}
|
|
582
|
-
const
|
|
583
|
-
`${
|
|
576
|
+
const d = a.querySelector(
|
|
577
|
+
`${C}[${y}="${u}"]`
|
|
584
578
|
);
|
|
585
|
-
return
|
|
579
|
+
return d && "getOuterHTML" in d ? d.getOuterHTML() : "";
|
|
586
580
|
}).join("");
|
|
587
|
-
n.modifyHtml(
|
|
588
|
-
}), n.apply(new
|
|
581
|
+
n.modifyHtml(a).setInnerHtml(l);
|
|
582
|
+
}), n.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
|
|
589
583
|
}
|
|
590
584
|
/**
|
|
591
585
|
* Removes a custom attribute by rebuilding product card content without it.
|
|
@@ -602,13 +596,13 @@ class Ht extends tt {
|
|
|
602
596
|
e.modifyHtml(s).setInnerHtml(i);
|
|
603
597
|
});
|
|
604
598
|
} else {
|
|
605
|
-
const o = t.filter((i) => i !==
|
|
599
|
+
const o = t.filter((i) => i !== D && i !== U), s = this.currentNode.querySelectorAll(M);
|
|
606
600
|
s == null || s.forEach((i) => {
|
|
607
601
|
const n = this._buildCompositionHtml(i, o);
|
|
608
602
|
e.modifyHtml(i).setInnerHtml(n);
|
|
609
603
|
});
|
|
610
604
|
}
|
|
611
|
-
e.apply(new
|
|
605
|
+
e.apply(new A(this.api.translate("Remove custom attribute")));
|
|
612
606
|
}
|
|
613
607
|
// ========================================================================
|
|
614
608
|
// DOM Mutation (Block Root Attributes, Reorder)
|
|
@@ -621,13 +615,7 @@ class Ht extends tt {
|
|
|
621
615
|
* producing a flicker on the custom attribute dropdowns.
|
|
622
616
|
*/
|
|
623
617
|
_updateBothAttributes(t, r) {
|
|
624
|
-
|
|
625
|
-
return;
|
|
626
|
-
const e = {
|
|
627
|
-
...$.getConfig(this.currentNode),
|
|
628
|
-
composition: t
|
|
629
|
-
};
|
|
630
|
-
this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(x, t.join(",")).setAttribute(F, JSON.stringify(r)).setNodeConfig(e).apply(new C(this.api.translate("Update card composition")));
|
|
618
|
+
this.currentNode && this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(V, t.join(",")).setAttribute(q, JSON.stringify(r)).apply(new A(this.api.translate("Update card composition")));
|
|
631
619
|
}
|
|
632
620
|
/**
|
|
633
621
|
* Reorders attribute rows within each product card based on composition order.
|
|
@@ -643,7 +631,7 @@ class Ht extends tt {
|
|
|
643
631
|
r.forEach((o) => {
|
|
644
632
|
const s = this._buildCompositionHtml(o, t);
|
|
645
633
|
e.modifyHtml(o).setInnerHtml(s);
|
|
646
|
-
}), e.apply(new
|
|
634
|
+
}), e.apply(new A(this.api.translate("Reorder product attributes")));
|
|
647
635
|
}
|
|
648
636
|
/**
|
|
649
637
|
* Builds HTML string with attributes ordered according to composition.
|
|
@@ -651,7 +639,7 @@ class Ht extends tt {
|
|
|
651
639
|
*/
|
|
652
640
|
_buildCompositionHtml(t, r) {
|
|
653
641
|
return r.reduce((e, o) => {
|
|
654
|
-
const s = t.querySelector(`${
|
|
642
|
+
const s = t.querySelector(`${C}[${y}="${o}"]`);
|
|
655
643
|
return s && "getOuterHTML" in s ? e + s.getOuterHTML() : e;
|
|
656
644
|
}, "");
|
|
657
645
|
}
|
|
@@ -661,19 +649,14 @@ class Ht extends tt {
|
|
|
661
649
|
_applyVisibilityToBlock(t, r) {
|
|
662
650
|
if (!this.currentNode)
|
|
663
651
|
return;
|
|
664
|
-
const e = this.currentNode.querySelectorAll(`${
|
|
652
|
+
const e = this.currentNode.querySelectorAll(`${C}[${y}="${t}"]`);
|
|
665
653
|
if (!(e != null && e.length))
|
|
666
654
|
return;
|
|
667
655
|
const o = r ? "1" : "0", s = r ? this.api.translate("visible") : this.api.translate("hidden"), i = `${this.api.translate("Set visibility")}: ${t} → ${s}`, n = this.api.getDocumentModifier();
|
|
668
656
|
e.forEach((a) => {
|
|
669
|
-
const
|
|
670
|
-
n.modifyHtml(a).setStyle("display",
|
|
671
|
-
});
|
|
672
|
-
const c = {
|
|
673
|
-
...$.getConfig(this.currentNode),
|
|
674
|
-
visibility: { ...this._readVisibilityFromRows(), [t]: r }
|
|
675
|
-
};
|
|
676
|
-
n.modifyHtml(this.currentNode).setNodeConfig(c), n.apply(new C(i));
|
|
657
|
+
const c = ft(a), l = r ? c : "none";
|
|
658
|
+
n.modifyHtml(a).setStyle("display", l).setAttribute(v, o);
|
|
659
|
+
}), n.apply(new A(i));
|
|
677
660
|
}
|
|
678
661
|
// ========================================================================
|
|
679
662
|
// Utilities
|
|
@@ -686,7 +669,7 @@ class Ht extends tt {
|
|
|
686
669
|
_findNthCustomKeyIndex(t, r) {
|
|
687
670
|
let e = 0;
|
|
688
671
|
for (let o = 0; o < t.length; o++)
|
|
689
|
-
if (t[o].startsWith(
|
|
672
|
+
if (t[o].startsWith(m)) {
|
|
690
673
|
if (e === r)
|
|
691
674
|
return o;
|
|
692
675
|
e++;
|
|
@@ -694,7 +677,7 @@ class Ht extends tt {
|
|
|
694
677
|
return -1;
|
|
695
678
|
}
|
|
696
679
|
_getCurrentLayout() {
|
|
697
|
-
return this.store.recommendationConfigs.orientation ||
|
|
680
|
+
return this.store.recommendationConfigs.orientation || gt(this.currentNode);
|
|
698
681
|
}
|
|
699
682
|
/**
|
|
700
683
|
* Extracts background color properties from existing card elements.
|
|
@@ -745,10 +728,10 @@ class Ht extends tt {
|
|
|
745
728
|
* or when all available filters have already been added (no unused attributes left).
|
|
746
729
|
*/
|
|
747
730
|
_updateAddButtonState() {
|
|
748
|
-
const t = this._readCustomAttributesFromNode(), r = t.length >=
|
|
731
|
+
const t = this._readCustomAttributesFromNode(), r = t.length >= g, e = new Set(t), o = this._getAddableFilters(), s = o.length > 0 && o.every((i) => e.has(i.attributeName));
|
|
749
732
|
this.api.setUIEAttribute(
|
|
750
|
-
|
|
751
|
-
|
|
733
|
+
x.ADD_ATTRIBUTE,
|
|
734
|
+
I.BUTTON.disabled,
|
|
752
735
|
r || s ? "true" : "false"
|
|
753
736
|
);
|
|
754
737
|
}
|
|
@@ -771,7 +754,7 @@ class Ht extends tt {
|
|
|
771
754
|
* excluding default attributes already covered by built-in toggle items.
|
|
772
755
|
*/
|
|
773
756
|
_getAddableFilters() {
|
|
774
|
-
return Object.values(this.store.filterList).filter((t) => !(t.type === "defaultAttribute" &&
|
|
757
|
+
return Object.values(this.store.filterList).filter((t) => !(t.type === "defaultAttribute" && it.has(t.attributeName)));
|
|
775
758
|
}
|
|
776
759
|
/**
|
|
777
760
|
* Looks up the display name for an attribute from the store's filterList.
|
|
@@ -788,28 +771,28 @@ class Ht extends tt {
|
|
|
788
771
|
_resolveAttributeContent(t, r, e) {
|
|
789
772
|
var n;
|
|
790
773
|
const s = this.store.recommendationProducts[e], i = pt(t, this.store.filterList) ? s == null ? void 0 : s[t] : (n = s == null ? void 0 : s.product_attributes) == null ? void 0 : n[t];
|
|
791
|
-
return
|
|
774
|
+
return _t(i) ?? r;
|
|
792
775
|
}
|
|
793
776
|
_getGridCellHtml(t, r, e, o = "", s = "", i = "") {
|
|
794
|
-
const n = `${
|
|
777
|
+
const n = `${m}${t}`, a = w(ct, [n], this.store.filterList), c = {
|
|
795
778
|
[t]: r,
|
|
796
779
|
product_attributes: { [t]: r }
|
|
797
780
|
};
|
|
798
|
-
let l =
|
|
781
|
+
let l = a[n](c);
|
|
799
782
|
return l = l.replace("<td", `<td width="${e}%"`), i && (l = l.replace(
|
|
800
783
|
`padding: ${ut}`,
|
|
801
784
|
`padding: ${i}`
|
|
802
785
|
)), o && (l = l.replace(/style="table-layout: fixed;"/, `style="table-layout: fixed; ${o}"`)), s && (l = l.replace(/border="0"/, `border="0" bgcolor="${s}"`)), l;
|
|
803
786
|
}
|
|
804
787
|
_getListRowHtml(t, r, e) {
|
|
805
|
-
const o =
|
|
788
|
+
const o = w(mt, [e], this.store.filterList), s = {
|
|
806
789
|
[t]: r,
|
|
807
790
|
product_attributes: { [t]: r }
|
|
808
791
|
}, n = o[e](s).replace(/<tr>/, "").replace(/<\/tr>/, "");
|
|
809
|
-
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${
|
|
792
|
+
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${v}="1">${n}</tr>`;
|
|
810
793
|
}
|
|
811
794
|
}
|
|
812
795
|
export {
|
|
813
796
|
bt as COMPOSITION_CONTROL_BLOCK_ID,
|
|
814
|
-
|
|
797
|
+
Ut as RecommendationCardCompositionControl
|
|
815
798
|
};
|
|
@@ -24,5 +24,13 @@ export declare class ItemsBlock extends Block {
|
|
|
24
24
|
getSettingsPanelTitleHtml(): string;
|
|
25
25
|
getTemplate(): string;
|
|
26
26
|
allowInnerBlocksDND(): boolean;
|
|
27
|
+
canBeSavedAsModule(): boolean;
|
|
27
28
|
onCreated(node: ImmutableHtmlNode): void;
|
|
29
|
+
/**
|
|
30
|
+
* Re-seeds nodeConfig from the persisted esd-ext-config when a saved module
|
|
31
|
+
* surfaces via document load. Stripo strips esd-ext-config and never restores it
|
|
32
|
+
* into nodeConfig, so without this a reused module would reset to defaults.
|
|
33
|
+
* Guarded to the nodeConfig-empty case so it runs once and never loops.
|
|
34
|
+
*/
|
|
35
|
+
onDocumentChanged(node: ImmutableHtmlNode): void;
|
|
28
36
|
}
|
|
@@ -55,7 +55,7 @@ export declare function getItemsBlockContainer(currentNode: ImmutableHtmlNode |
|
|
|
55
55
|
/**
|
|
56
56
|
* Gets the node configuration from the Items block.
|
|
57
57
|
* Uses Stripo V2's getNodeConfig() API.
|
|
58
|
-
* Falls back to
|
|
58
|
+
* Falls back to the persisted esd-ext-config (saved modules), then legacy config block.
|
|
59
59
|
* @param currentNode - The current node from the control
|
|
60
60
|
* @returns The ItemsBlockConfig object or null if not found
|
|
61
61
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useinsider/guido",
|
|
3
|
-
"version": "3.7.0-beta.
|
|
3
|
+
"version": "3.7.0-beta.4311638",
|
|
4
4
|
"description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
|
|
5
5
|
"main": "./dist/guido.umd.cjs",
|
|
6
6
|
"module": "./dist/library.js",
|