@useinsider/guido 3.2.0-beta.e01b42a → 3.2.0
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/README.md +1 -0
- package/dist/@types/config/schemas.js +66 -54
- package/dist/components/Guido.vue.js +4 -4
- package/dist/components/Guido.vue2.js +91 -81
- package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue.js +7 -7
- package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue2.js +12 -20
- package/dist/components/organisms/header/EditorActions.vue.js +2 -2
- package/dist/components/organisms/header/EditorActions.vue2.js +51 -36
- package/dist/components/organisms/header/RightSlot.vue.js +10 -10
- package/dist/components/organisms/header/RightSlot.vue2.js +16 -13
- package/dist/components/organisms/save-as-template/SaveAsTemplateDrawer.vue2.js +18 -17
- package/dist/composables/useHtmlCompiler.js +23 -21
- package/dist/composables/useHtmlValidator.js +40 -38
- package/dist/composables/usePreviewMode.js +20 -16
- package/dist/composables/useSave.js +23 -15
- package/dist/composables/useStripo.js +44 -41
- package/dist/composables/validators/useLiquidValidator.js +42 -0
- package/dist/config/compiler/liquidCompilerRules.js +15 -0
- package/dist/config/compiler/recommendationCompilerRules.js +158 -44
- package/dist/config/compiler/unsubscribeCompilerRules.js +37 -37
- package/dist/config/compiler/utils/recommendationCompilerUtils.js +49 -46
- package/dist/config/migrator/checkboxMigrator.js +5 -3
- package/dist/config/migrator/radioButtonMigrator.js +14 -12
- package/dist/enums/extensions/recommendationBlock.js +14 -11
- package/dist/enums/recommendation.js +2 -2
- package/dist/extensions/Blocks/CouponBlock/template.js +24 -13
- package/dist/extensions/Blocks/Recommendation/constants/selectors.js +27 -11
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +185 -172
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +94 -92
- package/dist/extensions/Blocks/Recommendation/controls/spacing/index.js +31 -31
- package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +7 -5
- package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +30 -29
- package/dist/extensions/Blocks/Recommendation/templates/index.js +7 -7
- package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +3 -1
- package/dist/extensions/Blocks/Recommendation/templates/list/template.js +20 -20
- package/dist/extensions/Blocks/Recommendation/templates/utils.js +57 -50
- package/dist/extensions/DynamicContent/dynamic-content.js +17 -12
- package/dist/guido.css +1 -1
- package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +218 -324
- package/dist/package.json.js +1 -1
- package/dist/services/recommendationApi.js +15 -15
- package/dist/services/stripoApi.js +9 -9
- package/dist/services/templateLibraryApi.js +48 -46
- package/dist/src/@types/config/index.d.ts +1 -1
- package/dist/src/@types/config/schemas.d.ts +28 -0
- package/dist/src/@types/config/types.d.ts +3 -1
- package/dist/src/@types/generic.d.ts +0 -1
- package/dist/src/@types/save-as-template.d.ts +1 -0
- package/dist/src/composables/useConfig.d.ts +12 -0
- package/dist/src/composables/validators/useLiquidValidator.d.ts +3 -0
- package/dist/src/config/compiler/liquidCompilerRules.d.ts +2 -0
- package/dist/src/config/compiler/utils/recommendationCompilerUtils.d.ts +1 -1
- package/dist/src/enums/extensions/recommendationBlock.d.ts +3 -0
- package/dist/src/extensions/Blocks/CouponBlock/template.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +5 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +5 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
- package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +3 -3
- package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +20 -3
- package/dist/src/extensions/Blocks/Recommendation/utils/tagName.d.ts +3 -3
- package/dist/src/services/templateLibraryApi.d.ts +1 -1
- package/dist/src/stores/config.d.ts +108 -0
- package/dist/src/stores/preview.d.ts +3 -0
- package/dist/src/utils/genericUtil.d.ts +1 -1
- package/dist/src/utils/htmlCompiler.d.ts +2 -1
- package/dist/static/styles/base.css.js +7 -2
- package/dist/static/styles/components/button.css.js +7 -13
- package/dist/static/styles/components/narrow-panel.css.js +0 -52
- package/dist/stores/preview.js +4 -3
- package/dist/utils/genericUtil.js +42 -20
- package/dist/utils/htmlCompiler.js +48 -41
- package/dist/utils/templatePreparation.js +36 -25
- package/dist/utils/tooltipUtils.js +4 -5
- package/package.json +4 -4
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
var X = Object.defineProperty;
|
|
2
|
-
var J = (p,
|
|
3
|
-
var
|
|
4
|
-
import { UIElementType as
|
|
2
|
+
var J = (p, _, t) => _ in p ? X(p, _, { enumerable: !0, configurable: !0, writable: !0, value: t }) : p[_] = t;
|
|
3
|
+
var C = (p, _, t) => J(p, typeof _ != "symbol" ? _ + "" : _, t);
|
|
4
|
+
import { UIElementType as f, UEAttr as $, ModificationDescription as A } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
5
|
import { CommonControl as Q } from "../../../common-control.js";
|
|
6
|
-
import { ATTR_PRODUCT_IMAGE as L, ATTR_PRODUCT_NAME as Z, ATTR_PRODUCT_PRICE as tt, ATTR_PRODUCT_OLD_PRICE as et, ATTR_PRODUCT_OMNIBUS_PRICE as rt, ATTR_PRODUCT_OMNIBUS_DISCOUNT as ot, ATTR_PRODUCT_BUTTON as D, ATTR_DATA_CUSTOM_ATTRIBUTES as
|
|
7
|
-
import { DEFAULT_COMPOSITION as
|
|
8
|
-
import { RecommendationConfigService as
|
|
9
|
-
import { useRecommendationExtensionStore as
|
|
10
|
-
import { ATTRIBUTE_CELL_CLASS as
|
|
11
|
-
import { listElementRenderer as
|
|
12
|
-
import { toDisplayName as
|
|
13
|
-
import { getTableDisplayValue as
|
|
14
|
-
import { getCurrentLayout as
|
|
15
|
-
const
|
|
6
|
+
import { ATTR_PRODUCT_IMAGE as L, ATTR_PRODUCT_NAME as Z, ATTR_PRODUCT_PRICE as tt, ATTR_PRODUCT_OLD_PRICE as et, ATTR_PRODUCT_OMNIBUS_PRICE as rt, ATTR_PRODUCT_OMNIBUS_DISCOUNT as ot, ATTR_PRODUCT_BUTTON as D, ATTR_DATA_CUSTOM_ATTRIBUTES as k, ATTR_CUSTOM_PREFIX as m, BUILT_IN_DEFAULT_ATTRIBUTES as st } from "../../constants/selectors.js";
|
|
7
|
+
import { DEFAULT_COMPOSITION as q, DEFAULT_VISIBILITY as P } from "../../constants/defaultConfig.js";
|
|
8
|
+
import { RecommendationConfigService as it } from "../../services/configService.js";
|
|
9
|
+
import { useRecommendationExtensionStore as nt } from "../../store/recommendation.js";
|
|
10
|
+
import { ATTRIBUTE_CELL_CLASS as lt, gridElementRenderer as at, DEFAULT_CELL_PADDING as ct } from "../../templates/grid/elementRenderer.js";
|
|
11
|
+
import { listElementRenderer as ut } from "../../templates/list/elementRenderer.js";
|
|
12
|
+
import { toDisplayName as dt, isDefaultAttribute as mt, buildElementRenderer as F } from "../../templates/utils.js";
|
|
13
|
+
import { getTableDisplayValue as ht } from "../../utils/tagName.js";
|
|
14
|
+
import { getCurrentLayout as pt } from "../main/utils.js";
|
|
15
|
+
const _t = "ui-elements-recommendation-card-composition", S = ".recommendation-attribute-row", N = ".product-card-wrapper > tbody", w = ".product-info-cell > table > tbody", M = "data-card-composition", y = "data-attribute-type", I = "data-visibility", x = {
|
|
16
16
|
ADD_ATTRIBUTE: "addAttribute"
|
|
17
17
|
}, g = 5, v = "reorderIcon_", h = [
|
|
18
18
|
{ key: L, label: "Product Image" },
|
|
@@ -22,21 +22,21 @@ const ht = "ui-elements-recommendation-card-composition", A = ".recommendation-a
|
|
|
22
22
|
{ key: rt, label: "Omnibus Price" },
|
|
23
23
|
{ key: ot, label: "Omnibus Discount" },
|
|
24
24
|
{ key: D, label: "Product Button" }
|
|
25
|
-
],
|
|
26
|
-
class
|
|
25
|
+
], ft = new Set(h.map((p) => p.key)), T = "customAttr_", E = "deleteAttr_";
|
|
26
|
+
class Nt extends Q {
|
|
27
27
|
constructor() {
|
|
28
28
|
super(...arguments);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
C(this, "store", nt());
|
|
30
|
+
C(this, "unsubscribeStore", null);
|
|
31
|
+
C(this, "eventController", null);
|
|
32
32
|
/**
|
|
33
33
|
* Guard flag: when true, onTemplateNodeUpdated skips _initializeComposition.
|
|
34
34
|
* Used during _onReorder to prevent multiple intermediate rebuilds.
|
|
35
35
|
*/
|
|
36
|
-
|
|
36
|
+
C(this, "reorderInProgress", !1);
|
|
37
37
|
}
|
|
38
38
|
getId() {
|
|
39
|
-
return
|
|
39
|
+
return _t;
|
|
40
40
|
}
|
|
41
41
|
// ========================================================================
|
|
42
42
|
// Lifecycle
|
|
@@ -49,9 +49,9 @@ class Rt extends Q {
|
|
|
49
49
|
`).join(""), r = Array.from(
|
|
50
50
|
{ length: g },
|
|
51
51
|
(l, u) => `
|
|
52
|
-
<div data-custom-select-key="${
|
|
52
|
+
<div data-custom-select-key="${T}${u}" style="display: none;">
|
|
53
53
|
${this._GuSelect({
|
|
54
|
-
name: `${
|
|
54
|
+
name: `${T}${u}`,
|
|
55
55
|
placeholder: this.api.translate("Select Attribute"),
|
|
56
56
|
options: []
|
|
57
57
|
})}
|
|
@@ -61,43 +61,43 @@ class Rt extends Q {
|
|
|
61
61
|
{ length: e },
|
|
62
62
|
(l, u) => `
|
|
63
63
|
<div data-reorder-icon-key="${v}${u}" style="display: none;">
|
|
64
|
-
<${
|
|
64
|
+
<${f.BUTTON}
|
|
65
65
|
class="drag-handle-btn flat-inline flat-white"
|
|
66
66
|
${$.BUTTON.name}="${v}${u}"
|
|
67
67
|
>
|
|
68
|
-
<${
|
|
68
|
+
<${f.ICON}
|
|
69
69
|
src="reorder"
|
|
70
70
|
class="icon-button"
|
|
71
|
-
></${
|
|
72
|
-
</${
|
|
71
|
+
></${f.ICON}>
|
|
72
|
+
</${f.BUTTON}>
|
|
73
73
|
</div>
|
|
74
74
|
`
|
|
75
75
|
).join(""), s = Array.from(
|
|
76
76
|
{ length: g },
|
|
77
77
|
(l, u) => `
|
|
78
|
-
<div data-custom-delete-key="${
|
|
79
|
-
<${
|
|
78
|
+
<div data-custom-delete-key="${E}${u}" style="display: none;">
|
|
79
|
+
<${f.BUTTON}
|
|
80
80
|
class="custom-attr-delete flat-inline flat-white"
|
|
81
|
-
${$.BUTTON.name}="${
|
|
81
|
+
${$.BUTTON.name}="${E}${u}"
|
|
82
82
|
>
|
|
83
|
-
<${
|
|
83
|
+
<${f.ICON}
|
|
84
84
|
src="delete"
|
|
85
85
|
class="icon-button"
|
|
86
|
-
></${
|
|
87
|
-
</${
|
|
86
|
+
></${f.ICON}>
|
|
87
|
+
</${f.BUTTON}>
|
|
88
88
|
</div>
|
|
89
89
|
`
|
|
90
|
-
).join(""),
|
|
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
|
+
), c = this.api.translate("For more information, you can"), a = 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
|
-
${
|
|
98
|
-
${
|
|
97
|
+
${n}
|
|
98
|
+
${c}
|
|
99
99
|
<!-- cspell:disable-next-line -->
|
|
100
|
-
<a href="${
|
|
100
|
+
<a href="${i}" target="_blank" rel="noopener noreferrer">${a}</a>.
|
|
101
101
|
</p>
|
|
102
102
|
</div>
|
|
103
103
|
|
|
@@ -120,7 +120,7 @@ class Rt extends Q {
|
|
|
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
|
})}
|
|
@@ -150,7 +150,7 @@ class Rt extends Q {
|
|
|
150
150
|
});
|
|
151
151
|
});
|
|
152
152
|
for (let t = 0; t < g; t++) {
|
|
153
|
-
const r = `${
|
|
153
|
+
const r = `${T}${t}`, e = t;
|
|
154
154
|
this.api.onValueChanged(r, (o) => {
|
|
155
155
|
this._onCustomAttributeChanged(e, o);
|
|
156
156
|
});
|
|
@@ -161,14 +161,14 @@ class Rt extends Q {
|
|
|
161
161
|
// ========================================================================
|
|
162
162
|
_readCompositionFromNode() {
|
|
163
163
|
if (!this.currentNode || !("getAttribute" in this.currentNode))
|
|
164
|
-
return [...
|
|
164
|
+
return [...q];
|
|
165
165
|
const t = this.currentNode.getAttribute(M);
|
|
166
|
-
return t ? t.split(",").filter(Boolean) : [...
|
|
166
|
+
return t ? t.split(",").filter(Boolean) : [...q];
|
|
167
167
|
}
|
|
168
168
|
_readCustomAttributesFromNode() {
|
|
169
169
|
if (!this.currentNode || !("getAttribute" in this.currentNode))
|
|
170
170
|
return [];
|
|
171
|
-
const t = this.currentNode.getAttribute(
|
|
171
|
+
const t = this.currentNode.getAttribute(k);
|
|
172
172
|
if (!t)
|
|
173
173
|
return [];
|
|
174
174
|
try {
|
|
@@ -180,7 +180,7 @@ class Rt extends Q {
|
|
|
180
180
|
_readVisibilityFromRows() {
|
|
181
181
|
if (!this.currentNode)
|
|
182
182
|
return this._getDefaultVisibilities();
|
|
183
|
-
const t = Array.from(this.currentNode.querySelectorAll(
|
|
183
|
+
const t = Array.from(this.currentNode.querySelectorAll(S)), r = this._extractVisibilityFromRows(t);
|
|
184
184
|
return this._mergeWithDefaults(r);
|
|
185
185
|
}
|
|
186
186
|
_getDefaultVisibilities() {
|
|
@@ -222,20 +222,20 @@ class Rt extends Q {
|
|
|
222
222
|
if (!o || this._tryReorderInPlace(o, t))
|
|
223
223
|
return !1;
|
|
224
224
|
const s = new Set(r);
|
|
225
|
-
let
|
|
226
|
-
const
|
|
227
|
-
if (
|
|
228
|
-
const l = h.find((u) => u.key ===
|
|
229
|
-
return this._createBuiltInItemHtml(l,
|
|
225
|
+
let i = 0, n = 0;
|
|
226
|
+
const c = t.map((a) => {
|
|
227
|
+
if (ft.has(a)) {
|
|
228
|
+
const l = h.find((u) => u.key === a);
|
|
229
|
+
return this._createBuiltInItemHtml(l, n++);
|
|
230
230
|
}
|
|
231
|
-
if (
|
|
232
|
-
const l =
|
|
231
|
+
if (a.startsWith(m)) {
|
|
232
|
+
const l = a.substring(m.length);
|
|
233
233
|
if (s.has(l))
|
|
234
|
-
return this._createCustomItemHtml(
|
|
234
|
+
return this._createCustomItemHtml(a, i++, n++);
|
|
235
235
|
}
|
|
236
236
|
return "";
|
|
237
237
|
}).join("");
|
|
238
|
-
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 = c, this._moveTogglesIntoItems(e), this._moveSelectsIntoItems(e, r.length), this._moveDeleteButtonsIntoItems(e, r.length), this._moveReorderIconsIntoItems(e, n), !0;
|
|
239
239
|
}
|
|
240
240
|
/**
|
|
241
241
|
* Attempts to reorder existing orderable-item elements to match the composition order.
|
|
@@ -247,27 +247,27 @@ class Rt extends Q {
|
|
|
247
247
|
const e = Array.from(t.querySelectorAll(".orderable-item"));
|
|
248
248
|
if (e.length !== r.length)
|
|
249
249
|
return !1;
|
|
250
|
-
const o = e.map((
|
|
250
|
+
const o = e.map((a) => a.dataset.key).filter(Boolean);
|
|
251
251
|
if (o.length !== r.length)
|
|
252
252
|
return !1;
|
|
253
|
-
const s = [...o].sort().join(","),
|
|
254
|
-
if (s !==
|
|
253
|
+
const s = [...o].sort().join(","), i = [...r].sort().join(",");
|
|
254
|
+
if (s !== i || r.some((a) => a.startsWith(m)))
|
|
255
255
|
return !1;
|
|
256
|
-
const
|
|
257
|
-
e.forEach((
|
|
258
|
-
const { key: l } =
|
|
256
|
+
const n = /* @__PURE__ */ new Map();
|
|
257
|
+
e.forEach((a) => {
|
|
258
|
+
const { key: l } = a.dataset;
|
|
259
259
|
if (l) {
|
|
260
|
-
const u =
|
|
261
|
-
u.push(
|
|
260
|
+
const u = n.get(l) || [];
|
|
261
|
+
u.push(a), n.set(l, u);
|
|
262
262
|
}
|
|
263
263
|
});
|
|
264
|
-
const
|
|
265
|
-
return r.forEach((
|
|
266
|
-
const l =
|
|
264
|
+
const c = /* @__PURE__ */ new Map();
|
|
265
|
+
return r.forEach((a) => {
|
|
266
|
+
const l = n.get(a);
|
|
267
267
|
if (!l)
|
|
268
268
|
return;
|
|
269
|
-
const u =
|
|
270
|
-
|
|
269
|
+
const u = c.get(a) || 0;
|
|
270
|
+
c.set(a, u + 1), l[u] && t.appendChild(l[u]);
|
|
271
271
|
}), !0;
|
|
272
272
|
}
|
|
273
273
|
_createBuiltInItemHtml(t, r) {
|
|
@@ -297,10 +297,10 @@ class Rt extends Q {
|
|
|
297
297
|
* Falls back to a single option for the currently selected attribute.
|
|
298
298
|
*/
|
|
299
299
|
_getSelectOptions(t, r = []) {
|
|
300
|
-
const
|
|
301
|
-
if (
|
|
302
|
-
const
|
|
303
|
-
return
|
|
300
|
+
const e = this._getAddableFilters();
|
|
301
|
+
if (e.length > 0) {
|
|
302
|
+
const s = new Set(r);
|
|
303
|
+
return s.delete(t), e.filter((i) => !s.has(i.attributeName)).map((i) => ({
|
|
304
304
|
text: i.displayName,
|
|
305
305
|
value: i.attributeName
|
|
306
306
|
}));
|
|
@@ -315,7 +315,7 @@ class Rt extends Q {
|
|
|
315
315
|
_initializeCustomSelects(t) {
|
|
316
316
|
t.length !== 0 && setTimeout(() => {
|
|
317
317
|
t.forEach((r, e) => {
|
|
318
|
-
const o = `${
|
|
318
|
+
const o = `${T}${e}`, s = this._getSelectOptions(r, t);
|
|
319
319
|
this.api.setUIEAttribute(o, $.SELECTPICKER.items, s), this.api.updateValues({ [o]: r });
|
|
320
320
|
});
|
|
321
321
|
}, 0);
|
|
@@ -339,10 +339,10 @@ class Rt extends Q {
|
|
|
339
339
|
*/
|
|
340
340
|
_moveSelectsIntoItems(t, r) {
|
|
341
341
|
for (let e = 0; e < r; e++) {
|
|
342
|
-
const o = `${
|
|
343
|
-
if (s &&
|
|
344
|
-
const
|
|
345
|
-
|
|
342
|
+
const o = `${T}${e}`, s = t.querySelector(`[data-custom-select-key="${o}"]`), i = t.querySelector(`[data-custom-select-slot="${e}"]`);
|
|
343
|
+
if (s && i) {
|
|
344
|
+
const n = s.querySelector("ue-select");
|
|
345
|
+
n && i.appendChild(n);
|
|
346
346
|
}
|
|
347
347
|
}
|
|
348
348
|
}
|
|
@@ -367,10 +367,10 @@ class Rt extends Q {
|
|
|
367
367
|
*/
|
|
368
368
|
_rescueSelectsToStore(t) {
|
|
369
369
|
for (let r = 0; r < g; r++) {
|
|
370
|
-
const e = `${
|
|
370
|
+
const e = `${T}${r}`, o = t.querySelector(`[data-custom-select-key="${e}"]`), s = t.querySelector(`[data-custom-select-slot="${r}"]`);
|
|
371
371
|
if (s) {
|
|
372
|
-
const
|
|
373
|
-
|
|
372
|
+
const i = s.querySelector("ue-select");
|
|
373
|
+
i && o && o.appendChild(i);
|
|
374
374
|
}
|
|
375
375
|
}
|
|
376
376
|
}
|
|
@@ -380,10 +380,10 @@ class Rt extends Q {
|
|
|
380
380
|
*/
|
|
381
381
|
_moveDeleteButtonsIntoItems(t, r) {
|
|
382
382
|
for (let e = 0; e < r; e++) {
|
|
383
|
-
const o = `${
|
|
384
|
-
if (s &&
|
|
385
|
-
const
|
|
386
|
-
|
|
383
|
+
const o = `${E}${e}`, s = t.querySelector(`[data-custom-delete-key="${o}"]`), i = t.querySelector(`[data-custom-delete-slot="${e}"]`);
|
|
384
|
+
if (s && i) {
|
|
385
|
+
const n = s.querySelector("ue-button");
|
|
386
|
+
n && i.appendChild(n);
|
|
387
387
|
}
|
|
388
388
|
}
|
|
389
389
|
}
|
|
@@ -393,10 +393,10 @@ class Rt extends Q {
|
|
|
393
393
|
*/
|
|
394
394
|
_rescueDeleteButtonsToStore(t) {
|
|
395
395
|
for (let r = 0; r < g; r++) {
|
|
396
|
-
const e = `${
|
|
396
|
+
const e = `${E}${r}`, o = t.querySelector(`[data-custom-delete-key="${e}"]`), s = t.querySelector(`[data-custom-delete-slot="${r}"]`);
|
|
397
397
|
if (s) {
|
|
398
|
-
const
|
|
399
|
-
|
|
398
|
+
const i = s.querySelector("ue-button");
|
|
399
|
+
i && o && o.appendChild(i);
|
|
400
400
|
}
|
|
401
401
|
}
|
|
402
402
|
}
|
|
@@ -406,10 +406,10 @@ class Rt extends Q {
|
|
|
406
406
|
*/
|
|
407
407
|
_moveReorderIconsIntoItems(t, r) {
|
|
408
408
|
for (let e = 0; e < r; e++) {
|
|
409
|
-
const o = `${v}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`),
|
|
410
|
-
if (s &&
|
|
411
|
-
const
|
|
412
|
-
|
|
409
|
+
const o = `${v}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
|
|
410
|
+
if (s && i) {
|
|
411
|
+
const n = s.querySelector("ue-button");
|
|
412
|
+
n && i.appendChild(n);
|
|
413
413
|
}
|
|
414
414
|
}
|
|
415
415
|
}
|
|
@@ -420,10 +420,10 @@ class Rt extends Q {
|
|
|
420
420
|
_rescueReorderIconsToStore(t) {
|
|
421
421
|
const r = h.length + g;
|
|
422
422
|
for (let e = 0; e < r; e++) {
|
|
423
|
-
const o = `${v}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`),
|
|
424
|
-
if (
|
|
425
|
-
const
|
|
426
|
-
|
|
423
|
+
const o = `${v}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
|
|
424
|
+
if (i) {
|
|
425
|
+
const n = i.querySelector("ue-button");
|
|
426
|
+
n && s && s.appendChild(n);
|
|
427
427
|
}
|
|
428
428
|
}
|
|
429
429
|
}
|
|
@@ -437,29 +437,29 @@ class Rt extends Q {
|
|
|
437
437
|
return;
|
|
438
438
|
const e = r.querySelector("[data-composition-list]"), o = r.querySelector("#guido__btn-add-attribute");
|
|
439
439
|
e && (this._setupDragAndDrop(e, t), this._setupDeleteHandler(e, t)), o && o.addEventListener("click", () => {
|
|
440
|
-
const s = new Set(this._readCustomAttributesFromNode()), i =
|
|
440
|
+
const s = new Set(this._readCustomAttributesFromNode()), i = this._getAddableFilters().find((n) => !s.has(n.attributeName));
|
|
441
441
|
i && this._onAddAttribute(i.attributeName, i.displayName);
|
|
442
442
|
}, { signal: t });
|
|
443
443
|
}
|
|
444
444
|
_setupDragAndDrop(t, r) {
|
|
445
445
|
let e = null, o = null;
|
|
446
446
|
t.addEventListener("dragstart", (s) => {
|
|
447
|
-
var
|
|
448
|
-
const
|
|
449
|
-
|
|
447
|
+
var c;
|
|
448
|
+
const n = s.target.closest(".orderable-item");
|
|
449
|
+
n && (e = n, n.classList.add("dragging"), (c = s.dataTransfer) == null || c.setData("text/plain", n.dataset.key || ""));
|
|
450
450
|
}, { signal: r }), t.addEventListener("dragend", () => {
|
|
451
451
|
e && e.classList.remove("dragging"), e = null, o == null || o.classList.remove("drag-over"), o = null;
|
|
452
452
|
}, { signal: r }), t.addEventListener("dragover", (s) => {
|
|
453
453
|
s.preventDefault();
|
|
454
|
-
const
|
|
455
|
-
|
|
454
|
+
const n = s.target.closest(".orderable-item"), c = n && n !== e ? n : null;
|
|
455
|
+
c !== o && (o == null || o.classList.remove("drag-over"), o = c, o == null || o.classList.add("drag-over"));
|
|
456
456
|
}, { signal: r }), t.addEventListener("drop", (s) => {
|
|
457
457
|
s.preventDefault();
|
|
458
|
-
const
|
|
459
|
-
if (!
|
|
458
|
+
const n = s.target.closest(".orderable-item");
|
|
459
|
+
if (!n || !e || n === e)
|
|
460
460
|
return;
|
|
461
|
-
const
|
|
462
|
-
s.clientY <
|
|
461
|
+
const c = n.getBoundingClientRect(), a = c.top + c.height / 2;
|
|
462
|
+
s.clientY < a ? t.insertBefore(e, n) : t.insertBefore(e, n.nextSibling), o == null || o.classList.remove("drag-over"), o = null, e.classList.remove("dragging");
|
|
463
463
|
const u = t.querySelectorAll(".orderable-item"), d = Array.from(u).map((b) => b.dataset.key).filter(Boolean);
|
|
464
464
|
this._onReorder(d), e = null;
|
|
465
465
|
}, { signal: r });
|
|
@@ -469,8 +469,8 @@ class Rt extends Q {
|
|
|
469
469
|
const s = e.target.closest(".custom-attr-delete");
|
|
470
470
|
if (!s)
|
|
471
471
|
return;
|
|
472
|
-
const
|
|
473
|
-
|
|
472
|
+
const i = s.closest("[data-custom-index]"), n = i == null ? void 0 : i.dataset.customIndex;
|
|
473
|
+
n !== void 0 && this._onDeleteCustomAttribute(Number(n));
|
|
474
474
|
}, { signal: r });
|
|
475
475
|
}
|
|
476
476
|
// ========================================================================
|
|
@@ -490,8 +490,8 @@ class Rt extends Q {
|
|
|
490
490
|
const r = this._readCustomAttributesFromNode();
|
|
491
491
|
if (r[t] === void 0)
|
|
492
492
|
return;
|
|
493
|
-
const o = this._readCompositionFromNode(), s = this._findNthCustomKeyIndex(o, t),
|
|
494
|
-
this._updateBothAttributes(
|
|
493
|
+
const o = this._readCompositionFromNode(), s = this._findNthCustomKeyIndex(o, t), i = o.filter((c, a) => a !== s), n = r.filter((c, a) => a !== t);
|
|
494
|
+
this._updateBothAttributes(i, n), this._removeCustomAttributeHtml(i), this._renderOrderableItems(i, n), this._initializeCustomSelects(n), this._updateAddButtonState();
|
|
495
495
|
}
|
|
496
496
|
/**
|
|
497
497
|
* Handles changing a custom attribute's selection via its inline _GuSelect.
|
|
@@ -501,10 +501,10 @@ class Rt extends Q {
|
|
|
501
501
|
const e = this._readCustomAttributesFromNode(), o = e[t];
|
|
502
502
|
if (o === void 0 || o === r)
|
|
503
503
|
return;
|
|
504
|
-
const s = `${m}${r}`,
|
|
505
|
-
|
|
506
|
-
const
|
|
507
|
-
this._updateBothAttributes(
|
|
504
|
+
const s = `${m}${r}`, i = this._readCompositionFromNode(), n = this._findNthCustomKeyIndex(i, t);
|
|
505
|
+
n !== -1 && (i[n] = s), e[t] = r;
|
|
506
|
+
const c = this._getDisplayNameForAttribute(r);
|
|
507
|
+
this._updateBothAttributes(i, e), this._injectCustomAttributeHtml(r, c, s, i), this._renderOrderableItems(i, e), this._initializeCustomSelects(e);
|
|
508
508
|
}
|
|
509
509
|
_onReorder(t) {
|
|
510
510
|
const r = t.filter((e) => e.startsWith(m)).map((e) => e.substring(m.length));
|
|
@@ -528,54 +528,54 @@ class Rt extends Q {
|
|
|
528
528
|
const s = this.currentNode.querySelectorAll(N);
|
|
529
529
|
if (!(s != null && s.length))
|
|
530
530
|
return;
|
|
531
|
-
const
|
|
531
|
+
const i = it.getConfig(this.currentNode), c = `0 ${Math.floor(i.columnSpacing / 2)}px`, a = this.api.getDocumentModifier(), l = this.store.recommendationProducts.length;
|
|
532
532
|
let u = 0;
|
|
533
533
|
s.forEach((d) => {
|
|
534
|
-
var
|
|
535
|
-
const b = d.querySelector(
|
|
536
|
-
if (
|
|
534
|
+
var U;
|
|
535
|
+
const b = d.querySelector(S), R = ((U = b == null ? void 0 : b.querySelectorAll(`.${lt}`)) == null ? void 0 : U.length) || 1, V = (100 / R).toFixed(2), { bgStyle: j, bgAttr: W } = this._extractSegmentBgFromCard(d), K = o.map((B) => {
|
|
536
|
+
if (B === e) {
|
|
537
537
|
const z = Array.from(
|
|
538
538
|
{ length: R },
|
|
539
|
-
(
|
|
540
|
-
const G = l > 0 ? (u +
|
|
539
|
+
(gt, H) => {
|
|
540
|
+
const G = l > 0 ? (u + H) % l : H, Y = this._resolveAttributeContent(t, r, G);
|
|
541
541
|
return this._getGridCellHtml(
|
|
542
542
|
t,
|
|
543
543
|
Y,
|
|
544
|
-
x,
|
|
545
544
|
V,
|
|
545
|
+
j,
|
|
546
546
|
W,
|
|
547
|
-
|
|
547
|
+
c
|
|
548
548
|
);
|
|
549
549
|
}
|
|
550
550
|
).join("");
|
|
551
551
|
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${I}="1">${z}</tr>`;
|
|
552
552
|
}
|
|
553
|
-
const
|
|
554
|
-
`${
|
|
553
|
+
const O = d.querySelector(
|
|
554
|
+
`${S}[${y}="${B}"]`
|
|
555
555
|
);
|
|
556
|
-
return
|
|
556
|
+
return O && "getOuterHTML" in O ? O.getOuterHTML() : "";
|
|
557
557
|
}).join("");
|
|
558
|
-
u += R, l > 0 && u >= l && (u = 0),
|
|
559
|
-
}),
|
|
558
|
+
u += R, l > 0 && u >= l && (u = 0), a.modifyHtml(d).setInnerHtml(K);
|
|
559
|
+
}), a.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
|
|
560
560
|
}
|
|
561
561
|
_injectListAttributeRow(t, r, e, o) {
|
|
562
|
-
const s = this.currentNode.querySelectorAll(
|
|
562
|
+
const s = this.currentNode.querySelectorAll(w);
|
|
563
563
|
if (!(s != null && s.length))
|
|
564
564
|
return;
|
|
565
|
-
const
|
|
566
|
-
s.forEach((
|
|
567
|
-
const l =
|
|
565
|
+
const i = o.filter((c) => c !== L && c !== D), n = this.api.getDocumentModifier();
|
|
566
|
+
s.forEach((c, a) => {
|
|
567
|
+
const l = i.map((u) => {
|
|
568
568
|
if (u === e) {
|
|
569
|
-
const b = this._resolveAttributeContent(t, r,
|
|
569
|
+
const b = this._resolveAttributeContent(t, r, a);
|
|
570
570
|
return this._getListRowHtml(t, b, e);
|
|
571
571
|
}
|
|
572
|
-
const d =
|
|
573
|
-
`${
|
|
572
|
+
const d = c.querySelector(
|
|
573
|
+
`${S}[${y}="${u}"]`
|
|
574
574
|
);
|
|
575
575
|
return d && "getOuterHTML" in d ? d.getOuterHTML() : "";
|
|
576
576
|
}).join("");
|
|
577
|
-
|
|
578
|
-
}),
|
|
577
|
+
n.modifyHtml(c).setInnerHtml(l);
|
|
578
|
+
}), n.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
|
|
579
579
|
}
|
|
580
580
|
/**
|
|
581
581
|
* Removes a custom attribute by rebuilding product card content without it.
|
|
@@ -588,17 +588,17 @@ class Rt extends Q {
|
|
|
588
588
|
if (r === "grid") {
|
|
589
589
|
const o = this.currentNode.querySelectorAll(N);
|
|
590
590
|
o == null || o.forEach((s) => {
|
|
591
|
-
const
|
|
592
|
-
e.modifyHtml(s).setInnerHtml(
|
|
591
|
+
const i = this._buildCompositionHtml(s, t);
|
|
592
|
+
e.modifyHtml(s).setInnerHtml(i);
|
|
593
593
|
});
|
|
594
594
|
} else {
|
|
595
|
-
const o = t.filter((
|
|
596
|
-
s == null || s.forEach((
|
|
597
|
-
const
|
|
598
|
-
e.modifyHtml(
|
|
595
|
+
const o = t.filter((i) => i !== L && i !== D), s = this.currentNode.querySelectorAll(w);
|
|
596
|
+
s == null || s.forEach((i) => {
|
|
597
|
+
const n = this._buildCompositionHtml(i, o);
|
|
598
|
+
e.modifyHtml(i).setInnerHtml(n);
|
|
599
599
|
});
|
|
600
600
|
}
|
|
601
|
-
e.apply(new
|
|
601
|
+
e.apply(new A(this.api.translate("Remove custom attribute")));
|
|
602
602
|
}
|
|
603
603
|
// ========================================================================
|
|
604
604
|
// DOM Mutation (Block Root Attributes, Reorder)
|
|
@@ -611,7 +611,7 @@ class Rt extends Q {
|
|
|
611
611
|
* producing a flicker on the custom attribute dropdowns.
|
|
612
612
|
*/
|
|
613
613
|
_updateBothAttributes(t, r) {
|
|
614
|
-
this.currentNode && this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(M, t.join(",")).setAttribute(
|
|
614
|
+
this.currentNode && this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(M, t.join(",")).setAttribute(k, JSON.stringify(r)).apply(new A(this.api.translate("Update card composition")));
|
|
615
615
|
}
|
|
616
616
|
/**
|
|
617
617
|
* Reorders attribute rows within each product card based on composition order.
|
|
@@ -627,7 +627,7 @@ class Rt extends Q {
|
|
|
627
627
|
r.forEach((o) => {
|
|
628
628
|
const s = this._buildCompositionHtml(o, t);
|
|
629
629
|
e.modifyHtml(o).setInnerHtml(s);
|
|
630
|
-
}), e.apply(new
|
|
630
|
+
}), e.apply(new A(this.api.translate("Reorder product attributes")));
|
|
631
631
|
}
|
|
632
632
|
/**
|
|
633
633
|
* Builds HTML string with attributes ordered according to composition.
|
|
@@ -635,7 +635,7 @@ class Rt extends Q {
|
|
|
635
635
|
*/
|
|
636
636
|
_buildCompositionHtml(t, r) {
|
|
637
637
|
return r.reduce((e, o) => {
|
|
638
|
-
const s = t.querySelector(`${
|
|
638
|
+
const s = t.querySelector(`${S}[${y}="${o}"]`);
|
|
639
639
|
return s && "getOuterHTML" in s ? e + s.getOuterHTML() : e;
|
|
640
640
|
}, "");
|
|
641
641
|
}
|
|
@@ -645,14 +645,14 @@ class Rt extends Q {
|
|
|
645
645
|
_applyVisibilityToBlock(t, r) {
|
|
646
646
|
if (!this.currentNode)
|
|
647
647
|
return;
|
|
648
|
-
const e = this.currentNode.querySelectorAll(`${
|
|
648
|
+
const e = this.currentNode.querySelectorAll(`${S}[${y}="${t}"]`);
|
|
649
649
|
if (!(e != null && e.length))
|
|
650
650
|
return;
|
|
651
|
-
const o = r ? "1" : "0", s = r ? this.api.translate("visible") : this.api.translate("hidden"),
|
|
652
|
-
e.forEach((
|
|
653
|
-
const
|
|
654
|
-
|
|
655
|
-
}),
|
|
651
|
+
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();
|
|
652
|
+
e.forEach((c) => {
|
|
653
|
+
const a = ht(c), l = r ? a : "none";
|
|
654
|
+
n.modifyHtml(c).setStyle("display", l).setAttribute(I, o);
|
|
655
|
+
}), n.apply(new A(i));
|
|
656
656
|
}
|
|
657
657
|
// ========================================================================
|
|
658
658
|
// Utilities
|
|
@@ -673,7 +673,7 @@ class Rt extends Q {
|
|
|
673
673
|
return -1;
|
|
674
674
|
}
|
|
675
675
|
_getCurrentLayout() {
|
|
676
|
-
return this.store.recommendationConfigs.orientation ||
|
|
676
|
+
return this.store.recommendationConfigs.orientation || pt(this.currentNode);
|
|
677
677
|
}
|
|
678
678
|
/**
|
|
679
679
|
* Extracts background color properties from existing card elements.
|
|
@@ -685,18 +685,18 @@ class Rt extends Q {
|
|
|
685
685
|
var o;
|
|
686
686
|
const r = t.querySelector(".product-card-segment");
|
|
687
687
|
if (r && "getAttribute" in r) {
|
|
688
|
-
const
|
|
689
|
-
if (
|
|
690
|
-
const
|
|
691
|
-
return { bgStyle: `background-color: ${
|
|
688
|
+
const i = (r.getAttribute("style") || "").match(/background-color:\s*([^;]+)/);
|
|
689
|
+
if (i) {
|
|
690
|
+
const n = r.getAttribute("bgcolor") || "";
|
|
691
|
+
return { bgStyle: `background-color: ${i[1].trim()};`, bgAttr: n };
|
|
692
692
|
}
|
|
693
693
|
}
|
|
694
694
|
const e = (o = this.currentNode) == null ? void 0 : o.querySelector(".product-card-wrapper");
|
|
695
695
|
if (e && "getStyle" in e) {
|
|
696
696
|
const s = e.getStyle("background-color");
|
|
697
697
|
if (s && s !== "transparent") {
|
|
698
|
-
const
|
|
699
|
-
return { bgStyle: `background-color: ${s};`, bgAttr:
|
|
698
|
+
const i = "getAttribute" in e && e.getAttribute("bgcolor") || "";
|
|
699
|
+
return { bgStyle: `background-color: ${s};`, bgAttr: i };
|
|
700
700
|
}
|
|
701
701
|
}
|
|
702
702
|
return { bgStyle: "", bgAttr: "" };
|
|
@@ -724,9 +724,9 @@ class Rt extends Q {
|
|
|
724
724
|
* or when all available filters have already been added (no unused attributes left).
|
|
725
725
|
*/
|
|
726
726
|
_updateAddButtonState() {
|
|
727
|
-
const t = this._readCustomAttributesFromNode(), r = t.length >= g, e = new Set(t), o =
|
|
727
|
+
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));
|
|
728
728
|
this.api.setUIEAttribute(
|
|
729
|
-
|
|
729
|
+
x.ADD_ATTRIBUTE,
|
|
730
730
|
$.BUTTON.disabled,
|
|
731
731
|
r || s ? "true" : "false"
|
|
732
732
|
);
|
|
@@ -745,37 +745,50 @@ class Rt extends Q {
|
|
|
745
745
|
o !== r && (r = o, this._initializeComposition());
|
|
746
746
|
});
|
|
747
747
|
}
|
|
748
|
+
/**
|
|
749
|
+
* Returns filters eligible for the custom attribute dropdown,
|
|
750
|
+
* excluding default attributes already covered by built-in toggle items.
|
|
751
|
+
*/
|
|
752
|
+
_getAddableFilters() {
|
|
753
|
+
return Object.values(this.store.filterList).filter((t) => !(t.type === "defaultAttribute" && st.has(t.attributeName)));
|
|
754
|
+
}
|
|
748
755
|
/**
|
|
749
756
|
* Looks up the display name for an attribute from the store's filterList.
|
|
750
757
|
* Falls back to Title Case conversion of the snake_case attribute name.
|
|
751
758
|
*/
|
|
752
759
|
_getDisplayNameForAttribute(t) {
|
|
753
760
|
const r = Object.values(this.store.filterList).find((e) => e.attributeName === t);
|
|
754
|
-
return r ? r.displayName :
|
|
761
|
+
return r ? r.displayName : dt(t);
|
|
755
762
|
}
|
|
756
763
|
/**
|
|
757
764
|
* Resolves the display content for a custom attribute cell.
|
|
758
765
|
* Uses the real product value from the store when available, falls back to displayName.
|
|
759
766
|
*/
|
|
760
767
|
_resolveAttributeContent(t, r, e) {
|
|
761
|
-
var
|
|
762
|
-
const s = this.store.recommendationProducts[e],
|
|
763
|
-
return
|
|
764
|
-
}
|
|
765
|
-
_getGridCellHtml(t, r, e, o = "", s = "",
|
|
766
|
-
const
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
768
|
+
var n;
|
|
769
|
+
const s = this.store.recommendationProducts[e], i = mt(t, this.store.filterList) ? s == null ? void 0 : s[t] : (n = s == null ? void 0 : s.product_attributes) == null ? void 0 : n[t];
|
|
770
|
+
return typeof i == "string" ? i : typeof i == "number" ? String(i) : r;
|
|
771
|
+
}
|
|
772
|
+
_getGridCellHtml(t, r, e, o = "", s = "", i = "") {
|
|
773
|
+
const n = `${m}${t}`, c = F(at, [n], this.store.filterList), a = {
|
|
774
|
+
[t]: r,
|
|
775
|
+
product_attributes: { [t]: r }
|
|
776
|
+
};
|
|
777
|
+
let l = c[n](a);
|
|
778
|
+
return l = l.replace("<td", `<td width="${e}%"`), i && (l = l.replace(
|
|
779
|
+
`padding: ${ct}`,
|
|
780
|
+
`padding: ${i}`
|
|
771
781
|
)), o && (l = l.replace(/style="table-layout: fixed;"/, `style="table-layout: fixed; ${o}"`)), s && (l = l.replace(/border="0"/, `border="0" bgcolor="${s}"`)), l;
|
|
772
782
|
}
|
|
773
783
|
_getListRowHtml(t, r, e) {
|
|
774
|
-
const o =
|
|
775
|
-
|
|
784
|
+
const o = F(ut, [e], this.store.filterList), s = {
|
|
785
|
+
[t]: r,
|
|
786
|
+
product_attributes: { [t]: r }
|
|
787
|
+
}, n = o[e](s).replace(/<tr>/, "").replace(/<\/tr>/, "");
|
|
788
|
+
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${I}="1">${n}</tr>`;
|
|
776
789
|
}
|
|
777
790
|
}
|
|
778
791
|
export {
|
|
779
|
-
|
|
780
|
-
|
|
792
|
+
_t as COMPOSITION_CONTROL_BLOCK_ID,
|
|
793
|
+
Nt as RecommendationCardCompositionControl
|
|
781
794
|
};
|