@useinsider/guido 3.7.0-beta.24bdfa3 → 3.7.0-beta.340a6d3
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 +66 -70
- package/dist/composables/usePreviewMode.js +14 -15
- package/dist/config/compiler/utils/recommendationCompilerUtils.js +82 -90
- package/dist/config/migrator/recommendation/htmlBuilder.js +58 -59
- package/dist/config/migrator/recommendation/settingsMapper.js +33 -38
- package/dist/extensions/Blocks/Recommendation/block.js +43 -59
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +32 -41
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +313 -377
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +72 -84
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +66 -68
- package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +7 -21
- package/dist/extensions/Blocks/Recommendation/recommendation.css.js +4 -64
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +5 -7
- package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +72 -101
- package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +30 -31
- package/dist/extensions/Blocks/Recommendation/templates/index.js +7 -9
- package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +59 -74
- package/dist/extensions/Blocks/Recommendation/templates/list/template.js +21 -21
- package/dist/extensions/Blocks/Recommendation/templates/utils.js +57 -88
- package/dist/src/@types/config/schemas.d.ts +0 -16
- package/dist/src/composables/useConfig.d.ts +0 -4
- package/dist/src/config/migrator/recommendation/settingsMapper.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/block.d.ts +0 -10
- package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +3 -29
- package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +1 -3
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +0 -2
- package/dist/src/extensions/Blocks/Recommendation/templates/grid/elementRenderer.d.ts +0 -16
- package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
- package/dist/src/extensions/Blocks/Recommendation/templates/list/elementRenderer.d.ts +0 -13
- package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +2 -3
- package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +1 -33
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +0 -15
- package/dist/src/stores/config.d.ts +0 -36
- package/package.json +1 -1
- package/dist/composables/useRecommendationPreview.js +0 -100
- package/dist/extensions/Blocks/Recommendation/controls/main/pricePlacement.js +0 -133
- package/dist/src/composables/useRecommendationPreview.d.ts +0 -10
- package/dist/src/composables/useRecommendationPreview.test.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/pricePlacement.d.ts +0 -59
|
@@ -1,95 +1,95 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { UIElementType as
|
|
5
|
-
import { CommonControl as
|
|
6
|
-
import { ATTR_PRODUCT_IMAGE as
|
|
7
|
-
import { DEFAULT_COMPOSITION as
|
|
8
|
-
import { RecommendationConfigService as
|
|
1
|
+
var Q = Object.defineProperty;
|
|
2
|
+
var Z = (p, g, t) => g in p ? Q(p, g, { enumerable: !0, configurable: !0, writable: !0, value: t }) : p[g] = t;
|
|
3
|
+
var S = (p, g, t) => Z(p, typeof g != "symbol" ? g + "" : g, t);
|
|
4
|
+
import { UIElementType as f, UEAttr as v, ModificationDescription as C } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
|
+
import { CommonControl as tt } from "../../../common-control.js";
|
|
6
|
+
import { ATTR_PRODUCT_IMAGE as H, ATTR_PRODUCT_NAME as et, ATTR_PRODUCT_PRICE as rt, ATTR_PRODUCT_OLD_PRICE as ot, ATTR_PRODUCT_OMNIBUS_PRICE as st, ATTR_PRODUCT_OMNIBUS_DISCOUNT as it, ATTR_PRODUCT_BUTTON as U, ATTR_DATA_CUSTOM_ATTRIBUTES as F, ATTR_CUSTOM_PREFIX as d, BUILT_IN_DEFAULT_ATTRIBUTES as nt } from "../../constants/selectors.js";
|
|
7
|
+
import { DEFAULT_COMPOSITION as P, DEFAULT_VISIBILITY as w } from "../../constants/defaultConfig.js";
|
|
8
|
+
import { RecommendationConfigService as $ } from "../../services/configService.js";
|
|
9
9
|
import { useRecommendationExtensionStore as lt } from "../../store/recommendation.js";
|
|
10
|
-
import { ATTRIBUTE_CELL_CLASS as at, gridElementRenderer as ct, DEFAULT_CELL_PADDING as
|
|
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 {
|
|
13
|
-
import { getTableDisplayValue as
|
|
14
|
-
import {
|
|
15
|
-
const
|
|
12
|
+
import { toDisplayName as ht, isDefaultAttribute as pt, toDisplayableAttributeValue as gt, buildElementRenderer as M } from "../../templates/utils.js";
|
|
13
|
+
import { getTableDisplayValue as ft } from "../../utils/tagName.js";
|
|
14
|
+
import { getCurrentLayout as _t } from "../main/utils.js";
|
|
15
|
+
const bt = "ui-elements-recommendation-card-composition", A = ".recommendation-attribute-row", L = ".product-card-wrapper > tbody", V = ".product-info-cell > table > tbody", x = "data-card-composition", y = "data-attribute-type", N = "data-visibility", j = {
|
|
16
16
|
ADD_ATTRIBUTE: "addAttribute"
|
|
17
|
-
},
|
|
18
|
-
{ key:
|
|
19
|
-
{ key:
|
|
20
|
-
{ key:
|
|
21
|
-
{ key:
|
|
22
|
-
{ key:
|
|
23
|
-
{ key:
|
|
17
|
+
}, _ = 5, R = "reorderIcon_", h = [
|
|
18
|
+
{ key: H, label: "Product Image" },
|
|
19
|
+
{ key: et, label: "Product Name" },
|
|
20
|
+
{ key: rt, label: "Product Price" },
|
|
21
|
+
{ key: ot, label: "Product Original Price" },
|
|
22
|
+
{ key: st, label: "Omnibus Price" },
|
|
23
|
+
{ key: it, label: "Omnibus Discount" },
|
|
24
24
|
{ key: U, label: "Product Button" }
|
|
25
|
-
],
|
|
26
|
-
class
|
|
25
|
+
], yt = new Set(h.map((p) => p.key)), T = "customAttr_", E = "deleteAttr_";
|
|
26
|
+
class Ht extends tt {
|
|
27
27
|
constructor() {
|
|
28
28
|
super(...arguments);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
S(this, "store", lt());
|
|
30
|
+
S(this, "unsubscribeStore", null);
|
|
31
|
+
S(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
|
+
S(this, "reorderInProgress", !1);
|
|
37
37
|
}
|
|
38
38
|
getId() {
|
|
39
|
-
return
|
|
39
|
+
return bt;
|
|
40
40
|
}
|
|
41
41
|
// ========================================================================
|
|
42
42
|
// Lifecycle
|
|
43
43
|
// ========================================================================
|
|
44
44
|
getTemplate() {
|
|
45
|
-
const t =
|
|
46
|
-
<div data-toggle-key="${
|
|
47
|
-
${this._GuToggle(`visibility_${
|
|
45
|
+
const t = h.map((l) => `
|
|
46
|
+
<div data-toggle-key="${l.key}" style="display: none;">
|
|
47
|
+
${this._GuToggle(`visibility_${l.key}`)}
|
|
48
48
|
</div>
|
|
49
49
|
`).join(""), r = Array.from(
|
|
50
|
-
{ length:
|
|
51
|
-
(
|
|
52
|
-
<div data-custom-select-key="${
|
|
50
|
+
{ length: _ },
|
|
51
|
+
(l, u) => `
|
|
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
|
})}
|
|
58
58
|
</div>
|
|
59
59
|
`
|
|
60
|
-
).join(""), e =
|
|
60
|
+
).join(""), e = h.length + _, o = Array.from(
|
|
61
61
|
{ length: e },
|
|
62
|
-
(
|
|
63
|
-
<div data-reorder-icon-key="${
|
|
64
|
-
<${
|
|
62
|
+
(l, u) => `
|
|
63
|
+
<div data-reorder-icon-key="${R}${u}" style="display: none;">
|
|
64
|
+
<${f.BUTTON}
|
|
65
65
|
class="drag-handle-btn flat-inline flat-white"
|
|
66
|
-
${
|
|
66
|
+
${v.BUTTON.name}="${R}${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
|
-
).join(""),
|
|
76
|
-
{ length:
|
|
77
|
-
(
|
|
78
|
-
<div data-custom-delete-key="${
|
|
79
|
-
<${
|
|
75
|
+
).join(""), s = Array.from(
|
|
76
|
+
{ length: _ },
|
|
77
|
+
(l, u) => `
|
|
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
|
-
${
|
|
81
|
+
${v.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
|
-
), c = this.api.translate("For more information, you can"),
|
|
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">
|
|
@@ -97,7 +97,7 @@ class Ut extends rt {
|
|
|
97
97
|
${n}
|
|
98
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
|
|
|
@@ -110,17 +110,17 @@ class Ut extends rt {
|
|
|
110
110
|
</div>
|
|
111
111
|
|
|
112
112
|
<div class="custom-delete-store" style="display: none;">
|
|
113
|
-
${
|
|
113
|
+
${s}
|
|
114
114
|
</div>
|
|
115
115
|
|
|
116
116
|
<div class="reorder-icon-store" style="display: none;">
|
|
117
|
-
${
|
|
117
|
+
${o}
|
|
118
118
|
</div>
|
|
119
119
|
|
|
120
120
|
<div class="orderable-list" data-composition-list></div>
|
|
121
121
|
|
|
122
122
|
${this._GuButton({
|
|
123
|
-
name:
|
|
123
|
+
name: j.ADD_ATTRIBUTE,
|
|
124
124
|
label: this.api.translate("Add Attribute"),
|
|
125
125
|
id: "guido__btn-add-attribute"
|
|
126
126
|
})}
|
|
@@ -140,19 +140,19 @@ class Ut extends rt {
|
|
|
140
140
|
// Initialization
|
|
141
141
|
// ========================================================================
|
|
142
142
|
_initializeComposition() {
|
|
143
|
-
const t = this._readCompositionFromNode(), r = this._readCustomAttributesFromNode(), e = this._readVisibilityFromRows(),
|
|
144
|
-
this.api.updateValues(
|
|
143
|
+
const t = this._readCompositionFromNode(), r = this._readCustomAttributesFromNode(), e = this._readVisibilityFromRows(), o = this._renderOrderableItems(t, r), s = this._buildVisibilityValues(e);
|
|
144
|
+
this.api.updateValues(s), o && this._initializeCustomSelects(r), this._updateAddButtonState();
|
|
145
145
|
}
|
|
146
146
|
_registerValueChangeListeners() {
|
|
147
|
-
|
|
147
|
+
h.forEach((t) => {
|
|
148
148
|
this.api.onValueChanged(`visibility_${t.key}`, (r) => {
|
|
149
149
|
this._applyVisibilityToBlock(t.key, r);
|
|
150
150
|
});
|
|
151
151
|
});
|
|
152
|
-
for (let t = 0; t <
|
|
153
|
-
const r = `${
|
|
154
|
-
this.api.onValueChanged(r, (
|
|
155
|
-
this._onCustomAttributeChanged(e,
|
|
152
|
+
for (let t = 0; t < _; t++) {
|
|
153
|
+
const r = `${T}${t}`, e = t;
|
|
154
|
+
this.api.onValueChanged(r, (o) => {
|
|
155
|
+
this._onCustomAttributeChanged(e, o);
|
|
156
156
|
});
|
|
157
157
|
}
|
|
158
158
|
}
|
|
@@ -161,50 +161,56 @@ class Ut extends rt {
|
|
|
161
161
|
// ========================================================================
|
|
162
162
|
_readCompositionFromNode() {
|
|
163
163
|
if (!this.currentNode || !("getAttribute" in this.currentNode))
|
|
164
|
-
return [...
|
|
165
|
-
const t = this.currentNode.getAttribute(
|
|
166
|
-
|
|
164
|
+
return [...P];
|
|
165
|
+
const t = this.currentNode.getAttribute(x);
|
|
166
|
+
if (t)
|
|
167
|
+
return t.split(",").filter(Boolean);
|
|
168
|
+
const { composition: r } = $.getConfig(this.currentNode);
|
|
169
|
+
return r != null && r.length ? [...r] : [...P];
|
|
167
170
|
}
|
|
168
171
|
_readCustomAttributesFromNode() {
|
|
169
172
|
if (!this.currentNode || !("getAttribute" in this.currentNode))
|
|
170
173
|
return [];
|
|
171
174
|
const t = this.currentNode.getAttribute(F);
|
|
172
|
-
if (
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
175
|
+
if (t)
|
|
176
|
+
try {
|
|
177
|
+
return JSON.parse(t);
|
|
178
|
+
} catch {
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
181
|
+
return this._readCompositionFromNode().filter((r) => r.startsWith(d)).map((r) => r.substring(d.length));
|
|
179
182
|
}
|
|
180
183
|
_readVisibilityFromRows() {
|
|
181
184
|
if (!this.currentNode)
|
|
182
185
|
return this._getDefaultVisibilities();
|
|
183
|
-
const t = Array.from(this.currentNode.querySelectorAll(
|
|
184
|
-
|
|
186
|
+
const t = Array.from(this.currentNode.querySelectorAll(A)), r = this._extractVisibilityFromRows(t);
|
|
187
|
+
if (Object.keys(r).length > 0)
|
|
188
|
+
return this._mergeWithDefaults(r);
|
|
189
|
+
const e = $.getConfig(this.currentNode).visibility;
|
|
190
|
+
return this._mergeWithDefaults({ ...e });
|
|
185
191
|
}
|
|
186
192
|
_getDefaultVisibilities() {
|
|
187
|
-
return { ...
|
|
193
|
+
return { ...w };
|
|
188
194
|
}
|
|
189
195
|
_extractVisibilityFromRows(t) {
|
|
190
196
|
const r = {};
|
|
191
197
|
return t.forEach((e) => {
|
|
192
198
|
if (!("getAttribute" in e))
|
|
193
199
|
return;
|
|
194
|
-
const
|
|
195
|
-
|
|
200
|
+
const o = e.getAttribute(y), s = e.getAttribute(N);
|
|
201
|
+
o && s !== null && (r[o] = this._parseVisibilityValue(s));
|
|
196
202
|
}), r;
|
|
197
203
|
}
|
|
198
204
|
_parseVisibilityValue(t) {
|
|
199
205
|
return t === "1" || t === "true";
|
|
200
206
|
}
|
|
201
207
|
_mergeWithDefaults(t) {
|
|
202
|
-
return Object.entries(
|
|
208
|
+
return Object.entries(w).forEach(([r, e]) => {
|
|
203
209
|
r in t || (t[r] = e);
|
|
204
210
|
}), t;
|
|
205
211
|
}
|
|
206
212
|
_buildVisibilityValues(t) {
|
|
207
|
-
return
|
|
213
|
+
return h.reduce((r, e) => (r[`visibility_${e.key}`] = t[e.key] ?? !0, r), {});
|
|
208
214
|
}
|
|
209
215
|
// ========================================================================
|
|
210
216
|
// UI Rendering (Orderable List)
|
|
@@ -218,30 +224,24 @@ class Ut extends rt {
|
|
|
218
224
|
const e = this._getControlContainer();
|
|
219
225
|
if (!e)
|
|
220
226
|
return !1;
|
|
221
|
-
const
|
|
222
|
-
if (!
|
|
223
|
-
return !1;
|
|
224
|
-
const o = !P.getConfig(this.currentNode).priceMovedToNextLine;
|
|
225
|
-
if (!(i.dataset.inlinePrices !== String(o)) && this._tryReorderInPlace(i, t))
|
|
227
|
+
const o = e.querySelector("[data-composition-list]");
|
|
228
|
+
if (!o || this._tryReorderInPlace(o, t))
|
|
226
229
|
return !1;
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
return
|
|
233
|
-
if (At.has(u)) {
|
|
234
|
-
const h = m.find((C) => C.key === u);
|
|
235
|
-
return this._createBuiltInItemHtml(h, a++);
|
|
230
|
+
const s = new Set(r);
|
|
231
|
+
let i = 0, n = 0;
|
|
232
|
+
const c = t.map((a) => {
|
|
233
|
+
if (yt.has(a)) {
|
|
234
|
+
const l = h.find((u) => u.key === a);
|
|
235
|
+
return this._createBuiltInItemHtml(l, n++);
|
|
236
236
|
}
|
|
237
|
-
if (
|
|
238
|
-
const
|
|
239
|
-
if (
|
|
240
|
-
return this._createCustomItemHtml(
|
|
237
|
+
if (a.startsWith(d)) {
|
|
238
|
+
const l = a.substring(d.length);
|
|
239
|
+
if (s.has(l))
|
|
240
|
+
return this._createCustomItemHtml(a, i++, n++);
|
|
241
241
|
}
|
|
242
242
|
return "";
|
|
243
243
|
}).join("");
|
|
244
|
-
return this._rescueTogglesToStore(e), this._rescueSelectsToStore(e), this._rescueDeleteButtonsToStore(e), this._rescueReorderIconsToStore(e),
|
|
244
|
+
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;
|
|
245
245
|
}
|
|
246
246
|
/**
|
|
247
247
|
* Attempts to reorder existing orderable-item elements to match the composition order.
|
|
@@ -253,27 +253,27 @@ class Ut extends rt {
|
|
|
253
253
|
const e = Array.from(t.querySelectorAll(".orderable-item"));
|
|
254
254
|
if (e.length !== r.length)
|
|
255
255
|
return !1;
|
|
256
|
-
const
|
|
257
|
-
if (
|
|
256
|
+
const o = e.map((a) => a.dataset.key).filter(Boolean);
|
|
257
|
+
if (o.length !== r.length)
|
|
258
258
|
return !1;
|
|
259
|
-
const
|
|
260
|
-
if (
|
|
259
|
+
const s = [...o].sort().join(","), i = [...r].sort().join(",");
|
|
260
|
+
if (s !== i || r.some((a) => a.startsWith(d)))
|
|
261
261
|
return !1;
|
|
262
262
|
const n = /* @__PURE__ */ new Map();
|
|
263
|
-
e.forEach((
|
|
264
|
-
const { key:
|
|
265
|
-
if (
|
|
266
|
-
const
|
|
267
|
-
|
|
263
|
+
e.forEach((a) => {
|
|
264
|
+
const { key: l } = a.dataset;
|
|
265
|
+
if (l) {
|
|
266
|
+
const u = n.get(l) || [];
|
|
267
|
+
u.push(a), n.set(l, u);
|
|
268
268
|
}
|
|
269
269
|
});
|
|
270
270
|
const c = /* @__PURE__ */ new Map();
|
|
271
|
-
return r.forEach((
|
|
272
|
-
const
|
|
273
|
-
if (!
|
|
271
|
+
return r.forEach((a) => {
|
|
272
|
+
const l = n.get(a);
|
|
273
|
+
if (!l)
|
|
274
274
|
return;
|
|
275
|
-
const
|
|
276
|
-
c.set(
|
|
275
|
+
const u = c.get(a) || 0;
|
|
276
|
+
c.set(a, u + 1), l[u] && t.appendChild(l[u]);
|
|
277
277
|
}), !0;
|
|
278
278
|
}
|
|
279
279
|
_createBuiltInItemHtml(t, r) {
|
|
@@ -285,33 +285,6 @@ class Ut extends rt {
|
|
|
285
285
|
</div>
|
|
286
286
|
`;
|
|
287
287
|
}
|
|
288
|
-
/**
|
|
289
|
-
* Inline mode: the merged "Product Prices" group item. It moves as a unit in
|
|
290
|
-
* the main list (both keys stay adjacent) and contains a nested 2-item drag
|
|
291
|
-
* to reorder Product Price ↔ Product Original Price — which flips the inline
|
|
292
|
-
* render order via `resolveInlinePriceOrder`. The group keeps a single
|
|
293
|
-
* visibility toggle (`data-action-for="productPrice"`). Nested sub-items use a
|
|
294
|
-
* plain drag handle (no UE button → untouched by the reorder-icon rescue).
|
|
295
|
-
*/
|
|
296
|
-
_createPriceGroupItemHtml(t, r) {
|
|
297
|
-
var n, c;
|
|
298
|
-
const e = ((n = m.find((l) => l.key === S)) == null ? void 0 : n.label) ?? "Product Price", i = ((c = m.find((l) => l.key === v)) == null ? void 0 : c.label) ?? "Product Original Price", o = (l, a) => `
|
|
299
|
-
<div class="price-suborderable-item" draggable="true" data-subkey="${l}">
|
|
300
|
-
<span class="sub-drag-handle">${Ct}</span>
|
|
301
|
-
<span class="item-label">${this.api.translate(a)}</span>
|
|
302
|
-
</div>`, s = r ? o(v, i) + o(S, e) : o(S, e) + o(v, i);
|
|
303
|
-
return `
|
|
304
|
-
<div class="orderable-item price-group-item" draggable="true"
|
|
305
|
-
data-key="${S}" data-group="prices">
|
|
306
|
-
<div class="price-group-header">
|
|
307
|
-
<span class="drag-handle" data-reorder-icon-slot="${t}"></span>
|
|
308
|
-
<span class="item-label">${this.api.translate("Product Prices")}</span>
|
|
309
|
-
<div class="item-action" data-action-for="${S}"></div>
|
|
310
|
-
</div>
|
|
311
|
-
<div class="price-suborderable-list">${s}</div>
|
|
312
|
-
</div>
|
|
313
|
-
`;
|
|
314
|
-
}
|
|
315
288
|
_createCustomItemHtml(t, r, e) {
|
|
316
289
|
return `
|
|
317
290
|
<div class="orderable-item" draggable="true"
|
|
@@ -332,10 +305,10 @@ class Ut extends rt {
|
|
|
332
305
|
_getSelectOptions(t, r = []) {
|
|
333
306
|
const e = this._getAddableFilters();
|
|
334
307
|
if (e.length > 0) {
|
|
335
|
-
const
|
|
336
|
-
return
|
|
337
|
-
text:
|
|
338
|
-
value:
|
|
308
|
+
const s = new Set(r);
|
|
309
|
+
return s.delete(t), e.filter((i) => !s.has(i.attributeName)).map((i) => ({
|
|
310
|
+
text: i.displayName,
|
|
311
|
+
value: i.attributeName
|
|
339
312
|
}));
|
|
340
313
|
}
|
|
341
314
|
return [{ text: this._getDisplayNameForAttribute(t), value: t }];
|
|
@@ -348,8 +321,8 @@ class Ut extends rt {
|
|
|
348
321
|
_initializeCustomSelects(t) {
|
|
349
322
|
t.length !== 0 && setTimeout(() => {
|
|
350
323
|
t.forEach((r, e) => {
|
|
351
|
-
const
|
|
352
|
-
this.api.setUIEAttribute(
|
|
324
|
+
const o = `${T}${e}`, s = this._getSelectOptions(r, t);
|
|
325
|
+
this.api.setUIEAttribute(o, v.SELECTPICKER.items, s), this.api.updateValues({ [o]: r });
|
|
353
326
|
});
|
|
354
327
|
}, 0);
|
|
355
328
|
}
|
|
@@ -358,11 +331,11 @@ class Ut extends rt {
|
|
|
358
331
|
* Stripo initializes toggles at template parse time; moving the DOM node preserves bindings.
|
|
359
332
|
*/
|
|
360
333
|
_moveTogglesIntoItems(t) {
|
|
361
|
-
|
|
362
|
-
const e = t.querySelector(`[data-toggle-key="${r.key}"]`),
|
|
363
|
-
if (e &&
|
|
364
|
-
const
|
|
365
|
-
|
|
334
|
+
h.forEach((r) => {
|
|
335
|
+
const e = t.querySelector(`[data-toggle-key="${r.key}"]`), o = t.querySelector(`[data-action-for="${r.key}"]`);
|
|
336
|
+
if (e && o) {
|
|
337
|
+
const s = e.querySelector("ue-switcher");
|
|
338
|
+
s && o.appendChild(s);
|
|
366
339
|
}
|
|
367
340
|
});
|
|
368
341
|
}
|
|
@@ -372,10 +345,10 @@ class Ut extends rt {
|
|
|
372
345
|
*/
|
|
373
346
|
_moveSelectsIntoItems(t, r) {
|
|
374
347
|
for (let e = 0; e < r; e++) {
|
|
375
|
-
const
|
|
376
|
-
if (
|
|
377
|
-
const n =
|
|
378
|
-
n &&
|
|
348
|
+
const o = `${T}${e}`, s = t.querySelector(`[data-custom-select-key="${o}"]`), i = t.querySelector(`[data-custom-select-slot="${e}"]`);
|
|
349
|
+
if (s && i) {
|
|
350
|
+
const n = s.querySelector("ue-select");
|
|
351
|
+
n && i.appendChild(n);
|
|
379
352
|
}
|
|
380
353
|
}
|
|
381
354
|
}
|
|
@@ -386,11 +359,11 @@ class Ut extends rt {
|
|
|
386
359
|
* previously-moved toggles, making them permanently lost.
|
|
387
360
|
*/
|
|
388
361
|
_rescueTogglesToStore(t) {
|
|
389
|
-
|
|
390
|
-
const e = t.querySelector(`[data-toggle-key="${r.key}"]`),
|
|
391
|
-
if (
|
|
392
|
-
const
|
|
393
|
-
|
|
362
|
+
h.forEach((r) => {
|
|
363
|
+
const e = t.querySelector(`[data-toggle-key="${r.key}"]`), o = t.querySelector(`[data-action-for="${r.key}"]`);
|
|
364
|
+
if (o) {
|
|
365
|
+
const s = o.querySelector("ue-switcher");
|
|
366
|
+
s && e && e.appendChild(s);
|
|
394
367
|
}
|
|
395
368
|
});
|
|
396
369
|
}
|
|
@@ -399,11 +372,11 @@ class Ut extends rt {
|
|
|
399
372
|
* Same rescue pattern as _rescueTogglesToStore — prevents innerHTML from destroying them.
|
|
400
373
|
*/
|
|
401
374
|
_rescueSelectsToStore(t) {
|
|
402
|
-
for (let r = 0; r <
|
|
403
|
-
const e = `${
|
|
404
|
-
if (
|
|
405
|
-
const
|
|
406
|
-
|
|
375
|
+
for (let r = 0; r < _; r++) {
|
|
376
|
+
const e = `${T}${r}`, o = t.querySelector(`[data-custom-select-key="${e}"]`), s = t.querySelector(`[data-custom-select-slot="${r}"]`);
|
|
377
|
+
if (s) {
|
|
378
|
+
const i = s.querySelector("ue-select");
|
|
379
|
+
i && o && o.appendChild(i);
|
|
407
380
|
}
|
|
408
381
|
}
|
|
409
382
|
}
|
|
@@ -413,10 +386,10 @@ class Ut extends rt {
|
|
|
413
386
|
*/
|
|
414
387
|
_moveDeleteButtonsIntoItems(t, r) {
|
|
415
388
|
for (let e = 0; e < r; e++) {
|
|
416
|
-
const
|
|
417
|
-
if (
|
|
418
|
-
const n =
|
|
419
|
-
n &&
|
|
389
|
+
const o = `${E}${e}`, s = t.querySelector(`[data-custom-delete-key="${o}"]`), i = t.querySelector(`[data-custom-delete-slot="${e}"]`);
|
|
390
|
+
if (s && i) {
|
|
391
|
+
const n = s.querySelector("ue-button");
|
|
392
|
+
n && i.appendChild(n);
|
|
420
393
|
}
|
|
421
394
|
}
|
|
422
395
|
}
|
|
@@ -425,11 +398,11 @@ class Ut extends rt {
|
|
|
425
398
|
* Same rescue pattern as _rescueSelectsToStore — prevents innerHTML from destroying them.
|
|
426
399
|
*/
|
|
427
400
|
_rescueDeleteButtonsToStore(t) {
|
|
428
|
-
for (let r = 0; r <
|
|
429
|
-
const e = `${
|
|
430
|
-
if (
|
|
431
|
-
const
|
|
432
|
-
|
|
401
|
+
for (let r = 0; r < _; r++) {
|
|
402
|
+
const e = `${E}${r}`, o = t.querySelector(`[data-custom-delete-key="${e}"]`), s = t.querySelector(`[data-custom-delete-slot="${r}"]`);
|
|
403
|
+
if (s) {
|
|
404
|
+
const i = s.querySelector("ue-button");
|
|
405
|
+
i && o && o.appendChild(i);
|
|
433
406
|
}
|
|
434
407
|
}
|
|
435
408
|
}
|
|
@@ -439,10 +412,10 @@ class Ut extends rt {
|
|
|
439
412
|
*/
|
|
440
413
|
_moveReorderIconsIntoItems(t, r) {
|
|
441
414
|
for (let e = 0; e < r; e++) {
|
|
442
|
-
const
|
|
443
|
-
if (
|
|
444
|
-
const n =
|
|
445
|
-
n &&
|
|
415
|
+
const o = `${R}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
|
|
416
|
+
if (s && i) {
|
|
417
|
+
const n = s.querySelector("ue-button");
|
|
418
|
+
n && i.appendChild(n);
|
|
446
419
|
}
|
|
447
420
|
}
|
|
448
421
|
}
|
|
@@ -451,12 +424,12 @@ class Ut extends rt {
|
|
|
451
424
|
* Same rescue pattern as _rescueDeleteButtonsToStore — prevents innerHTML from destroying them.
|
|
452
425
|
*/
|
|
453
426
|
_rescueReorderIconsToStore(t) {
|
|
454
|
-
const r =
|
|
427
|
+
const r = h.length + _;
|
|
455
428
|
for (let e = 0; e < r; e++) {
|
|
456
|
-
const
|
|
457
|
-
if (
|
|
458
|
-
const n =
|
|
459
|
-
n &&
|
|
429
|
+
const o = `${R}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
|
|
430
|
+
if (i) {
|
|
431
|
+
const n = i.querySelector("ue-button");
|
|
432
|
+
n && s && s.appendChild(n);
|
|
460
433
|
}
|
|
461
434
|
}
|
|
462
435
|
}
|
|
@@ -468,83 +441,41 @@ class Ut extends rt {
|
|
|
468
441
|
const { signal: t } = this.eventController, r = this._getControlContainer();
|
|
469
442
|
if (!r)
|
|
470
443
|
return;
|
|
471
|
-
const e = r.querySelector("[data-composition-list]"),
|
|
472
|
-
e && (this._setupDragAndDrop(e, t), this._setupDeleteHandler(e, t)),
|
|
473
|
-
const
|
|
474
|
-
|
|
444
|
+
const e = r.querySelector("[data-composition-list]"), o = r.querySelector("#guido__btn-add-attribute");
|
|
445
|
+
e && (this._setupDragAndDrop(e, t), this._setupDeleteHandler(e, t)), o && o.addEventListener("click", () => {
|
|
446
|
+
const s = new Set(this._readCustomAttributesFromNode()), i = this._getAddableFilters().find((n) => !s.has(n.attributeName));
|
|
447
|
+
i && this._onAddAttribute(i.attributeName, i.displayName);
|
|
475
448
|
}, { signal: t });
|
|
476
449
|
}
|
|
477
|
-
/**
|
|
478
|
-
* Builds the composition key order from the orderable list, expanding the
|
|
479
|
-
* inline "Product Prices" group into its two sub-keys (in nested DOM order)
|
|
480
|
-
* so both price keys stay adjacent and in the user-chosen order.
|
|
481
|
-
*/
|
|
482
|
-
_extractCompositionOrder(t) {
|
|
483
|
-
const r = [];
|
|
484
|
-
return t.querySelectorAll(".orderable-item").forEach((e) => {
|
|
485
|
-
const i = e;
|
|
486
|
-
i.dataset.group === "prices" ? i.querySelectorAll(".price-suborderable-item").forEach((o) => {
|
|
487
|
-
const s = o.dataset.subkey;
|
|
488
|
-
s && r.push(s);
|
|
489
|
-
}) : i.dataset.key && r.push(i.dataset.key);
|
|
490
|
-
}), r;
|
|
491
|
-
}
|
|
492
450
|
_setupDragAndDrop(t, r) {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
itemSelector: ".price-suborderable-item",
|
|
499
|
-
getDropParent: (e) => e.parentElement
|
|
500
|
-
});
|
|
501
|
-
}
|
|
502
|
-
/**
|
|
503
|
-
* Wires drag/drop reordering for one item level on the shared list. Both the
|
|
504
|
-
* top-level items and the nested price sub-items use this; they never fight
|
|
505
|
-
* because each only sets its `dragged` ref when its own `itemSelector` matches
|
|
506
|
-
* at dragstart (and the top-level one additionally ignores drags originating
|
|
507
|
-
* inside `ignoreSelector`). Every drop re-reads the full composition via
|
|
508
|
-
* `_extractCompositionOrder`, so both levels commit through `_onReorder`
|
|
509
|
-
* identically.
|
|
510
|
-
*/
|
|
511
|
-
_registerDragHandlers(t, r, e) {
|
|
512
|
-
let i = null, o = null;
|
|
513
|
-
const s = (n) => n.target.closest(e.itemSelector);
|
|
514
|
-
t.addEventListener("dragstart", (n) => {
|
|
515
|
-
var a;
|
|
516
|
-
const c = n.target;
|
|
517
|
-
if (e.ignoreSelector && c.closest(e.ignoreSelector))
|
|
518
|
-
return;
|
|
519
|
-
const l = s(n);
|
|
520
|
-
l && (i = l, l.classList.add("dragging"), (a = n.dataTransfer) == null || a.setData("text/plain", l.dataset.key ?? l.dataset.subkey ?? ""));
|
|
451
|
+
let e = null, o = null;
|
|
452
|
+
t.addEventListener("dragstart", (s) => {
|
|
453
|
+
var c;
|
|
454
|
+
const n = s.target.closest(".orderable-item");
|
|
455
|
+
n && (e = n, n.classList.add("dragging"), (c = s.dataTransfer) == null || c.setData("text/plain", n.dataset.key || ""));
|
|
521
456
|
}, { signal: r }), t.addEventListener("dragend", () => {
|
|
522
|
-
|
|
523
|
-
}, { signal: r }), t.addEventListener("dragover", (
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
457
|
+
e && e.classList.remove("dragging"), e = null, o == null || o.classList.remove("drag-over"), o = null;
|
|
458
|
+
}, { signal: r }), t.addEventListener("dragover", (s) => {
|
|
459
|
+
s.preventDefault();
|
|
460
|
+
const n = s.target.closest(".orderable-item"), c = n && n !== e ? n : null;
|
|
461
|
+
c !== o && (o == null || o.classList.remove("drag-over"), o = c, o == null || o.classList.add("drag-over"));
|
|
462
|
+
}, { signal: r }), t.addEventListener("drop", (s) => {
|
|
463
|
+
s.preventDefault();
|
|
464
|
+
const n = s.target.closest(".orderable-item");
|
|
465
|
+
if (!n || !e || n === e)
|
|
528
466
|
return;
|
|
529
|
-
n.
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
var d;
|
|
534
|
-
const c = i && s(n);
|
|
535
|
-
if (!i || !c || c === i)
|
|
536
|
-
return;
|
|
537
|
-
n.preventDefault();
|
|
538
|
-
const l = c.getBoundingClientRect(), a = n.clientY < l.top + l.height / 2;
|
|
539
|
-
(d = e.getDropParent(c)) == null || d.insertBefore(i, a ? c : c.nextSibling), o == null || o.classList.remove("drag-over"), i.classList.remove("dragging"), i = null, o = null, this._onReorder(this._extractCompositionOrder(t));
|
|
467
|
+
const c = n.getBoundingClientRect(), a = c.top + c.height / 2;
|
|
468
|
+
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");
|
|
469
|
+
const u = t.querySelectorAll(".orderable-item"), m = Array.from(u).map((b) => b.dataset.key).filter(Boolean);
|
|
470
|
+
this._onReorder(m), e = null;
|
|
540
471
|
}, { signal: r });
|
|
541
472
|
}
|
|
542
473
|
_setupDeleteHandler(t, r) {
|
|
543
474
|
t.addEventListener("click", (e) => {
|
|
544
|
-
const
|
|
545
|
-
if (!
|
|
475
|
+
const s = e.target.closest(".custom-attr-delete");
|
|
476
|
+
if (!s)
|
|
546
477
|
return;
|
|
547
|
-
const
|
|
478
|
+
const i = s.closest("[data-custom-index]"), n = i == null ? void 0 : i.dataset.customIndex;
|
|
548
479
|
n !== void 0 && this._onDeleteCustomAttribute(Number(n));
|
|
549
480
|
}, { signal: r });
|
|
550
481
|
}
|
|
@@ -552,10 +483,10 @@ class Ut extends rt {
|
|
|
552
483
|
// Actions (Add, Delete, Reorder)
|
|
553
484
|
// ========================================================================
|
|
554
485
|
_onAddAttribute(t, r) {
|
|
555
|
-
const e = `${
|
|
556
|
-
|
|
557
|
-
const
|
|
558
|
-
this._updateBothAttributes(
|
|
486
|
+
const e = `${d}${t}`, o = this._readCompositionFromNode();
|
|
487
|
+
o.push(e);
|
|
488
|
+
const s = [...this._readCustomAttributesFromNode(), t];
|
|
489
|
+
this._updateBothAttributes(o, s), this._injectCustomAttributeHtml(t, r, e, o), this._renderOrderableItems(o, s), this._initializeCustomSelects(s), this._updateAddButtonState();
|
|
559
490
|
}
|
|
560
491
|
/**
|
|
561
492
|
* Removes a single custom attribute by its index in the customAttrs array.
|
|
@@ -565,32 +496,27 @@ class Ut extends rt {
|
|
|
565
496
|
const r = this._readCustomAttributesFromNode();
|
|
566
497
|
if (r[t] === void 0)
|
|
567
498
|
return;
|
|
568
|
-
const
|
|
569
|
-
this._updateBothAttributes(
|
|
499
|
+
const o = this._readCompositionFromNode(), s = this._findNthCustomKeyIndex(o, t), i = o.filter((c, a) => a !== s), n = r.filter((c, a) => a !== t);
|
|
500
|
+
this._updateBothAttributes(i, n), this._removeCustomAttributeHtml(i), this._renderOrderableItems(i, n), this._initializeCustomSelects(n), this._updateAddButtonState();
|
|
570
501
|
}
|
|
571
502
|
/**
|
|
572
503
|
* Handles changing a custom attribute's selection via its inline _GuSelect.
|
|
573
504
|
* Uses the customIndex to target only the specific instance, supporting duplicates.
|
|
574
505
|
*/
|
|
575
506
|
_onCustomAttributeChanged(t, r) {
|
|
576
|
-
const e = this._readCustomAttributesFromNode(),
|
|
577
|
-
if (
|
|
507
|
+
const e = this._readCustomAttributesFromNode(), o = e[t];
|
|
508
|
+
if (o === void 0 || o === r)
|
|
578
509
|
return;
|
|
579
|
-
const
|
|
580
|
-
n !== -1 && (
|
|
510
|
+
const s = `${d}${r}`, i = this._readCompositionFromNode(), n = this._findNthCustomKeyIndex(i, t);
|
|
511
|
+
n !== -1 && (i[n] = s), e[t] = r;
|
|
581
512
|
const c = this._getDisplayNameForAttribute(r);
|
|
582
|
-
this._updateBothAttributes(
|
|
513
|
+
this._updateBothAttributes(i, e), this._injectCustomAttributeHtml(r, c, s, i), this._renderOrderableItems(i, e), this._initializeCustomSelects(e);
|
|
583
514
|
}
|
|
584
515
|
_onReorder(t) {
|
|
585
|
-
const r = t.filter((e) => e.startsWith(
|
|
516
|
+
const r = t.filter((e) => e.startsWith(d)).map((e) => e.substring(d.length));
|
|
586
517
|
this.reorderInProgress = !0;
|
|
587
518
|
try {
|
|
588
|
-
this._updateBothAttributes(t, r);
|
|
589
|
-
const e = !P.getConfig(this.currentNode).priceMovedToNextLine;
|
|
590
|
-
this._getCurrentLayout() === "grid" && !e ? this._reorderProductAttributes(t) : this.currentNode && ft({
|
|
591
|
-
currentNode: this.currentNode,
|
|
592
|
-
documentModifier: this.api.getDocumentModifier()
|
|
593
|
-
});
|
|
519
|
+
this._updateBothAttributes(t, r), this._getCurrentLayout() === "grid" && this._reorderProductAttributes(t);
|
|
594
520
|
} finally {
|
|
595
521
|
this.reorderInProgress = !1;
|
|
596
522
|
}
|
|
@@ -599,67 +525,67 @@ class Ut extends rt {
|
|
|
599
525
|
// ========================================================================
|
|
600
526
|
// HTML Injection / Removal (Product Card DOM)
|
|
601
527
|
// ========================================================================
|
|
602
|
-
_injectCustomAttributeHtml(t, r, e,
|
|
528
|
+
_injectCustomAttributeHtml(t, r, e, o) {
|
|
603
529
|
if (!this.currentNode)
|
|
604
530
|
return;
|
|
605
|
-
this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, r, e,
|
|
531
|
+
this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, r, e, o) : this._injectListAttributeRow(t, r, e, o);
|
|
606
532
|
}
|
|
607
|
-
_injectGridAttributeRow(t, r, e,
|
|
608
|
-
const
|
|
609
|
-
if (!(
|
|
533
|
+
_injectGridAttributeRow(t, r, e, o) {
|
|
534
|
+
const s = this.currentNode.querySelectorAll(L);
|
|
535
|
+
if (!(s != null && s.length))
|
|
610
536
|
return;
|
|
611
|
-
const
|
|
612
|
-
let
|
|
613
|
-
|
|
614
|
-
var
|
|
615
|
-
const
|
|
616
|
-
if (
|
|
617
|
-
const
|
|
618
|
-
{ length:
|
|
619
|
-
(
|
|
620
|
-
const
|
|
537
|
+
const i = $.getConfig(this.currentNode), c = `0 ${Math.floor(i.columnSpacing / 2)}px`, a = this.api.getDocumentModifier(), l = this.store.recommendationProducts.length;
|
|
538
|
+
let u = 0;
|
|
539
|
+
s.forEach((m) => {
|
|
540
|
+
var k;
|
|
541
|
+
const b = m.querySelector(A), I = ((k = b == null ? void 0 : b.querySelectorAll(`.${at}`)) == null ? void 0 : k.length) || 1, B = (100 / I).toFixed(2), { bgStyle: W, bgAttr: K } = this._extractSegmentBgFromCard(m), O = l > 0 ? Math.min(I, l - u) : I, z = o.map((q) => {
|
|
542
|
+
if (q === e) {
|
|
543
|
+
const G = Array.from(
|
|
544
|
+
{ length: O },
|
|
545
|
+
(Ct, X) => {
|
|
546
|
+
const J = this._resolveAttributeContent(
|
|
621
547
|
t,
|
|
622
548
|
r,
|
|
623
|
-
|
|
549
|
+
u + X
|
|
624
550
|
);
|
|
625
551
|
return this._getGridCellHtml(
|
|
626
552
|
t,
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
553
|
+
J,
|
|
554
|
+
B,
|
|
555
|
+
W,
|
|
556
|
+
K,
|
|
631
557
|
c
|
|
632
558
|
);
|
|
633
559
|
}
|
|
634
|
-
).join(""),
|
|
635
|
-
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${
|
|
560
|
+
).join(""), Y = dt(B, c).repeat(I - O);
|
|
561
|
+
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${N}="1">${G}${Y}</tr>`;
|
|
636
562
|
}
|
|
637
|
-
const
|
|
638
|
-
`${
|
|
563
|
+
const D = m.querySelector(
|
|
564
|
+
`${A}[${y}="${q}"]`
|
|
639
565
|
);
|
|
640
|
-
return
|
|
566
|
+
return D && "getOuterHTML" in D ? D.getOuterHTML() : "";
|
|
641
567
|
}).join("");
|
|
642
|
-
|
|
643
|
-
}),
|
|
568
|
+
u += O, l > 0 && u >= l && (u = 0), a.modifyHtml(m).setInnerHtml(z);
|
|
569
|
+
}), a.apply(new C(`${this.api.translate("Add custom attribute")}: ${r}`));
|
|
644
570
|
}
|
|
645
|
-
_injectListAttributeRow(t, r, e,
|
|
646
|
-
const
|
|
647
|
-
if (!(
|
|
571
|
+
_injectListAttributeRow(t, r, e, o) {
|
|
572
|
+
const s = this.currentNode.querySelectorAll(V);
|
|
573
|
+
if (!(s != null && s.length))
|
|
648
574
|
return;
|
|
649
|
-
const
|
|
650
|
-
|
|
651
|
-
const
|
|
652
|
-
if (
|
|
653
|
-
const
|
|
654
|
-
return this._getListRowHtml(t,
|
|
575
|
+
const i = o.filter((c) => c !== H && c !== U), n = this.api.getDocumentModifier();
|
|
576
|
+
s.forEach((c, a) => {
|
|
577
|
+
const l = i.map((u) => {
|
|
578
|
+
if (u === e) {
|
|
579
|
+
const b = this._resolveAttributeContent(t, r, a);
|
|
580
|
+
return this._getListRowHtml(t, b, e);
|
|
655
581
|
}
|
|
656
|
-
const
|
|
657
|
-
`${
|
|
582
|
+
const m = c.querySelector(
|
|
583
|
+
`${A}[${y}="${u}"]`
|
|
658
584
|
);
|
|
659
|
-
return
|
|
585
|
+
return m && "getOuterHTML" in m ? m.getOuterHTML() : "";
|
|
660
586
|
}).join("");
|
|
661
|
-
n.modifyHtml(c).setInnerHtml(
|
|
662
|
-
}), n.apply(new
|
|
587
|
+
n.modifyHtml(c).setInnerHtml(l);
|
|
588
|
+
}), n.apply(new C(`${this.api.translate("Add custom attribute")}: ${r}`));
|
|
663
589
|
}
|
|
664
590
|
/**
|
|
665
591
|
* Removes a custom attribute by rebuilding product card content without it.
|
|
@@ -670,19 +596,19 @@ class Ut extends rt {
|
|
|
670
596
|
return;
|
|
671
597
|
const r = this._getCurrentLayout(), e = this.api.getDocumentModifier();
|
|
672
598
|
if (r === "grid") {
|
|
673
|
-
const
|
|
674
|
-
|
|
675
|
-
const
|
|
676
|
-
e.modifyHtml(
|
|
599
|
+
const o = this.currentNode.querySelectorAll(L);
|
|
600
|
+
o == null || o.forEach((s) => {
|
|
601
|
+
const i = this._buildCompositionHtml(s, t);
|
|
602
|
+
e.modifyHtml(s).setInnerHtml(i);
|
|
677
603
|
});
|
|
678
604
|
} else {
|
|
679
|
-
const
|
|
680
|
-
|
|
681
|
-
const n = this._buildCompositionHtml(
|
|
682
|
-
e.modifyHtml(
|
|
605
|
+
const o = t.filter((i) => i !== H && i !== U), s = this.currentNode.querySelectorAll(V);
|
|
606
|
+
s == null || s.forEach((i) => {
|
|
607
|
+
const n = this._buildCompositionHtml(i, o);
|
|
608
|
+
e.modifyHtml(i).setInnerHtml(n);
|
|
683
609
|
});
|
|
684
610
|
}
|
|
685
|
-
e.apply(new
|
|
611
|
+
e.apply(new C(this.api.translate("Remove custom attribute")));
|
|
686
612
|
}
|
|
687
613
|
// ========================================================================
|
|
688
614
|
// DOM Mutation (Block Root Attributes, Reorder)
|
|
@@ -695,7 +621,13 @@ class Ut extends rt {
|
|
|
695
621
|
* producing a flicker on the custom attribute dropdowns.
|
|
696
622
|
*/
|
|
697
623
|
_updateBothAttributes(t, r) {
|
|
698
|
-
|
|
624
|
+
if (!this.currentNode)
|
|
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")));
|
|
699
631
|
}
|
|
700
632
|
/**
|
|
701
633
|
* Reorders attribute rows within each product card based on composition order.
|
|
@@ -704,23 +636,23 @@ class Ut extends rt {
|
|
|
704
636
|
_reorderProductAttributes(t) {
|
|
705
637
|
if (!this.currentNode)
|
|
706
638
|
return;
|
|
707
|
-
const r = this.currentNode.querySelectorAll(
|
|
639
|
+
const r = this.currentNode.querySelectorAll(L);
|
|
708
640
|
if (!(r != null && r.length))
|
|
709
641
|
return;
|
|
710
642
|
const e = this.api.getDocumentModifier();
|
|
711
|
-
r.forEach((
|
|
712
|
-
const
|
|
713
|
-
e.modifyHtml(
|
|
714
|
-
}), e.apply(new
|
|
643
|
+
r.forEach((o) => {
|
|
644
|
+
const s = this._buildCompositionHtml(o, t);
|
|
645
|
+
e.modifyHtml(o).setInnerHtml(s);
|
|
646
|
+
}), e.apply(new C(this.api.translate("Reorder product attributes")));
|
|
715
647
|
}
|
|
716
648
|
/**
|
|
717
649
|
* Builds HTML string with attributes ordered according to composition.
|
|
718
650
|
* Queries existing rows from the container by data-attribute-type.
|
|
719
651
|
*/
|
|
720
652
|
_buildCompositionHtml(t, r) {
|
|
721
|
-
return r.reduce((e,
|
|
722
|
-
const
|
|
723
|
-
return
|
|
653
|
+
return r.reduce((e, o) => {
|
|
654
|
+
const s = t.querySelector(`${A}[${y}="${o}"]`);
|
|
655
|
+
return s && "getOuterHTML" in s ? e + s.getOuterHTML() : e;
|
|
724
656
|
}, "");
|
|
725
657
|
}
|
|
726
658
|
// ========================================================================
|
|
@@ -729,14 +661,19 @@ class Ut extends rt {
|
|
|
729
661
|
_applyVisibilityToBlock(t, r) {
|
|
730
662
|
if (!this.currentNode)
|
|
731
663
|
return;
|
|
732
|
-
const e = this.currentNode.querySelectorAll(`${
|
|
664
|
+
const e = this.currentNode.querySelectorAll(`${A}[${y}="${t}"]`);
|
|
733
665
|
if (!(e != null && e.length))
|
|
734
666
|
return;
|
|
735
|
-
const
|
|
736
|
-
e.forEach((
|
|
737
|
-
const l =
|
|
738
|
-
n.modifyHtml(
|
|
739
|
-
})
|
|
667
|
+
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
|
+
e.forEach((a) => {
|
|
669
|
+
const l = ft(a), u = r ? l : "none";
|
|
670
|
+
n.modifyHtml(a).setStyle("display", u).setAttribute(N, o);
|
|
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));
|
|
740
677
|
}
|
|
741
678
|
// ========================================================================
|
|
742
679
|
// Utilities
|
|
@@ -748,16 +685,16 @@ class Ut extends rt {
|
|
|
748
685
|
*/
|
|
749
686
|
_findNthCustomKeyIndex(t, r) {
|
|
750
687
|
let e = 0;
|
|
751
|
-
for (let
|
|
752
|
-
if (t[
|
|
688
|
+
for (let o = 0; o < t.length; o++)
|
|
689
|
+
if (t[o].startsWith(d)) {
|
|
753
690
|
if (e === r)
|
|
754
|
-
return
|
|
691
|
+
return o;
|
|
755
692
|
e++;
|
|
756
693
|
}
|
|
757
694
|
return -1;
|
|
758
695
|
}
|
|
759
696
|
_getCurrentLayout() {
|
|
760
|
-
return this.store.recommendationConfigs.orientation ||
|
|
697
|
+
return this.store.recommendationConfigs.orientation || _t(this.currentNode);
|
|
761
698
|
}
|
|
762
699
|
/**
|
|
763
700
|
* Extracts background color properties from existing card elements.
|
|
@@ -766,21 +703,21 @@ class Ut extends rt {
|
|
|
766
703
|
* Used when injecting new attribute cells to match the card's current background.
|
|
767
704
|
*/
|
|
768
705
|
_extractSegmentBgFromCard(t) {
|
|
769
|
-
var
|
|
706
|
+
var o;
|
|
770
707
|
const r = t.querySelector(".product-card-segment");
|
|
771
708
|
if (r && "getAttribute" in r) {
|
|
772
|
-
const
|
|
773
|
-
if (
|
|
709
|
+
const i = (r.getAttribute("style") || "").match(/background-color:\s*([^;]+)/);
|
|
710
|
+
if (i) {
|
|
774
711
|
const n = r.getAttribute("bgcolor") || "";
|
|
775
|
-
return { bgStyle: `background-color: ${
|
|
712
|
+
return { bgStyle: `background-color: ${i[1].trim()};`, bgAttr: n };
|
|
776
713
|
}
|
|
777
714
|
}
|
|
778
|
-
const e = (
|
|
715
|
+
const e = (o = this.currentNode) == null ? void 0 : o.querySelector(".product-card-wrapper");
|
|
779
716
|
if (e && "getStyle" in e) {
|
|
780
|
-
const
|
|
781
|
-
if (
|
|
782
|
-
const
|
|
783
|
-
return { bgStyle: `background-color: ${
|
|
717
|
+
const s = e.getStyle("background-color");
|
|
718
|
+
if (s && s !== "transparent") {
|
|
719
|
+
const i = "getAttribute" in e && e.getAttribute("bgcolor") || "";
|
|
720
|
+
return { bgStyle: `background-color: ${s};`, bgAttr: i };
|
|
784
721
|
}
|
|
785
722
|
}
|
|
786
723
|
return { bgStyle: "", bgAttr: "" };
|
|
@@ -790,18 +727,17 @@ class Ut extends rt {
|
|
|
790
727
|
return t ? t.querySelector("[data-card-composition-control]") : null;
|
|
791
728
|
}
|
|
792
729
|
/**
|
|
793
|
-
*
|
|
794
|
-
*
|
|
795
|
-
*
|
|
796
|
-
* disabled state.)
|
|
730
|
+
* Adds/removes orderable-disabled class based on layout orientation.
|
|
731
|
+
* List layout hides drag handles via CSS and disables draggable attribute
|
|
732
|
+
* to prevent native browser drag-and-drop from working without the handle.
|
|
797
733
|
*/
|
|
798
734
|
_updateOrderableState() {
|
|
799
|
-
const
|
|
800
|
-
if (!
|
|
735
|
+
const r = this._getCurrentLayout() === "list", e = this._getControlContainer();
|
|
736
|
+
if (!e)
|
|
801
737
|
return;
|
|
802
|
-
const
|
|
803
|
-
|
|
804
|
-
|
|
738
|
+
const o = e.querySelector("[data-composition-list]");
|
|
739
|
+
o && (o.classList.toggle("orderable-disabled", r), o.querySelectorAll(".orderable-item").forEach((s) => {
|
|
740
|
+
s.setAttribute("draggable", r ? "false" : "true");
|
|
805
741
|
}));
|
|
806
742
|
}
|
|
807
743
|
/**
|
|
@@ -809,11 +745,11 @@ class Ut extends rt {
|
|
|
809
745
|
* or when all available filters have already been added (no unused attributes left).
|
|
810
746
|
*/
|
|
811
747
|
_updateAddButtonState() {
|
|
812
|
-
const t = this._readCustomAttributesFromNode(), r = t.length >=
|
|
748
|
+
const t = this._readCustomAttributesFromNode(), r = t.length >= _, e = new Set(t), o = this._getAddableFilters(), s = o.length > 0 && o.every((i) => e.has(i.attributeName));
|
|
813
749
|
this.api.setUIEAttribute(
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
r ||
|
|
750
|
+
j.ADD_ATTRIBUTE,
|
|
751
|
+
v.BUTTON.disabled,
|
|
752
|
+
r || s ? "true" : "false"
|
|
817
753
|
);
|
|
818
754
|
}
|
|
819
755
|
/**
|
|
@@ -826,8 +762,8 @@ class Ut extends rt {
|
|
|
826
762
|
this.unsubscribeStore = this.store.$subscribe(() => {
|
|
827
763
|
const e = this.store.recommendationConfigs.orientation;
|
|
828
764
|
e !== t && (t = e, this._updateOrderableState());
|
|
829
|
-
const
|
|
830
|
-
|
|
765
|
+
const o = Object.keys(this.store.filterList).sort().join(",");
|
|
766
|
+
o !== r && (r = o, this._initializeComposition());
|
|
831
767
|
});
|
|
832
768
|
}
|
|
833
769
|
/**
|
|
@@ -843,7 +779,7 @@ class Ut extends rt {
|
|
|
843
779
|
*/
|
|
844
780
|
_getDisplayNameForAttribute(t) {
|
|
845
781
|
const r = Object.values(this.store.filterList).find((e) => e.attributeName === t);
|
|
846
|
-
return r ? r.displayName :
|
|
782
|
+
return r ? r.displayName : ht(t);
|
|
847
783
|
}
|
|
848
784
|
/**
|
|
849
785
|
* Resolves the display content for a custom attribute cell.
|
|
@@ -851,29 +787,29 @@ class Ut extends rt {
|
|
|
851
787
|
*/
|
|
852
788
|
_resolveAttributeContent(t, r, e) {
|
|
853
789
|
var n;
|
|
854
|
-
const
|
|
855
|
-
return
|
|
790
|
+
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 gt(i) ?? r;
|
|
856
792
|
}
|
|
857
|
-
_getGridCellHtml(t, r, e,
|
|
858
|
-
const n = `${
|
|
793
|
+
_getGridCellHtml(t, r, e, o = "", s = "", i = "") {
|
|
794
|
+
const n = `${d}${t}`, c = M(ct, [n], this.store.filterList), a = {
|
|
859
795
|
[t]: r,
|
|
860
796
|
product_attributes: { [t]: r }
|
|
861
797
|
};
|
|
862
|
-
let
|
|
863
|
-
return
|
|
864
|
-
`padding: ${
|
|
865
|
-
`padding: ${
|
|
866
|
-
)),
|
|
798
|
+
let l = c[n](a);
|
|
799
|
+
return l = l.replace("<td", `<td width="${e}%"`), i && (l = l.replace(
|
|
800
|
+
`padding: ${ut}`,
|
|
801
|
+
`padding: ${i}`
|
|
802
|
+
)), o && (l = l.replace(/style="table-layout: fixed;"/, `style="table-layout: fixed; ${o}"`)), s && (l = l.replace(/border="0"/, `border="0" bgcolor="${s}"`)), l;
|
|
867
803
|
}
|
|
868
804
|
_getListRowHtml(t, r, e) {
|
|
869
|
-
const
|
|
805
|
+
const o = M(mt, [e], this.store.filterList), s = {
|
|
870
806
|
[t]: r,
|
|
871
807
|
product_attributes: { [t]: r }
|
|
872
|
-
}, n =
|
|
873
|
-
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${
|
|
808
|
+
}, n = o[e](s).replace(/<tr>/, "").replace(/<\/tr>/, "");
|
|
809
|
+
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${N}="1">${n}</tr>`;
|
|
874
810
|
}
|
|
875
811
|
}
|
|
876
812
|
export {
|
|
877
|
-
|
|
878
|
-
|
|
813
|
+
bt as COMPOSITION_CONTROL_BLOCK_ID,
|
|
814
|
+
Ht as RecommendationCardCompositionControl
|
|
879
815
|
};
|