@useinsider/guido 3.7.2-beta.13c9a35 → 3.7.2-beta.1e8f93e
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/Items/block.js +48 -29
- package/dist/extensions/Blocks/Items/utils/nodeConfigUtils.js +62 -45
- package/dist/extensions/Blocks/Recommendation/block.js +41 -60
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +32 -41
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +288 -369
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +84 -96
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +80 -82
- 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/Items/block.d.ts +8 -0
- package/dist/src/extensions/Blocks/Items/utils/nodeConfigUtils.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/extensions/Blocks/Recommendation/controls/main/pricePlacement.d.ts +0 -59
|
@@ -1,103 +1,103 @@
|
|
|
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 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
|
-
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 _t, buildElementRenderer as w } from "../../templates/utils.js";
|
|
13
|
+
import { getTableDisplayValue as ft } from "../../utils/tagName.js";
|
|
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:
|
|
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
23
|
{ key: st, label: "Omnibus Discount" },
|
|
24
24
|
{ key: U, label: "Product Button" }
|
|
25
|
-
],
|
|
26
|
-
class Ut extends
|
|
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
|
-
|
|
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: g },
|
|
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 + g, o = Array.from(
|
|
61
61
|
{ length: e },
|
|
62
|
-
(
|
|
63
|
-
<div data-reorder-icon-key="${
|
|
64
|
-
<${
|
|
62
|
+
(l, u) => `
|
|
63
|
+
<div data-reorder-icon-key="${E}${u}" style="display: none;">
|
|
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"
|
|
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="${R}${
|
|
79
|
-
<${
|
|
75
|
+
).join(""), s = Array.from(
|
|
76
|
+
{ length: g },
|
|
77
|
+
(l, u) => `
|
|
78
|
+
<div data-custom-delete-key="${R}${u}" style="display: none;">
|
|
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"
|
|
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
|
+
), 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="${
|
|
100
|
+
<a href="${i}" target="_blank" rel="noopener noreferrer">${c}</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: x.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 < g; 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,14 +161,14 @@ 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
|
-
return t ? t.split(",").filter(Boolean) : [...
|
|
164
|
+
return [...P];
|
|
165
|
+
const t = this.currentNode.getAttribute(V);
|
|
166
|
+
return t ? t.split(",").filter(Boolean) : [...P];
|
|
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(q);
|
|
172
172
|
if (!t)
|
|
173
173
|
return [];
|
|
174
174
|
try {
|
|
@@ -180,31 +180,31 @@ class Ut extends rt {
|
|
|
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(C)), r = this._extractVisibilityFromRows(t);
|
|
184
184
|
return this._mergeWithDefaults(r);
|
|
185
185
|
}
|
|
186
186
|
_getDefaultVisibilities() {
|
|
187
|
-
return { ...
|
|
187
|
+
return { ...F };
|
|
188
188
|
}
|
|
189
189
|
_extractVisibilityFromRows(t) {
|
|
190
190
|
const r = {};
|
|
191
191
|
return t.forEach((e) => {
|
|
192
192
|
if (!("getAttribute" in e))
|
|
193
193
|
return;
|
|
194
|
-
const
|
|
195
|
-
|
|
194
|
+
const o = e.getAttribute(y), s = e.getAttribute(v);
|
|
195
|
+
o && s !== null && (r[o] = this._parseVisibilityValue(s));
|
|
196
196
|
}), r;
|
|
197
197
|
}
|
|
198
198
|
_parseVisibilityValue(t) {
|
|
199
199
|
return t === "1" || t === "true";
|
|
200
200
|
}
|
|
201
201
|
_mergeWithDefaults(t) {
|
|
202
|
-
return Object.entries(
|
|
202
|
+
return Object.entries(F).forEach(([r, e]) => {
|
|
203
203
|
r in t || (t[r] = e);
|
|
204
204
|
}), t;
|
|
205
205
|
}
|
|
206
206
|
_buildVisibilityValues(t) {
|
|
207
|
-
return
|
|
207
|
+
return h.reduce((r, e) => (r[`visibility_${e.key}`] = t[e.key] ?? !0, r), {});
|
|
208
208
|
}
|
|
209
209
|
// ========================================================================
|
|
210
210
|
// UI Rendering (Orderable List)
|
|
@@ -218,30 +218,24 @@ class Ut extends rt {
|
|
|
218
218
|
const e = this._getControlContainer();
|
|
219
219
|
if (!e)
|
|
220
220
|
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))
|
|
221
|
+
const o = e.querySelector("[data-composition-list]");
|
|
222
|
+
if (!o || this._tryReorderInPlace(o, t))
|
|
226
223
|
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++);
|
|
224
|
+
const s = new Set(r);
|
|
225
|
+
let i = 0, n = 0;
|
|
226
|
+
const a = t.map((c) => {
|
|
227
|
+
if (yt.has(c)) {
|
|
228
|
+
const l = h.find((u) => u.key === c);
|
|
229
|
+
return this._createBuiltInItemHtml(l, n++);
|
|
236
230
|
}
|
|
237
|
-
if (
|
|
238
|
-
const
|
|
239
|
-
if (
|
|
240
|
-
return this._createCustomItemHtml(
|
|
231
|
+
if (c.startsWith(m)) {
|
|
232
|
+
const l = c.substring(m.length);
|
|
233
|
+
if (s.has(l))
|
|
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),
|
|
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 Ut extends rt {
|
|
|
253
247
|
const e = Array.from(t.querySelectorAll(".orderable-item"));
|
|
254
248
|
if (e.length !== r.length)
|
|
255
249
|
return !1;
|
|
256
|
-
const
|
|
257
|
-
if (
|
|
250
|
+
const o = e.map((c) => c.dataset.key).filter(Boolean);
|
|
251
|
+
if (o.length !== r.length)
|
|
258
252
|
return !1;
|
|
259
|
-
const
|
|
260
|
-
if (
|
|
253
|
+
const s = [...o].sort().join(","), i = [...r].sort().join(",");
|
|
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:
|
|
265
|
-
if (
|
|
266
|
-
const
|
|
267
|
-
|
|
257
|
+
e.forEach((c) => {
|
|
258
|
+
const { key: l } = c.dataset;
|
|
259
|
+
if (l) {
|
|
260
|
+
const u = n.get(l) || [];
|
|
261
|
+
u.push(c), n.set(l, u);
|
|
268
262
|
}
|
|
269
263
|
});
|
|
270
|
-
const
|
|
271
|
-
return r.forEach((
|
|
272
|
-
const
|
|
273
|
-
if (!
|
|
264
|
+
const a = /* @__PURE__ */ new Map();
|
|
265
|
+
return r.forEach((c) => {
|
|
266
|
+
const l = n.get(c);
|
|
267
|
+
if (!l)
|
|
274
268
|
return;
|
|
275
|
-
const
|
|
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) {
|
|
@@ -285,33 +279,6 @@ class Ut extends rt {
|
|
|
285
279
|
</div>
|
|
286
280
|
`;
|
|
287
281
|
}
|
|
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
282
|
_createCustomItemHtml(t, r, e) {
|
|
316
283
|
return `
|
|
317
284
|
<div class="orderable-item" draggable="true"
|
|
@@ -332,10 +299,10 @@ class Ut extends rt {
|
|
|
332
299
|
_getSelectOptions(t, r = []) {
|
|
333
300
|
const e = this._getAddableFilters();
|
|
334
301
|
if (e.length > 0) {
|
|
335
|
-
const
|
|
336
|
-
return
|
|
337
|
-
text:
|
|
338
|
-
value:
|
|
302
|
+
const s = new Set(r);
|
|
303
|
+
return s.delete(t), e.filter((i) => !s.has(i.attributeName)).map((i) => ({
|
|
304
|
+
text: i.displayName,
|
|
305
|
+
value: i.attributeName
|
|
339
306
|
}));
|
|
340
307
|
}
|
|
341
308
|
return [{ text: this._getDisplayNameForAttribute(t), value: t }];
|
|
@@ -348,8 +315,8 @@ class Ut extends rt {
|
|
|
348
315
|
_initializeCustomSelects(t) {
|
|
349
316
|
t.length !== 0 && setTimeout(() => {
|
|
350
317
|
t.forEach((r, e) => {
|
|
351
|
-
const
|
|
352
|
-
this.api.setUIEAttribute(
|
|
318
|
+
const o = `${T}${e}`, s = this._getSelectOptions(r, t);
|
|
319
|
+
this.api.setUIEAttribute(o, I.SELECTPICKER.items, s), this.api.updateValues({ [o]: r });
|
|
353
320
|
});
|
|
354
321
|
}, 0);
|
|
355
322
|
}
|
|
@@ -358,11 +325,11 @@ class Ut extends rt {
|
|
|
358
325
|
* Stripo initializes toggles at template parse time; moving the DOM node preserves bindings.
|
|
359
326
|
*/
|
|
360
327
|
_moveTogglesIntoItems(t) {
|
|
361
|
-
|
|
362
|
-
const e = t.querySelector(`[data-toggle-key="${r.key}"]`),
|
|
363
|
-
if (e &&
|
|
364
|
-
const
|
|
365
|
-
|
|
328
|
+
h.forEach((r) => {
|
|
329
|
+
const e = t.querySelector(`[data-toggle-key="${r.key}"]`), o = t.querySelector(`[data-action-for="${r.key}"]`);
|
|
330
|
+
if (e && o) {
|
|
331
|
+
const s = e.querySelector("ue-switcher");
|
|
332
|
+
s && o.appendChild(s);
|
|
366
333
|
}
|
|
367
334
|
});
|
|
368
335
|
}
|
|
@@ -372,10 +339,10 @@ class Ut extends rt {
|
|
|
372
339
|
*/
|
|
373
340
|
_moveSelectsIntoItems(t, r) {
|
|
374
341
|
for (let e = 0; e < r; e++) {
|
|
375
|
-
const
|
|
376
|
-
if (
|
|
377
|
-
const n =
|
|
378
|
-
n &&
|
|
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);
|
|
379
346
|
}
|
|
380
347
|
}
|
|
381
348
|
}
|
|
@@ -386,11 +353,11 @@ class Ut extends rt {
|
|
|
386
353
|
* previously-moved toggles, making them permanently lost.
|
|
387
354
|
*/
|
|
388
355
|
_rescueTogglesToStore(t) {
|
|
389
|
-
|
|
390
|
-
const e = t.querySelector(`[data-toggle-key="${r.key}"]`),
|
|
391
|
-
if (
|
|
392
|
-
const
|
|
393
|
-
|
|
356
|
+
h.forEach((r) => {
|
|
357
|
+
const e = t.querySelector(`[data-toggle-key="${r.key}"]`), o = t.querySelector(`[data-action-for="${r.key}"]`);
|
|
358
|
+
if (o) {
|
|
359
|
+
const s = o.querySelector("ue-switcher");
|
|
360
|
+
s && e && e.appendChild(s);
|
|
394
361
|
}
|
|
395
362
|
});
|
|
396
363
|
}
|
|
@@ -399,11 +366,11 @@ class Ut extends rt {
|
|
|
399
366
|
* Same rescue pattern as _rescueTogglesToStore — prevents innerHTML from destroying them.
|
|
400
367
|
*/
|
|
401
368
|
_rescueSelectsToStore(t) {
|
|
402
|
-
for (let r = 0; r <
|
|
403
|
-
const e = `${
|
|
404
|
-
if (
|
|
405
|
-
const
|
|
406
|
-
|
|
369
|
+
for (let r = 0; r < g; r++) {
|
|
370
|
+
const e = `${T}${r}`, o = t.querySelector(`[data-custom-select-key="${e}"]`), s = t.querySelector(`[data-custom-select-slot="${r}"]`);
|
|
371
|
+
if (s) {
|
|
372
|
+
const i = s.querySelector("ue-select");
|
|
373
|
+
i && o && o.appendChild(i);
|
|
407
374
|
}
|
|
408
375
|
}
|
|
409
376
|
}
|
|
@@ -413,10 +380,10 @@ class Ut extends rt {
|
|
|
413
380
|
*/
|
|
414
381
|
_moveDeleteButtonsIntoItems(t, r) {
|
|
415
382
|
for (let e = 0; e < r; e++) {
|
|
416
|
-
const
|
|
417
|
-
if (
|
|
418
|
-
const n =
|
|
419
|
-
n &&
|
|
383
|
+
const o = `${R}${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);
|
|
420
387
|
}
|
|
421
388
|
}
|
|
422
389
|
}
|
|
@@ -425,11 +392,11 @@ class Ut extends rt {
|
|
|
425
392
|
* Same rescue pattern as _rescueSelectsToStore — prevents innerHTML from destroying them.
|
|
426
393
|
*/
|
|
427
394
|
_rescueDeleteButtonsToStore(t) {
|
|
428
|
-
for (let r = 0; r <
|
|
429
|
-
const e = `${R}${r}`,
|
|
430
|
-
if (
|
|
431
|
-
const
|
|
432
|
-
|
|
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}"]`);
|
|
397
|
+
if (s) {
|
|
398
|
+
const i = s.querySelector("ue-button");
|
|
399
|
+
i && o && o.appendChild(i);
|
|
433
400
|
}
|
|
434
401
|
}
|
|
435
402
|
}
|
|
@@ -439,10 +406,10 @@ class Ut extends rt {
|
|
|
439
406
|
*/
|
|
440
407
|
_moveReorderIconsIntoItems(t, r) {
|
|
441
408
|
for (let e = 0; e < r; e++) {
|
|
442
|
-
const
|
|
443
|
-
if (
|
|
444
|
-
const n =
|
|
445
|
-
n &&
|
|
409
|
+
const o = `${E}${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);
|
|
446
413
|
}
|
|
447
414
|
}
|
|
448
415
|
}
|
|
@@ -451,12 +418,12 @@ class Ut extends rt {
|
|
|
451
418
|
* Same rescue pattern as _rescueDeleteButtonsToStore — prevents innerHTML from destroying them.
|
|
452
419
|
*/
|
|
453
420
|
_rescueReorderIconsToStore(t) {
|
|
454
|
-
const r =
|
|
421
|
+
const r = h.length + g;
|
|
455
422
|
for (let e = 0; e < r; e++) {
|
|
456
|
-
const
|
|
457
|
-
if (
|
|
458
|
-
const n =
|
|
459
|
-
n &&
|
|
423
|
+
const o = `${E}${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);
|
|
460
427
|
}
|
|
461
428
|
}
|
|
462
429
|
}
|
|
@@ -468,83 +435,41 @@ class Ut extends rt {
|
|
|
468
435
|
const { signal: t } = this.eventController, r = this._getControlContainer();
|
|
469
436
|
if (!r)
|
|
470
437
|
return;
|
|
471
|
-
const e = r.querySelector("[data-composition-list]"),
|
|
472
|
-
e && (this._setupDragAndDrop(e, t), this._setupDeleteHandler(e, t)),
|
|
473
|
-
const
|
|
474
|
-
|
|
438
|
+
const e = r.querySelector("[data-composition-list]"), o = r.querySelector("#guido__btn-add-attribute");
|
|
439
|
+
e && (this._setupDragAndDrop(e, t), this._setupDeleteHandler(e, t)), o && o.addEventListener("click", () => {
|
|
440
|
+
const s = new Set(this._readCustomAttributesFromNode()), i = this._getAddableFilters().find((n) => !s.has(n.attributeName));
|
|
441
|
+
i && this._onAddAttribute(i.attributeName, i.displayName);
|
|
475
442
|
}, { signal: t });
|
|
476
443
|
}
|
|
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
444
|
_setupDragAndDrop(t, r) {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
ignoreSelector: ".price-suborderable-item",
|
|
496
|
-
getDropParent: () => t
|
|
497
|
-
}), this._registerDragHandlers(t, r, {
|
|
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) => {
|
|
445
|
+
let e = null, o = null;
|
|
446
|
+
t.addEventListener("dragstart", (s) => {
|
|
515
447
|
var a;
|
|
516
|
-
const
|
|
517
|
-
|
|
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 ?? ""));
|
|
448
|
+
const n = s.target.closest(".orderable-item");
|
|
449
|
+
n && (e = n, n.classList.add("dragging"), (a = s.dataTransfer) == null || a.setData("text/plain", n.dataset.key || ""));
|
|
521
450
|
}, { signal: r }), t.addEventListener("dragend", () => {
|
|
522
|
-
|
|
523
|
-
}, { signal: r }), t.addEventListener("dragover", (
|
|
524
|
-
|
|
451
|
+
e && e.classList.remove("dragging"), e = null, o == null || o.classList.remove("drag-over"), o = null;
|
|
452
|
+
}, { signal: r }), t.addEventListener("dragover", (s) => {
|
|
453
|
+
s.preventDefault();
|
|
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"));
|
|
456
|
+
}, { signal: r }), t.addEventListener("drop", (s) => {
|
|
457
|
+
s.preventDefault();
|
|
458
|
+
const n = s.target.closest(".orderable-item");
|
|
459
|
+
if (!n || !e || n === e)
|
|
525
460
|
return;
|
|
526
|
-
const
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
const l = c !== i ? c : null;
|
|
531
|
-
l !== o && (o == null || o.classList.remove("drag-over"), o = l, o == null || o.classList.add("drag-over"));
|
|
532
|
-
}, { signal: r }), t.addEventListener("drop", (n) => {
|
|
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));
|
|
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;
|
|
540
465
|
}, { signal: r });
|
|
541
466
|
}
|
|
542
467
|
_setupDeleteHandler(t, r) {
|
|
543
468
|
t.addEventListener("click", (e) => {
|
|
544
|
-
const
|
|
545
|
-
if (!
|
|
469
|
+
const s = e.target.closest(".custom-attr-delete");
|
|
470
|
+
if (!s)
|
|
546
471
|
return;
|
|
547
|
-
const
|
|
472
|
+
const i = s.closest("[data-custom-index]"), n = i == null ? void 0 : i.dataset.customIndex;
|
|
548
473
|
n !== void 0 && this._onDeleteCustomAttribute(Number(n));
|
|
549
474
|
}, { signal: r });
|
|
550
475
|
}
|
|
@@ -552,10 +477,10 @@ class Ut extends rt {
|
|
|
552
477
|
// Actions (Add, Delete, Reorder)
|
|
553
478
|
// ========================================================================
|
|
554
479
|
_onAddAttribute(t, r) {
|
|
555
|
-
const e = `${
|
|
556
|
-
|
|
557
|
-
const
|
|
558
|
-
this._updateBothAttributes(
|
|
480
|
+
const e = `${m}${t}`, o = this._readCompositionFromNode();
|
|
481
|
+
o.push(e);
|
|
482
|
+
const s = [...this._readCustomAttributesFromNode(), t];
|
|
483
|
+
this._updateBothAttributes(o, s), this._injectCustomAttributeHtml(t, r, e, o), this._renderOrderableItems(o, s), this._initializeCustomSelects(s), this._updateAddButtonState();
|
|
559
484
|
}
|
|
560
485
|
/**
|
|
561
486
|
* Removes a single custom attribute by its index in the customAttrs array.
|
|
@@ -565,32 +490,27 @@ class Ut extends rt {
|
|
|
565
490
|
const r = this._readCustomAttributesFromNode();
|
|
566
491
|
if (r[t] === void 0)
|
|
567
492
|
return;
|
|
568
|
-
const
|
|
569
|
-
this._updateBothAttributes(
|
|
493
|
+
const o = this._readCompositionFromNode(), s = this._findNthCustomKeyIndex(o, t), i = o.filter((a, c) => c !== s), n = r.filter((a, c) => c !== t);
|
|
494
|
+
this._updateBothAttributes(i, n), this._removeCustomAttributeHtml(i), this._renderOrderableItems(i, n), this._initializeCustomSelects(n), this._updateAddButtonState();
|
|
570
495
|
}
|
|
571
496
|
/**
|
|
572
497
|
* Handles changing a custom attribute's selection via its inline _GuSelect.
|
|
573
498
|
* Uses the customIndex to target only the specific instance, supporting duplicates.
|
|
574
499
|
*/
|
|
575
500
|
_onCustomAttributeChanged(t, r) {
|
|
576
|
-
const e = this._readCustomAttributesFromNode(),
|
|
577
|
-
if (
|
|
501
|
+
const e = this._readCustomAttributesFromNode(), o = e[t];
|
|
502
|
+
if (o === void 0 || o === r)
|
|
578
503
|
return;
|
|
579
|
-
const
|
|
580
|
-
n !== -1 && (
|
|
581
|
-
const
|
|
582
|
-
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 a = this._getDisplayNameForAttribute(r);
|
|
507
|
+
this._updateBothAttributes(i, e), this._injectCustomAttributeHtml(r, a, s, i), this._renderOrderableItems(i, e), this._initializeCustomSelects(e);
|
|
583
508
|
}
|
|
584
509
|
_onReorder(t) {
|
|
585
|
-
const r = t.filter((e) => e.startsWith(
|
|
510
|
+
const r = t.filter((e) => e.startsWith(m)).map((e) => e.substring(m.length));
|
|
586
511
|
this.reorderInProgress = !0;
|
|
587
512
|
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
|
-
});
|
|
513
|
+
this._updateBothAttributes(t, r), this._getCurrentLayout() === "grid" && this._reorderProductAttributes(t);
|
|
594
514
|
} finally {
|
|
595
515
|
this.reorderInProgress = !1;
|
|
596
516
|
}
|
|
@@ -599,66 +519,66 @@ class Ut extends rt {
|
|
|
599
519
|
// ========================================================================
|
|
600
520
|
// HTML Injection / Removal (Product Card DOM)
|
|
601
521
|
// ========================================================================
|
|
602
|
-
_injectCustomAttributeHtml(t, r, e,
|
|
522
|
+
_injectCustomAttributeHtml(t, r, e, o) {
|
|
603
523
|
if (!this.currentNode)
|
|
604
524
|
return;
|
|
605
|
-
this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, r, e,
|
|
525
|
+
this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, r, e, o) : this._injectListAttributeRow(t, r, e, o);
|
|
606
526
|
}
|
|
607
|
-
_injectGridAttributeRow(t, r, e,
|
|
608
|
-
const
|
|
609
|
-
if (!(
|
|
527
|
+
_injectGridAttributeRow(t, r, e, o) {
|
|
528
|
+
const s = this.currentNode.querySelectorAll(L);
|
|
529
|
+
if (!(s != null && s.length))
|
|
610
530
|
return;
|
|
611
|
-
const
|
|
612
|
-
let
|
|
613
|
-
|
|
614
|
-
var
|
|
615
|
-
const
|
|
616
|
-
if (
|
|
617
|
-
const
|
|
618
|
-
{ length:
|
|
619
|
-
(
|
|
620
|
-
const
|
|
531
|
+
const i = nt.getConfig(this.currentNode), a = `0 ${Math.floor(i.columnSpacing / 2)}px`, c = this.api.getDocumentModifier(), l = this.store.recommendationProducts.length;
|
|
532
|
+
let u = 0;
|
|
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(
|
|
538
|
+
{ length: O },
|
|
539
|
+
(At, Y) => {
|
|
540
|
+
const X = this._resolveAttributeContent(
|
|
621
541
|
t,
|
|
622
542
|
r,
|
|
623
|
-
|
|
543
|
+
u + Y
|
|
624
544
|
);
|
|
625
545
|
return this._getGridCellHtml(
|
|
626
546
|
t,
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
547
|
+
X,
|
|
548
|
+
B,
|
|
549
|
+
j,
|
|
550
|
+
W,
|
|
551
|
+
a
|
|
632
552
|
);
|
|
633
553
|
}
|
|
634
|
-
).join(""),
|
|
635
|
-
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>`;
|
|
636
556
|
}
|
|
637
|
-
const
|
|
638
|
-
`${
|
|
557
|
+
const N = d.querySelector(
|
|
558
|
+
`${C}[${y}="${k}"]`
|
|
639
559
|
);
|
|
640
|
-
return
|
|
560
|
+
return N && "getOuterHTML" in N ? N.getOuterHTML() : "";
|
|
641
561
|
}).join("");
|
|
642
|
-
|
|
643
|
-
}),
|
|
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}`));
|
|
644
564
|
}
|
|
645
|
-
_injectListAttributeRow(t, r, e,
|
|
646
|
-
const
|
|
647
|
-
if (!(
|
|
565
|
+
_injectListAttributeRow(t, r, e, o) {
|
|
566
|
+
const s = this.currentNode.querySelectorAll(M);
|
|
567
|
+
if (!(s != null && s.length))
|
|
648
568
|
return;
|
|
649
|
-
const
|
|
650
|
-
|
|
651
|
-
const
|
|
652
|
-
if (
|
|
653
|
-
const
|
|
654
|
-
return this._getListRowHtml(t,
|
|
569
|
+
const i = o.filter((a) => a !== D && a !== U), n = this.api.getDocumentModifier();
|
|
570
|
+
s.forEach((a, c) => {
|
|
571
|
+
const l = i.map((u) => {
|
|
572
|
+
if (u === e) {
|
|
573
|
+
const b = this._resolveAttributeContent(t, r, c);
|
|
574
|
+
return this._getListRowHtml(t, b, e);
|
|
655
575
|
}
|
|
656
|
-
const
|
|
657
|
-
`${
|
|
576
|
+
const d = a.querySelector(
|
|
577
|
+
`${C}[${y}="${u}"]`
|
|
658
578
|
);
|
|
659
|
-
return
|
|
579
|
+
return d && "getOuterHTML" in d ? d.getOuterHTML() : "";
|
|
660
580
|
}).join("");
|
|
661
|
-
n.modifyHtml(
|
|
581
|
+
n.modifyHtml(a).setInnerHtml(l);
|
|
662
582
|
}), n.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
|
|
663
583
|
}
|
|
664
584
|
/**
|
|
@@ -670,16 +590,16 @@ class Ut extends rt {
|
|
|
670
590
|
return;
|
|
671
591
|
const r = this._getCurrentLayout(), e = this.api.getDocumentModifier();
|
|
672
592
|
if (r === "grid") {
|
|
673
|
-
const
|
|
674
|
-
|
|
675
|
-
const
|
|
676
|
-
e.modifyHtml(
|
|
593
|
+
const o = this.currentNode.querySelectorAll(L);
|
|
594
|
+
o == null || o.forEach((s) => {
|
|
595
|
+
const i = this._buildCompositionHtml(s, t);
|
|
596
|
+
e.modifyHtml(s).setInnerHtml(i);
|
|
677
597
|
});
|
|
678
598
|
} else {
|
|
679
|
-
const
|
|
680
|
-
|
|
681
|
-
const n = this._buildCompositionHtml(
|
|
682
|
-
e.modifyHtml(
|
|
599
|
+
const o = t.filter((i) => i !== D && i !== U), s = this.currentNode.querySelectorAll(M);
|
|
600
|
+
s == null || s.forEach((i) => {
|
|
601
|
+
const n = this._buildCompositionHtml(i, o);
|
|
602
|
+
e.modifyHtml(i).setInnerHtml(n);
|
|
683
603
|
});
|
|
684
604
|
}
|
|
685
605
|
e.apply(new A(this.api.translate("Remove custom attribute")));
|
|
@@ -695,7 +615,7 @@ class Ut extends rt {
|
|
|
695
615
|
* producing a flicker on the custom attribute dropdowns.
|
|
696
616
|
*/
|
|
697
617
|
_updateBothAttributes(t, r) {
|
|
698
|
-
this.currentNode && this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(
|
|
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")));
|
|
699
619
|
}
|
|
700
620
|
/**
|
|
701
621
|
* Reorders attribute rows within each product card based on composition order.
|
|
@@ -704,13 +624,13 @@ class Ut extends rt {
|
|
|
704
624
|
_reorderProductAttributes(t) {
|
|
705
625
|
if (!this.currentNode)
|
|
706
626
|
return;
|
|
707
|
-
const r = this.currentNode.querySelectorAll(
|
|
627
|
+
const r = this.currentNode.querySelectorAll(L);
|
|
708
628
|
if (!(r != null && r.length))
|
|
709
629
|
return;
|
|
710
630
|
const e = this.api.getDocumentModifier();
|
|
711
|
-
r.forEach((
|
|
712
|
-
const
|
|
713
|
-
e.modifyHtml(
|
|
631
|
+
r.forEach((o) => {
|
|
632
|
+
const s = this._buildCompositionHtml(o, t);
|
|
633
|
+
e.modifyHtml(o).setInnerHtml(s);
|
|
714
634
|
}), e.apply(new A(this.api.translate("Reorder product attributes")));
|
|
715
635
|
}
|
|
716
636
|
/**
|
|
@@ -718,9 +638,9 @@ class Ut extends rt {
|
|
|
718
638
|
* Queries existing rows from the container by data-attribute-type.
|
|
719
639
|
*/
|
|
720
640
|
_buildCompositionHtml(t, r) {
|
|
721
|
-
return r.reduce((e,
|
|
722
|
-
const
|
|
723
|
-
return
|
|
641
|
+
return r.reduce((e, o) => {
|
|
642
|
+
const s = t.querySelector(`${C}[${y}="${o}"]`);
|
|
643
|
+
return s && "getOuterHTML" in s ? e + s.getOuterHTML() : e;
|
|
724
644
|
}, "");
|
|
725
645
|
}
|
|
726
646
|
// ========================================================================
|
|
@@ -729,14 +649,14 @@ class Ut extends rt {
|
|
|
729
649
|
_applyVisibilityToBlock(t, r) {
|
|
730
650
|
if (!this.currentNode)
|
|
731
651
|
return;
|
|
732
|
-
const e = this.currentNode.querySelectorAll(`${
|
|
652
|
+
const e = this.currentNode.querySelectorAll(`${C}[${y}="${t}"]`);
|
|
733
653
|
if (!(e != null && e.length))
|
|
734
654
|
return;
|
|
735
|
-
const
|
|
736
|
-
e.forEach((
|
|
737
|
-
const
|
|
738
|
-
n.modifyHtml(
|
|
739
|
-
}), n.apply(new A(
|
|
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();
|
|
656
|
+
e.forEach((a) => {
|
|
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));
|
|
740
660
|
}
|
|
741
661
|
// ========================================================================
|
|
742
662
|
// Utilities
|
|
@@ -748,16 +668,16 @@ class Ut extends rt {
|
|
|
748
668
|
*/
|
|
749
669
|
_findNthCustomKeyIndex(t, r) {
|
|
750
670
|
let e = 0;
|
|
751
|
-
for (let
|
|
752
|
-
if (t[
|
|
671
|
+
for (let o = 0; o < t.length; o++)
|
|
672
|
+
if (t[o].startsWith(m)) {
|
|
753
673
|
if (e === r)
|
|
754
|
-
return
|
|
674
|
+
return o;
|
|
755
675
|
e++;
|
|
756
676
|
}
|
|
757
677
|
return -1;
|
|
758
678
|
}
|
|
759
679
|
_getCurrentLayout() {
|
|
760
|
-
return this.store.recommendationConfigs.orientation ||
|
|
680
|
+
return this.store.recommendationConfigs.orientation || gt(this.currentNode);
|
|
761
681
|
}
|
|
762
682
|
/**
|
|
763
683
|
* Extracts background color properties from existing card elements.
|
|
@@ -766,21 +686,21 @@ class Ut extends rt {
|
|
|
766
686
|
* Used when injecting new attribute cells to match the card's current background.
|
|
767
687
|
*/
|
|
768
688
|
_extractSegmentBgFromCard(t) {
|
|
769
|
-
var
|
|
689
|
+
var o;
|
|
770
690
|
const r = t.querySelector(".product-card-segment");
|
|
771
691
|
if (r && "getAttribute" in r) {
|
|
772
|
-
const
|
|
773
|
-
if (
|
|
692
|
+
const i = (r.getAttribute("style") || "").match(/background-color:\s*([^;]+)/);
|
|
693
|
+
if (i) {
|
|
774
694
|
const n = r.getAttribute("bgcolor") || "";
|
|
775
|
-
return { bgStyle: `background-color: ${
|
|
695
|
+
return { bgStyle: `background-color: ${i[1].trim()};`, bgAttr: n };
|
|
776
696
|
}
|
|
777
697
|
}
|
|
778
|
-
const e = (
|
|
698
|
+
const e = (o = this.currentNode) == null ? void 0 : o.querySelector(".product-card-wrapper");
|
|
779
699
|
if (e && "getStyle" in e) {
|
|
780
|
-
const
|
|
781
|
-
if (
|
|
782
|
-
const
|
|
783
|
-
return { bgStyle: `background-color: ${
|
|
700
|
+
const s = e.getStyle("background-color");
|
|
701
|
+
if (s && s !== "transparent") {
|
|
702
|
+
const i = "getAttribute" in e && e.getAttribute("bgcolor") || "";
|
|
703
|
+
return { bgStyle: `background-color: ${s};`, bgAttr: i };
|
|
784
704
|
}
|
|
785
705
|
}
|
|
786
706
|
return { bgStyle: "", bgAttr: "" };
|
|
@@ -790,18 +710,17 @@ class Ut extends rt {
|
|
|
790
710
|
return t ? t.querySelector("[data-card-composition-control]") : null;
|
|
791
711
|
}
|
|
792
712
|
/**
|
|
793
|
-
*
|
|
794
|
-
*
|
|
795
|
-
*
|
|
796
|
-
* disabled state.)
|
|
713
|
+
* Adds/removes orderable-disabled class based on layout orientation.
|
|
714
|
+
* List layout hides drag handles via CSS and disables draggable attribute
|
|
715
|
+
* to prevent native browser drag-and-drop from working without the handle.
|
|
797
716
|
*/
|
|
798
717
|
_updateOrderableState() {
|
|
799
|
-
const
|
|
800
|
-
if (!
|
|
718
|
+
const r = this._getCurrentLayout() === "list", e = this._getControlContainer();
|
|
719
|
+
if (!e)
|
|
801
720
|
return;
|
|
802
|
-
const
|
|
803
|
-
|
|
804
|
-
|
|
721
|
+
const o = e.querySelector("[data-composition-list]");
|
|
722
|
+
o && (o.classList.toggle("orderable-disabled", r), o.querySelectorAll(".orderable-item").forEach((s) => {
|
|
723
|
+
s.setAttribute("draggable", r ? "false" : "true");
|
|
805
724
|
}));
|
|
806
725
|
}
|
|
807
726
|
/**
|
|
@@ -809,11 +728,11 @@ class Ut extends rt {
|
|
|
809
728
|
* or when all available filters have already been added (no unused attributes left).
|
|
810
729
|
*/
|
|
811
730
|
_updateAddButtonState() {
|
|
812
|
-
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));
|
|
813
732
|
this.api.setUIEAttribute(
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
r ||
|
|
733
|
+
x.ADD_ATTRIBUTE,
|
|
734
|
+
I.BUTTON.disabled,
|
|
735
|
+
r || s ? "true" : "false"
|
|
817
736
|
);
|
|
818
737
|
}
|
|
819
738
|
/**
|
|
@@ -826,8 +745,8 @@ class Ut extends rt {
|
|
|
826
745
|
this.unsubscribeStore = this.store.$subscribe(() => {
|
|
827
746
|
const e = this.store.recommendationConfigs.orientation;
|
|
828
747
|
e !== t && (t = e, this._updateOrderableState());
|
|
829
|
-
const
|
|
830
|
-
|
|
748
|
+
const o = Object.keys(this.store.filterList).sort().join(",");
|
|
749
|
+
o !== r && (r = o, this._initializeComposition());
|
|
831
750
|
});
|
|
832
751
|
}
|
|
833
752
|
/**
|
|
@@ -835,7 +754,7 @@ class Ut extends rt {
|
|
|
835
754
|
* excluding default attributes already covered by built-in toggle items.
|
|
836
755
|
*/
|
|
837
756
|
_getAddableFilters() {
|
|
838
|
-
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)));
|
|
839
758
|
}
|
|
840
759
|
/**
|
|
841
760
|
* Looks up the display name for an attribute from the store's filterList.
|
|
@@ -843,7 +762,7 @@ class Ut extends rt {
|
|
|
843
762
|
*/
|
|
844
763
|
_getDisplayNameForAttribute(t) {
|
|
845
764
|
const r = Object.values(this.store.filterList).find((e) => e.attributeName === t);
|
|
846
|
-
return r ? r.displayName :
|
|
765
|
+
return r ? r.displayName : ht(t);
|
|
847
766
|
}
|
|
848
767
|
/**
|
|
849
768
|
* Resolves the display content for a custom attribute cell.
|
|
@@ -851,29 +770,29 @@ class Ut extends rt {
|
|
|
851
770
|
*/
|
|
852
771
|
_resolveAttributeContent(t, r, e) {
|
|
853
772
|
var n;
|
|
854
|
-
const
|
|
855
|
-
return
|
|
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];
|
|
774
|
+
return _t(i) ?? r;
|
|
856
775
|
}
|
|
857
|
-
_getGridCellHtml(t, r, e,
|
|
858
|
-
const n = `${
|
|
776
|
+
_getGridCellHtml(t, r, e, o = "", s = "", i = "") {
|
|
777
|
+
const n = `${m}${t}`, a = w(ct, [n], this.store.filterList), c = {
|
|
859
778
|
[t]: r,
|
|
860
779
|
product_attributes: { [t]: r }
|
|
861
780
|
};
|
|
862
|
-
let
|
|
863
|
-
return
|
|
864
|
-
`padding: ${
|
|
865
|
-
`padding: ${
|
|
866
|
-
)),
|
|
781
|
+
let l = a[n](c);
|
|
782
|
+
return l = l.replace("<td", `<td width="${e}%"`), i && (l = l.replace(
|
|
783
|
+
`padding: ${ut}`,
|
|
784
|
+
`padding: ${i}`
|
|
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;
|
|
867
786
|
}
|
|
868
787
|
_getListRowHtml(t, r, e) {
|
|
869
|
-
const
|
|
788
|
+
const o = w(mt, [e], this.store.filterList), s = {
|
|
870
789
|
[t]: r,
|
|
871
790
|
product_attributes: { [t]: r }
|
|
872
|
-
}, n =
|
|
873
|
-
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${
|
|
791
|
+
}, n = o[e](s).replace(/<tr>/, "").replace(/<\/tr>/, "");
|
|
792
|
+
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${v}="1">${n}</tr>`;
|
|
874
793
|
}
|
|
875
794
|
}
|
|
876
795
|
export {
|
|
877
|
-
|
|
796
|
+
bt as COMPOSITION_CONTROL_BLOCK_ID,
|
|
878
797
|
Ut as RecommendationCardCompositionControl
|
|
879
798
|
};
|